contacts minor refactoring
This commit is contained in:
parent
0ba1aadf70
commit
dec4990d32
12 changed files with 204 additions and 188 deletions
|
@ -22,7 +22,7 @@ class App:
|
|||
def __init__(self, version, path_to_profile=None, uri=None):
|
||||
self._version = version
|
||||
self._app = self._settings = self._profile_manager = self._plugin_loader = None
|
||||
self._tox = self._ms = self._init = self.tray = self._main_loop = self._av_loop = None
|
||||
self._tox = self._ms = self._init = self._main_loop = self._av_loop = None
|
||||
self._uri = self._toxes = self._tray = None
|
||||
if uri is not None and uri.startswith('tox:'):
|
||||
self._uri = uri[4:]
|
||||
|
@ -63,15 +63,7 @@ class App:
|
|||
else:
|
||||
auto_profile = Settings.get_auto_profile()
|
||||
if auto_profile is None: # no default profile
|
||||
# show login screen if default profile not found
|
||||
self.load_login_screen_translations()
|
||||
ls = LoginScreen()
|
||||
ls.setWindowIconText("Toxygen")
|
||||
profiles = ProfileManager.find_profiles()
|
||||
ls.update_select(profiles)
|
||||
ls.show()
|
||||
self._app.exec_()
|
||||
result = ls.result
|
||||
result = self.select_profile()
|
||||
if result is None:
|
||||
return
|
||||
if result.is_new_profile(): # create new profile
|
||||
|
@ -208,6 +200,16 @@ class App:
|
|||
def create_tox(self, data):
|
||||
return tox_factory(data, self._settings)
|
||||
|
||||
def select_profile(self):
|
||||
self.load_login_screen_translations()
|
||||
ls = LoginScreen()
|
||||
profiles = ProfileManager.find_profiles()
|
||||
ls.update_select(profiles)
|
||||
ls.show()
|
||||
self._app.exec_()
|
||||
|
||||
return ls.result
|
||||
|
||||
def load_existing_profile(self, profile_path):
|
||||
self._settings = Settings(self._toxes, profile_path.replace('.tox', '.json'))
|
||||
self._profile_manager = ProfileManager(self._settings, self._toxes, profile_path)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import pyaudio
|
||||
import time
|
||||
import threading
|
||||
from user_data import settings
|
||||
from wrapper.toxav_enums import *
|
||||
import cv2
|
||||
import itertools
|
||||
import numpy as np
|
||||
from av import screen_sharing
|
||||
from av.call import Call
|
||||
|
||||
|
||||
# TODO: play sound until outgoing call will be started or cancelled
|
||||
|
@ -14,8 +14,9 @@ from av import screen_sharing
|
|||
|
||||
class AV:
|
||||
|
||||
def __init__(self, toxav):
|
||||
def __init__(self, toxav, settings):
|
||||
self._toxav = toxav
|
||||
self._settings = settings
|
||||
self._running = True
|
||||
|
||||
self._calls = {} # dict: key - friend number, value - Call instance
|
||||
|
@ -118,7 +119,7 @@ class AV:
|
|||
rate=self._audio_rate,
|
||||
channels=self._audio_channels,
|
||||
input=True,
|
||||
input_device_index=settings.Settings.get_instance().audio['input'],
|
||||
input_device_index=self._settings.audio['input'],
|
||||
frames_per_buffer=self._audio_sample_count * 10)
|
||||
|
||||
self._audio_thread = threading.Thread(target=self.send_audio)
|
||||
|
@ -147,15 +148,14 @@ class AV:
|
|||
return
|
||||
|
||||
self._video_running = True
|
||||
s = settings.Settings.get_instance()
|
||||
self._video_width = s.video['width']
|
||||
self._video_height = s.video['height']
|
||||
|
||||
if s.video['device'] == -1:
|
||||
self._video = screen_sharing.DesktopGrabber(s.video['x'], s.video['y'],
|
||||
s.video['width'], s.video['height'])
|
||||
self._video = screen_sharing.DesktopGrabber(self._settings.video['x'], self._settings.video['y'],
|
||||
self._settings.video['width'], self._settings.video['height'])
|
||||
else:
|
||||
self._video = cv2.VideoCapture(s.video['device'])
|
||||
self._video = cv2.VideoCapture(self._settings.video['device'])
|
||||
self._video.set(cv2.CAP_PROP_FPS, 25)
|
||||
self._video.set(cv2.CAP_PROP_FRAME_WIDTH, self._video_width)
|
||||
self._video.set(cv2.CAP_PROP_FRAME_HEIGHT, self._video_height)
|
||||
|
@ -185,7 +185,7 @@ class AV:
|
|||
self._out_stream = self._audio.open(format=pyaudio.paInt16,
|
||||
channels=channels_count,
|
||||
rate=rate,
|
||||
output_device_index=settings.Settings.get_instance().audio['output'],
|
||||
output_device_index=self._settings.audio['output'],
|
||||
output=True)
|
||||
self._out_stream.write(samples)
|
||||
|
||||
|
|
|
@ -4,15 +4,16 @@ import av.calls
|
|||
from PyQt5 import QtWidgets
|
||||
from messenger.messages import *
|
||||
import time
|
||||
from ui import av_widgets
|
||||
|
||||
|
||||
class CallsManager:
|
||||
|
||||
def __init__(self, tox):
|
||||
def __init__(self, tox, settings):
|
||||
self._call = av.calls.AV(tox.AV) # object with data about calls
|
||||
self._call_widgets = {} # dict of incoming call widgets
|
||||
self._incoming_calls = set()
|
||||
|
||||
self._settings = settings
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# AV support
|
||||
|
@ -29,7 +30,7 @@ class CallsManager:
|
|||
if not self.is_active_a_friend():
|
||||
return
|
||||
if num not in self._call and self.is_active_online(): # start call
|
||||
if not Settings.get_instance().audio['enabled']:
|
||||
if not self._settings.audio['enabled']:
|
||||
return
|
||||
self._call(num, audio, video)
|
||||
self._screen.active_call()
|
||||
|
@ -47,7 +48,7 @@ class CallsManager:
|
|||
"""
|
||||
Incoming call from friend.
|
||||
"""
|
||||
if not Settings.get_instance().audio['enabled']:
|
||||
if not self._settings.audio['enabled']:
|
||||
return
|
||||
friend = self.get_friend_by_number(friend_number)
|
||||
if video:
|
||||
|
@ -62,7 +63,7 @@ class CallsManager:
|
|||
self._messages.scrollToBottom()
|
||||
else:
|
||||
friend.actions = True
|
||||
self._call_widgets[friend_number] = avwidgets.IncomingCallWidget(friend_number, text, friend.name)
|
||||
self._call_widgets[friend_number] = av_widgets.IncomingCallWidget(friend_number, text, friend.name)
|
||||
self._call_widgets[friend_number].set_pixmap(friend.get_pixmap())
|
||||
self._call_widgets[friend_number].show()
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from user_data.settings import *
|
||||
from PyQt5 import QtCore, QtGui
|
||||
from wrapper.toxcore_enums_and_consts import TOX_PUBLIC_KEY_SIZE
|
||||
import util.util as util
|
||||
|
||||
|
||||
class BaseContact:
|
||||
|
@ -11,13 +12,14 @@ class BaseContact:
|
|||
Base class for all contacts.
|
||||
"""
|
||||
|
||||
def __init__(self, name, status_message, widget, tox_id):
|
||||
def __init__(self, profile_manager, name, status_message, widget, tox_id):
|
||||
"""
|
||||
:param name: name, example: 'Toxygen user'
|
||||
:param status_message: status message, example: 'Toxing on Toxygen'
|
||||
:param widget: ContactItem instance
|
||||
:param tox_id: tox id of contact
|
||||
"""
|
||||
self._profile_manager = profile_manager
|
||||
self._name, self._status_message = name, status_message
|
||||
self._status, self._widget = None, widget
|
||||
self._tox_id = tox_id
|
||||
|
@ -81,11 +83,7 @@ class BaseContact:
|
|||
"""
|
||||
Tries to load avatar of contact or uses default avatar
|
||||
"""
|
||||
return
|
||||
prefix = ProfileManager.get_path() + 'avatars/'
|
||||
avatar_path = prefix + '{}.png'.format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
||||
if not os.path.isfile(avatar_path) or not os.path.getsize(avatar_path): # load default image
|
||||
avatar_path = curr_directory() + '/images/avatar.png'
|
||||
avatar_path = self.get_avatar_path()
|
||||
width = self._widget.avatar_label.width()
|
||||
pixmap = QtGui.QPixmap(avatar_path)
|
||||
self._widget.avatar_label.setPixmap(pixmap.scaled(width, width, QtCore.Qt.KeepAspectRatio,
|
||||
|
@ -93,13 +91,13 @@ class BaseContact:
|
|||
self._widget.avatar_label.repaint()
|
||||
|
||||
def reset_avatar(self):
|
||||
avatar_path = (ProfileManager.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
||||
avatar_path = self.get_avatar_path()
|
||||
if os.path.isfile(avatar_path):
|
||||
os.remove(avatar_path)
|
||||
self.load_avatar()
|
||||
|
||||
def set_avatar(self, avatar):
|
||||
avatar_path = (ProfileManager.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
||||
avatar_path = self.get_avatar_path()
|
||||
with open(avatar_path, 'wb') as f:
|
||||
f.write(avatar)
|
||||
self.load_avatar()
|
||||
|
@ -107,6 +105,17 @@ class BaseContact:
|
|||
def get_pixmap(self):
|
||||
return self._widget.avatar_label.pixmap()
|
||||
|
||||
def get_avatar_path(self):
|
||||
directory = util.join_path(self._profile_manager.get_path(), 'avatars')
|
||||
avatar_path = util.join_path(directory, '{}.png'.format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]))
|
||||
if not os.path.isfile(avatar_path) or not os.path.getsize(avatar_path): # load default image
|
||||
avatar_path = util.join_path(util.get_images_directory(), self.get_default_avatar_name())
|
||||
|
||||
return avatar_path
|
||||
|
||||
@staticmethod
|
||||
def get_default_avatar_name():
|
||||
return 'avatar.png'
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Widgets
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from history.database import *
|
||||
from contacts import basecontact
|
||||
import util
|
||||
import util.util as util
|
||||
from messenger.messages import *
|
||||
from file_transfers import file_transfers as ft
|
||||
import re
|
||||
|
@ -12,12 +12,12 @@ class Contact(basecontact.BaseContact):
|
|||
Properties: number, message getter, history etc. Base class for friend and gc classes
|
||||
"""
|
||||
|
||||
def __init__(self, message_getter, number, name, status_message, widget, tox_id):
|
||||
def __init__(self, message_getter, number, profile_manager, name, status_message, widget, tox_id):
|
||||
"""
|
||||
:param message_getter: gets messages from db
|
||||
:param number: number of friend.
|
||||
"""
|
||||
super().__init__(name, status_message, widget, tox_id)
|
||||
super().__init__(profile_manager, name, status_message, widget, tox_id)
|
||||
self._number = number
|
||||
self._new_messages = False
|
||||
self._visible = True
|
||||
|
|
|
@ -1,36 +1,56 @@
|
|||
import util.util as util
|
||||
import util.ui as util_ui
|
||||
from contacts.friend import Friend
|
||||
import os
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from messenger.messages import *
|
||||
from wrapper.toxcore_enums_and_consts import *
|
||||
from network.tox_dns import tox_dns
|
||||
|
||||
|
||||
class ContactsManager:
|
||||
|
||||
def __init__(self, tox, settings, screen):
|
||||
def __init__(self, tox, settings, screen, profile_manager):
|
||||
self._tox = tox
|
||||
self._settings = settings
|
||||
self._screen = screen
|
||||
self._profile_manager = profile_manager
|
||||
self._messages = screen.messages
|
||||
self._contacts, self._active_friend = [], -1
|
||||
self._sorting = settings['sorting']
|
||||
data = tox.self_get_friend_list()
|
||||
self._filter_string = ''
|
||||
self._friend_item_height = 40 if settings['compact_mode'] else 70
|
||||
screen.online_contacts.setCurrentIndex(int(self._sorting))
|
||||
aliases = settings['friends_aliases']
|
||||
for i in data: # creates list of friends
|
||||
tox_id = tox.friend_get_public_key(i)
|
||||
self.load_contacts()
|
||||
|
||||
def load_contacts(self):
|
||||
self.load_friends()
|
||||
self.load_groups()
|
||||
if len(self._contacts):
|
||||
self.set_active(0)
|
||||
self.filtration_and_sorting(self._sorting)
|
||||
|
||||
def load_friends(self):
|
||||
aliases = self._settings['friends_aliases']
|
||||
friend_numbers = self._tox.self_get_friend_list()
|
||||
for friend_number in friend_numbers: # creates list of friends
|
||||
tox_id = self._tox.friend_get_public_key(friend_number)
|
||||
try:
|
||||
alias = list(filter(lambda x: x[0] == tox_id, aliases))[0][1]
|
||||
except:
|
||||
alias = ''
|
||||
item = self.create_friend_item()
|
||||
name = alias or tox.friend_get_name(i) or tox_id
|
||||
status_message = tox.friend_get_status_message(i)
|
||||
name = alias or self._tox.friend_get_name(friend_number) or tox_id
|
||||
status_message = self._tox.friend_get_status_message(i)
|
||||
if not self._history.friend_exists_in_db(tox_id):
|
||||
self._history.add_friend_to_db(tox_id)
|
||||
message_getter = self._history.messages_getter(tox_id)
|
||||
friend = Friend(message_getter, i, name, status_message, item, tox_id)
|
||||
friend = Friend(self._profile_manager, message_getter, friend_number, name, status_message, item, tox_id)
|
||||
friend.set_alias(alias)
|
||||
self._contacts.append(friend)
|
||||
if len(self._contacts):
|
||||
self.set_active(0)
|
||||
self.filtration_and_sorting(self._sorting)
|
||||
|
||||
def load_groups(self):
|
||||
pass
|
||||
|
||||
def get_friend(self, num):
|
||||
if num < 0 or num >= len(self._contacts):
|
||||
|
@ -40,6 +60,10 @@ class ContactsManager:
|
|||
def get_curr_friend(self):
|
||||
return self._contacts[self._active_friend] if self._active_friend + 1 else None
|
||||
|
||||
def save_profile(self):
|
||||
data = self._tox.get_savedata()
|
||||
self._profile_manager.save_profile(data)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Work with active friend
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
@ -78,7 +102,7 @@ class ContactsManager:
|
|||
self._screen.messageEdit.setPlainText(friend.curr_text)
|
||||
self._active_friend = value
|
||||
friend.reset_messages()
|
||||
if not Settings.get_instance()['save_history']:
|
||||
if not self._settings['save_history']:
|
||||
friend.delete_old_messages()
|
||||
self._messages.clear()
|
||||
friend.load_corr()
|
||||
|
@ -128,19 +152,14 @@ class ContactsManager:
|
|||
self._screen.account_name.setText(friend.name)
|
||||
self._screen.account_status.setText(friend.status_message)
|
||||
self._screen.account_status.setToolTip(friend.get_full_status())
|
||||
if friend.tox_id is None:
|
||||
avatar_path = curr_directory() + '/images/group.png'
|
||||
else:
|
||||
avatar_path = (ProfileManager.get_path() + 'avatars/{}.png').format(friend.tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
||||
if not os.path.isfile(avatar_path): # load default image
|
||||
avatar_path = curr_directory() + '/images/avatar.png'
|
||||
avatar_path = friend.get_avatar_path()
|
||||
os.chdir(os.path.dirname(avatar_path))
|
||||
pixmap = QtGui.QPixmap(avatar_path)
|
||||
self._screen.account_avatar.setPixmap(pixmap.scaled(64, 64, QtCore.Qt.KeepAspectRatio,
|
||||
QtCore.Qt.SmoothTransformation))
|
||||
except Exception as ex: # no friend found. ignore
|
||||
log('Friend value: ' + str(value))
|
||||
log('Error in set active: ' + str(ex))
|
||||
util.log('Friend value: ' + str(value))
|
||||
util.log('Error in set active: ' + str(ex))
|
||||
raise
|
||||
|
||||
def set_active_by_number_and_type(self, number, is_friend):
|
||||
|
@ -167,7 +186,6 @@ class ContactsManager:
|
|||
:param filter_str: show contacts which name contains this substring
|
||||
"""
|
||||
filter_str = filter_str.lower()
|
||||
settings = Settings.get_instance()
|
||||
number = self.get_active_number()
|
||||
is_friend = self.is_active_a_friend()
|
||||
if sorting > 1:
|
||||
|
@ -203,8 +221,8 @@ class ContactsManager:
|
|||
else:
|
||||
self._screen.friends_list.item(index).setSizeHint(QtCore.QSize(250, 0))
|
||||
self._sorting, self._filter_string = sorting, filter_str
|
||||
settings['sorting'] = self._sorting
|
||||
settings.save()
|
||||
self._settings['sorting'] = self._sorting
|
||||
self._settings.save()
|
||||
self.set_active_by_number_and_type(number, is_friend)
|
||||
|
||||
def update_filtration(self):
|
||||
|
@ -213,7 +231,6 @@ class ContactsManager:
|
|||
"""
|
||||
self.filtration_and_sorting(self._sorting, self._filter_string)
|
||||
|
||||
|
||||
def create_friend_item(self):
|
||||
"""
|
||||
Method-factory
|
||||
|
@ -221,7 +238,42 @@ class ContactsManager:
|
|||
"""
|
||||
return self._factory.friend_item()
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Friend getters
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
def get_friend_by_number(self, num):
|
||||
return list(filter(lambda x: x.number == num and type(x) is Friend, self._contacts))[0]
|
||||
|
||||
def get_last_message(self):
|
||||
if self._active_friend + 1:
|
||||
return self.get_curr_friend().get_last_message_text()
|
||||
else:
|
||||
return ''
|
||||
|
||||
def get_active_number(self):
|
||||
return self.get_curr_friend().number if self._active_friend + 1 else -1
|
||||
|
||||
def get_active_name(self):
|
||||
return self.get_curr_friend().name if self._active_friend + 1 else ''
|
||||
|
||||
def is_active_online(self):
|
||||
return self._active_friend + 1 and self.get_curr_friend().status is not None
|
||||
|
||||
def new_name(self, number, name):
|
||||
friend = self.get_friend_by_number(number)
|
||||
tmp = friend.name
|
||||
friend.set_name(name)
|
||||
name = str(name, 'utf-8')
|
||||
if friend.name == name and tmp != name:
|
||||
message = QtWidgets.QApplication.translate("MainWindow", 'User {} is now known as {}')
|
||||
message = message.format(tmp, name)
|
||||
friend.append_message(InfoMessage(message, time.time()))
|
||||
friend.actions = True
|
||||
if number == self.get_active_number():
|
||||
self.create_message_item(message, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE'])
|
||||
self._messages.scrollToBottom()
|
||||
self.set_active(None)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Work with friends (remove, block, set alias, get public key)
|
||||
|
@ -233,19 +285,11 @@ class ContactsManager:
|
|||
"""
|
||||
friend = self._contacts[num]
|
||||
name = friend.name
|
||||
dialog = QtWidgets.QApplication.translate('MainWindow',
|
||||
"Enter new alias for friend {} or leave empty to use friend's name:")
|
||||
dialog = dialog.format(name)
|
||||
title = QtWidgets.QApplication.translate('MainWindow',
|
||||
'Set alias')
|
||||
text, ok = QtWidgets.QInputDialog.getText(None,
|
||||
title,
|
||||
dialog,
|
||||
QtWidgets.QLineEdit.Normal,
|
||||
name)
|
||||
text = util_ui.tr("Enter new alias for friend {} or leave empty to use friend's name:").format(name)
|
||||
title = util_ui.tr('Set alias')
|
||||
text, ok = util_ui.text_dialog(text, title, name)
|
||||
if ok:
|
||||
settings = Settings.get_instance()
|
||||
aliases = settings['friends_aliases']
|
||||
aliases = self._settings['friends_aliases']
|
||||
if text:
|
||||
friend.name = bytes(text, 'utf-8')
|
||||
try:
|
||||
|
@ -262,7 +306,7 @@ class ContactsManager:
|
|||
del aliases[index]
|
||||
except:
|
||||
pass
|
||||
settings.save()
|
||||
self._settings.save()
|
||||
if num == self.get_active_number() and self.is_active_a_friend():
|
||||
self.update()
|
||||
|
||||
|
@ -275,15 +319,14 @@ class ContactsManager:
|
|||
:param num: number of friend in list
|
||||
"""
|
||||
friend = self._contacts[num]
|
||||
settings = Settings.get_instance()
|
||||
try:
|
||||
index = list(map(lambda x: x[0], settings['friends_aliases'])).index(friend.tox_id)
|
||||
del settings['friends_aliases'][index]
|
||||
index = list(map(lambda x: x[0], self._settings['friends_aliases'])).index(friend.tox_id)
|
||||
del self._settings['friends_aliases'][index]
|
||||
except:
|
||||
pass
|
||||
if friend.tox_id in settings['notes']:
|
||||
del settings['notes'][friend.tox_id]
|
||||
settings.save()
|
||||
if friend.tox_id in self._settings['notes']:
|
||||
del self._settings['notes'][friend.tox_id]
|
||||
self._settings.save()
|
||||
self.clear_history(num)
|
||||
if self._history.friend_exists_in_db(friend.tox_id):
|
||||
self._history.delete_friend_from_db(friend.tox_id)
|
||||
|
@ -296,7 +339,7 @@ class ContactsManager:
|
|||
else:
|
||||
self.set_active(0)
|
||||
data = self._tox.get_savedata()
|
||||
ProfileManager.get_instance().save_profile(data)
|
||||
self._profile_manager.save_profile(data)
|
||||
|
||||
def add_friend(self, tox_id):
|
||||
"""
|
||||
|
@ -309,7 +352,7 @@ class ContactsManager:
|
|||
self._history.add_friend_to_db(tox_id)
|
||||
message_getter = self._history.messages_getter(tox_id)
|
||||
except Exception as ex: # something is wrong
|
||||
log('Accept friend request failed! ' + str(ex))
|
||||
util.log('Accept friend request failed! ' + str(ex))
|
||||
message_getter = None
|
||||
friend = Friend(message_getter, num, tox_id, '', item, tox_id)
|
||||
self._contacts.append(friend)
|
||||
|
@ -319,17 +362,15 @@ class ContactsManager:
|
|||
Block user with specified tox id (or public key) - delete from friends list and ignore friend requests
|
||||
"""
|
||||
tox_id = tox_id[:TOX_PUBLIC_KEY_SIZE * 2]
|
||||
if tox_id == self.tox_id[:TOX_PUBLIC_KEY_SIZE * 2]:
|
||||
if tox_id == self._tox.self_get_address[:TOX_PUBLIC_KEY_SIZE * 2]:
|
||||
return
|
||||
settings = Settings.get_instance()
|
||||
if tox_id not in settings['blocked']:
|
||||
settings['blocked'].append(tox_id)
|
||||
settings.save()
|
||||
if tox_id not in self._settings['blocked']:
|
||||
self._settings['blocked'].append(tox_id)
|
||||
self._settings.save()
|
||||
try:
|
||||
num = self._tox.friend_by_public_key(tox_id)
|
||||
self.delete_friend(num)
|
||||
data = self._tox.get_savedata()
|
||||
ProfileManager.get_instance().save_profile(data)
|
||||
self.save_profile()
|
||||
except: # not in friend list
|
||||
pass
|
||||
|
||||
|
@ -339,13 +380,11 @@ class ContactsManager:
|
|||
:param tox_id: tox id of contact
|
||||
:param add_to_friend_list: add this contact to friend list or not
|
||||
"""
|
||||
s = Settings.get_instance()
|
||||
s['blocked'].remove(tox_id)
|
||||
s.save()
|
||||
self._settings['blocked'].remove(tox_id)
|
||||
self._settings.save()
|
||||
if add_to_friend_list:
|
||||
self.add_friend(tox_id)
|
||||
data = self._tox.get_savedata()
|
||||
ProfileManager.get_instance().save_profile(data)
|
||||
self.save_profile()
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Friend requests
|
||||
|
@ -366,11 +405,9 @@ class ContactsManager:
|
|||
raise Exception('TOX DNS lookup failed')
|
||||
if len(tox_id) == TOX_PUBLIC_KEY_SIZE * 2: # public key
|
||||
self.add_friend(tox_id)
|
||||
msgBox = QtWidgets.QMessageBox()
|
||||
msgBox.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "Friend added"))
|
||||
text = (QtWidgets.QApplication.translate("MainWindow", 'Friend added without sending friend request'))
|
||||
msgBox.setText(text)
|
||||
msgBox.exec_()
|
||||
title = util_ui.tr('Friend added')
|
||||
text = util_ui.tr('Friend added without sending friend request')
|
||||
util_ui.message_box(text, title)
|
||||
else:
|
||||
result = self._tox.friend_add(tox_id, message.encode('utf-8'))
|
||||
tox_id = tox_id[:TOX_PUBLIC_KEY_SIZE * 2]
|
||||
|
@ -380,11 +417,10 @@ class ContactsManager:
|
|||
message_getter = self._history.messages_getter(tox_id)
|
||||
friend = Friend(message_getter, result, tox_id, '', item, tox_id)
|
||||
self._contacts.append(friend)
|
||||
data = self._tox.get_savedata()
|
||||
ProfileManager.get_instance().save_profile(data)
|
||||
self.save_profile()
|
||||
return True
|
||||
except Exception as ex: # wrong data
|
||||
log('Friend request failed with ' + str(ex))
|
||||
util.log('Friend request failed with ' + str(ex))
|
||||
return str(ex)
|
||||
|
||||
def process_friend_request(self, tox_id, message):
|
||||
|
@ -396,13 +432,34 @@ class ContactsManager:
|
|||
if tox_id in self._settings['blocked']:
|
||||
return
|
||||
try:
|
||||
text = QtWidgets.QApplication.translate('MainWindow', 'User {} wants to add you to contact list. Message:\n{}')
|
||||
info = text.format(tox_id, message)
|
||||
fr_req = QtWidgets.QApplication.translate('MainWindow', 'Friend request')
|
||||
reply = QtWidgets.QMessageBox.question(None, fr_req, info, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
|
||||
if reply == QtWidgets.QMessageBox.Yes: # accepted
|
||||
text = util_ui.tr('User {} wants to add you to contact list. Message:\n{}')
|
||||
reply = util_ui.question(text.format(tox_id, message), util_ui.tr('Friend request'))
|
||||
if reply: # accepted
|
||||
self.add_friend(tox_id)
|
||||
data = self._tox.get_savedata()
|
||||
ProfileManager.get_instance().save_profile(data)
|
||||
self._profile_manager.save_profile(data)
|
||||
except Exception as ex: # something is wrong
|
||||
log('Accept friend request failed! ' + str(ex))
|
||||
util.log('Accept friend request failed! ' + str(ex))
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Typing notifications
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
def send_typing(self, typing):
|
||||
"""
|
||||
Send typing notification to a friend
|
||||
"""
|
||||
if self._settings['typing_notifications'] and self._active_friend + 1:
|
||||
try:
|
||||
friend = self.get_curr_friend()
|
||||
if friend.status is not None:
|
||||
self._tox.self_set_typing(friend.number, typing)
|
||||
except:
|
||||
pass
|
||||
|
||||
def friend_typing(self, friend_number, typing):
|
||||
"""
|
||||
Display incoming typing notification
|
||||
"""
|
||||
if friend_number == self.get_active_number() and self.is_active_a_friend():
|
||||
self._screen.typing.setVisible(typing)
|
||||
|
|
|
@ -8,8 +8,8 @@ class Friend(contact.Contact):
|
|||
Friend in list of friends.
|
||||
"""
|
||||
|
||||
def __init__(self, message_getter, number, name, status_message, widget, tox_id):
|
||||
super().__init__(message_getter, number, name, status_message, widget, tox_id)
|
||||
def __init__(self, profile_manager, message_getter, number, name, status_message, widget, tox_id):
|
||||
super().__init__(profile_manager, message_getter, number, name, status_message, widget, tox_id)
|
||||
self._receipts = 0
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from contacts import contact
|
||||
import util
|
||||
import util.util as util
|
||||
from PyQt5 import QtGui, QtCore
|
||||
from wrapper import toxcore_enums_and_consts as constants
|
||||
|
||||
|
@ -8,8 +8,8 @@ from wrapper import toxcore_enums_and_consts as constants
|
|||
|
||||
class GroupChat(contact.Contact):
|
||||
|
||||
def __init__(self, name, status_message, widget, tox, group_number):
|
||||
super().__init__(None, group_number, name, status_message, widget, None)
|
||||
def __init__(self, profile_manager, name, status_message, widget, tox, group_number):
|
||||
super().__init__(None, group_number, profile_manager, name, status_message, widget, None)
|
||||
self._tox = tox
|
||||
self.set_status(constants.TOX_USER_STATUS['NONE'])
|
||||
|
||||
|
@ -23,13 +23,9 @@ class GroupChat(contact.Contact):
|
|||
def new_title(self, title):
|
||||
super().set_name(title)
|
||||
|
||||
def load_avatar(self):
|
||||
path = util.curr_directory() + '/images/group.png'
|
||||
width = self._widget.avatar_label.width()
|
||||
pixmap = QtGui.QPixmap(path)
|
||||
self._widget.avatar_label.setPixmap(pixmap.scaled(width, width, QtCore.Qt.KeepAspectRatio,
|
||||
QtCore.Qt.SmoothTransformation))
|
||||
self._widget.avatar_label.repaint()
|
||||
@staticmethod
|
||||
def get_default_avatar_name():
|
||||
return 'group.png'
|
||||
|
||||
def remove_invalid_unsent_files(self):
|
||||
pass
|
||||
|
|
|
@ -22,12 +22,13 @@ class Profile(basecontact.BaseContact):
|
|||
"""
|
||||
Profile of current toxygen user. Contains friends list, tox instance
|
||||
"""
|
||||
def __init__(self, tox, screen):
|
||||
def __init__(self, profile_manager, tox, screen):
|
||||
"""
|
||||
:param tox: tox instance
|
||||
:param screen: ref to main screen
|
||||
"""
|
||||
basecontact.BaseContact.__init__(self,
|
||||
profile_manager,
|
||||
tox.self_get_name(),
|
||||
tox.self_get_status_message(),
|
||||
screen.user_info,
|
||||
|
@ -86,43 +87,6 @@ class Profile(basecontact.BaseContact):
|
|||
self._tox_id = self._tox.self_get_address()
|
||||
return self._tox_id
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Friend getters
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
def get_friend_by_number(self, num):
|
||||
return list(filter(lambda x: x.number == num and type(x) is Friend, self._contacts))[0]
|
||||
|
||||
def get_last_message(self):
|
||||
if self._active_friend + 1:
|
||||
return self.get_curr_friend().get_last_message_text()
|
||||
else:
|
||||
return ''
|
||||
|
||||
def get_active_number(self):
|
||||
return self.get_curr_friend().number if self._active_friend + 1 else -1
|
||||
|
||||
def get_active_name(self):
|
||||
return self.get_curr_friend().name if self._active_friend + 1 else ''
|
||||
|
||||
def is_active_online(self):
|
||||
return self._active_friend + 1 and self.get_curr_friend().status is not None
|
||||
|
||||
def new_name(self, number, name):
|
||||
friend = self.get_friend_by_number(number)
|
||||
tmp = friend.name
|
||||
friend.set_name(name)
|
||||
name = str(name, 'utf-8')
|
||||
if friend.name == name and tmp != name:
|
||||
message = QtWidgets.QApplication.translate("MainWindow", 'User {} is now known as {}')
|
||||
message = message.format(tmp, name)
|
||||
friend.append_message(InfoMessage(message, time.time()))
|
||||
friend.actions = True
|
||||
if number == self.get_active_number():
|
||||
self.create_message_item(message, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE'])
|
||||
self._messages.scrollToBottom()
|
||||
self.set_active(None)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Friend connection status callbacks
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
@ -168,29 +132,6 @@ class Profile(basecontact.BaseContact):
|
|||
self._paused_file_transfers[ft.get_id()] = [ft.get_path(), friend_num, True, ft.total_size()]
|
||||
self.cancel_transfer(friend_num, file_num, True)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Typing notifications
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
def send_typing(self, typing):
|
||||
"""
|
||||
Send typing notification to a friend
|
||||
"""
|
||||
if Settings.get_instance()['typing_notifications'] and self._active_friend + 1:
|
||||
try:
|
||||
friend = self.get_curr_friend()
|
||||
if friend.status is not None:
|
||||
self._tox.self_set_typing(friend.number, typing)
|
||||
except:
|
||||
pass
|
||||
|
||||
def friend_typing(self, friend_number, typing):
|
||||
"""
|
||||
Display incoming typing notification
|
||||
"""
|
||||
if friend_number == self.get_active_number() and self.is_active_a_friend():
|
||||
self._screen.typing.setVisible(typing)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Private messages
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
@ -294,7 +235,6 @@ class Profile(basecontact.BaseContact):
|
|||
# Friend, message and file transfer items creation
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def create_message_item(self, text, time, owner, message_type, append=True):
|
||||
if message_type == MESSAGE_TYPE['INFO_MESSAGE']:
|
||||
name = ''
|
||||
|
|
|
@ -13,7 +13,7 @@ class ProfileManager:
|
|||
self._path = path
|
||||
self._directory = os.path.basename(path)
|
||||
# create /avatars if not exists:
|
||||
directory = path + 'avatars'
|
||||
directory = util.join_path(self._directory, 'avatars')
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
import PyQt5
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
|
||||
def tr(s):
|
||||
return PyQt5.QtWidgets.QApplication.translate('Toxygen', s)
|
||||
return QtWidgets.QApplication.translate('Toxygen', s)
|
||||
|
||||
|
||||
def question(text, title=None):
|
||||
reply = PyQt5.QtWidgets.QMessageBox.question(None, title or 'Toxygen', text,
|
||||
PyQt5.QtWidgets.QMessageBox.Yes,
|
||||
PyQt5.QtWidgets.QMessageBox.No)
|
||||
return reply == PyQt5.QtWidgets.QMessageBox.Yes
|
||||
reply = QtWidgets.QMessageBox.question(None, title or 'Toxygen', text,
|
||||
QtWidgets.QMessageBox.Yes,
|
||||
QtWidgets.QMessageBox.No)
|
||||
return reply == QtWidgets.QMessageBox.Yes
|
||||
|
||||
|
||||
def message_box(text, title=None):
|
||||
m_box = PyQt5.QtWidgets.QMessageBox()
|
||||
m_box = QtWidgets.QMessageBox()
|
||||
m_box.setText(tr(text))
|
||||
m_box.setWindowTitle(title or 'Toxygen')
|
||||
m_box.exec_()
|
||||
|
||||
|
||||
def text_dialog(text, title='', default_value=''):
|
||||
text, ok = QtWidgets.QInputDialog.getText(None, title, text, QtWidgets.QLineEdit.Normal, default_value)
|
||||
|
||||
return text, ok
|
||||
|
||||
|
||||
# TODO: move all dialogs here
|
||||
|
|
|
@ -79,6 +79,10 @@ def curr_time():
|
|||
return time.strftime('%H:%M')
|
||||
|
||||
|
||||
def join_path(a, b):
|
||||
return os.path.join(a, b)
|
||||
|
||||
|
||||
def copy(src, dest):
|
||||
if not os.path.exists(dest):
|
||||
os.makedirs(dest)
|
||||
|
|
Loading…
Reference in a new issue