From 04f985205091cf718a68ae07b5ffa96440141dea Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Wed, 8 Jun 2016 22:53:41 +0300 Subject: [PATCH] refactoring --- src/contact.py | 113 ++++++++++++++++ src/file_transfers.py | 2 + src/friend.py | 183 ++++++++++++++++++++++++++ src/profile.py | 291 +----------------------------------------- src/tox_dns.py | 1 - 5 files changed, 300 insertions(+), 290 deletions(-) create mode 100644 src/contact.py create mode 100644 src/friend.py diff --git a/src/contact.py b/src/contact.py new file mode 100644 index 0000000..c957113 --- /dev/null +++ b/src/contact.py @@ -0,0 +1,113 @@ +import os +from settings import * +try: + from PySide import QtCore, QtGui +except ImportError: + from PyQt4 import QtCore, QtGui +from toxcore_enums_and_consts import TOX_PUBLIC_KEY_SIZE + + +class Contact(object): + """ + Class encapsulating TOX contact + Properties: name (alias of contact or name), status_message, status (connection status) + widget - widget for update + """ + + def __init__(self, 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._name, self._status_message = name, status_message + self._status, self._widget = None, widget + self._widget.name.setText(name) + self._widget.status_message.setText(status_message) + self._tox_id = tox_id + self.load_avatar() + + # ----------------------------------------------------------------------------------------------------------------- + # name - current name or alias of user + # ----------------------------------------------------------------------------------------------------------------- + + def get_name(self): + return self._name + + def set_name(self, value): + self._name = value.decode('utf-8') + self._widget.name.setText(self._name) + self._widget.name.repaint() + + name = property(get_name, set_name) + + # ----------------------------------------------------------------------------------------------------------------- + # Status message + # ----------------------------------------------------------------------------------------------------------------- + + def get_status_message(self): + return self._status_message + + def set_status_message(self, value): + self._status_message = value.decode('utf-8') + self._widget.status_message.setText(self._status_message) + self._widget.status_message.repaint() + + status_message = property(get_status_message, set_status_message) + + # ----------------------------------------------------------------------------------------------------------------- + # Status + # ----------------------------------------------------------------------------------------------------------------- + + def get_status(self): + return self._status + + def set_status(self, value): + self._widget.connection_status.data = self._status = value + self._widget.connection_status.repaint() + + status = property(get_status, set_status) + + # ----------------------------------------------------------------------------------------------------------------- + # TOX ID. WARNING: for friend it will return public key, for profile - full address + # ----------------------------------------------------------------------------------------------------------------- + + def get_tox_id(self): + return self._tox_id + + tox_id = property(get_tox_id) + + # ----------------------------------------------------------------------------------------------------------------- + # Avatars + # ----------------------------------------------------------------------------------------------------------------- + + def load_avatar(self): + """ + Tries to load avatar of contact or uses default avatar + """ + avatar_path = '{}.png'.format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) + os.chdir(ProfileHelper.get_path() + 'avatars/') + if not os.path.isfile(avatar_path): # load default image + avatar_path = 'avatar.png' + os.chdir(curr_directory() + '/images/') + pixmap = QtGui.QPixmap(QtCore.QSize(64, 64)) + pixmap.load(avatar_path) + self._widget.avatar_label.setScaledContents(False) + self._widget.avatar_label.setPixmap(pixmap.scaled(64, 64, QtCore.Qt.KeepAspectRatio)) + self._widget.avatar_label.repaint() + + def reset_avatar(self): + avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) + if os.path.isfile(avatar_path): + os.remove(avatar_path) + self.load_avatar() + + def set_avatar(self, avatar): + avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) + with open(avatar_path, 'wb') as f: + f.write(avatar) + self.load_avatar() + + def get_pixmap(self): + return self._widget.avatar_label.pixmap() diff --git a/src/file_transfers.py b/src/file_transfers.py index 66d1f26..3a68cad 100644 --- a/src/file_transfers.py +++ b/src/file_transfers.py @@ -19,6 +19,8 @@ TOX_FILE_TRANSFER_STATE = { } +# TODO: rewrite + class StateSignal(QtCore.QObject): try: signal = QtCore.Signal(int, float) # state and progress diff --git a/src/friend.py b/src/friend.py new file mode 100644 index 0000000..1b79096 --- /dev/null +++ b/src/friend.py @@ -0,0 +1,183 @@ +import contact +from messages import * +from history import * +import util + + +class Friend(contact.Contact): + """ + Friend in list of friends. Can be hidden, properties 'has unread messages' and 'has alias' added + """ + + def __init__(self, message_getter, number, *args): + """ + :param message_getter: gets messages from db + :param number: number of friend. + """ + super(Friend, self).__init__(*args) + self._number = number + self._new_messages = False + self._visible = True + self._alias = False + self._message_getter = message_getter + self._corr = [] + self._unsaved_messages = 0 + self._history_loaded = False + self._receipts = 0 + + def __del__(self): + self.set_visibility(False) + del self._widget + if hasattr(self, '_message_getter'): + del self._message_getter + + # ----------------------------------------------------------------------------------------------------------------- + # History support + # ----------------------------------------------------------------------------------------------------------------- + + def get_receipts(self): + return self._receipts + + receipts = property(get_receipts) + + def inc_receipts(self): + self._receipts += 1 + + def dec_receipt(self): + if self._receipts: + self._receipts -= 1 + self.mark_as_sent() + + def load_corr(self, first_time=True): + """ + :param first_time: friend became active, load first part of messages + """ + if (first_time and self._history_loaded) or (not hasattr(self, '_message_getter')): + return + data = self._message_getter.get(PAGE_SIZE) + if data is not None and len(data): + data.reverse() + else: + return + data = map(lambda tupl: TextMessage(*tupl), data) + self._corr = data + self._corr + self._history_loaded = True + + def get_corr_for_saving(self): + """ + Get data to save in db + :return: list of unsaved messages or [] + """ + if hasattr(self, '_message_getter'): + del self._message_getter + messages = filter(lambda x: x.get_type() <= 1, self._corr) + return map(lambda x: x.get_data(), messages[-self._unsaved_messages:]) if self._unsaved_messages else [] + + def get_corr(self): + return self._corr[:] + + def append_message(self, message): + """ + :param message: text or file transfer message + """ + self._corr.append(message) + if message.get_type() <= 1: + self._unsaved_messages += 1 + + def get_last_message_text(self): + messages = filter(lambda x: x.get_type() <= 1 and x.get_owner() != MESSAGE_OWNER['FRIEND'], self._corr) + if messages: + return messages[-1].get_data()[0] + else: + return '' + + def unsent_messages(self): + """ + :return list of unsent messages + """ + messages = filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr) + return messages + + def mark_as_sent(self): + try: + message = filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr)[0] + message.mark_as_sent() + except Exception as ex: + util.log('Mark as sent ex: ' + str(ex)) + + def clear_corr(self): + """ + Clear messages list + """ + if hasattr(self, '_message_getter'): + del self._message_getter + # don't delete data about active file transfer + self._corr = filter(lambda x: x.get_type() in (2, 3) and x.get_status() >= 2, self._corr) + self._unsaved_messages = 0 + + def update_transfer_data(self, file_number, status, inline=None): + """ + Update status of active transfer and load inline if needed + """ + try: + tr = filter(lambda x: x.get_type() == MESSAGE_TYPE['FILE_TRANSFER'] and x.is_active(file_number), + self._corr)[0] + tr.set_status(status) + if inline: # inline was loaded + i = self._corr.index(tr) + self._corr.insert(i, inline) + return i - len(self._corr) + except: + pass + + # ----------------------------------------------------------------------------------------------------------------- + # Alias support + # ----------------------------------------------------------------------------------------------------------------- + + def set_name(self, value): + """ + Set new name or ignore if alias exists + :param value: new name + """ + if not self._alias: + super(Friend, self).set_name(value) + + def set_alias(self, alias): + self._alias = bool(alias) + + # ----------------------------------------------------------------------------------------------------------------- + # Visibility in friends' list + # ----------------------------------------------------------------------------------------------------------------- + + def get_visibility(self): + return self._visible + + def set_visibility(self, value): + self._visible = value + + visibility = property(get_visibility, set_visibility) + + # ----------------------------------------------------------------------------------------------------------------- + # Unread messages from friend + # ----------------------------------------------------------------------------------------------------------------- + + def get_messages(self): + return self._new_messages + + def set_messages(self, value): + self._widget.connection_status.messages = self._new_messages = value + self._widget.connection_status.repaint() + + messages = property(get_messages, set_messages) + + # ----------------------------------------------------------------------------------------------------------------- + # Friend's number (can be used in toxcore) + # ----------------------------------------------------------------------------------------------------------------- + + def get_number(self): + return self._number + + def set_number(self, value): + self._number = value + + number = property(get_number, set_number) diff --git a/src/profile.py b/src/profile.py index c23684d..f1287de 100644 --- a/src/profile.py +++ b/src/profile.py @@ -3,9 +3,7 @@ try: from PySide import QtCore, QtGui except ImportError: from PyQt4 import QtCore, QtGui -from tox import Tox -import os -from messages import * +from friend import * from settings import * from toxcore_enums_and_consts import * from ctypes import * @@ -19,292 +17,7 @@ import avwidgets import plugin_support -class Contact(object): - """ - Class encapsulating TOX contact - Properties: name (alias of contact or name), status_message, status (connection status) - widget - widget for update - """ - - def __init__(self, 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._name, self._status_message = name, status_message - self._status, self._widget = None, widget - self._widget.name.setText(name) - self._widget.status_message.setText(status_message) - self._tox_id = tox_id - self.load_avatar() - - # ----------------------------------------------------------------------------------------------------------------- - # name - current name or alias of user - # ----------------------------------------------------------------------------------------------------------------- - - def get_name(self): - return self._name - - def set_name(self, value): - self._name = value.decode('utf-8') - self._widget.name.setText(self._name) - self._widget.name.repaint() - - name = property(get_name, set_name) - - # ----------------------------------------------------------------------------------------------------------------- - # Status message - # ----------------------------------------------------------------------------------------------------------------- - - def get_status_message(self): - return self._status_message - - def set_status_message(self, value): - self._status_message = value.decode('utf-8') - self._widget.status_message.setText(self._status_message) - self._widget.status_message.repaint() - - status_message = property(get_status_message, set_status_message) - - # ----------------------------------------------------------------------------------------------------------------- - # Status - # ----------------------------------------------------------------------------------------------------------------- - - def get_status(self): - return self._status - - def set_status(self, value): - self._widget.connection_status.data = self._status = value - self._widget.connection_status.repaint() - - status = property(get_status, set_status) - - # ----------------------------------------------------------------------------------------------------------------- - # TOX ID. WARNING: for friend it will return public key, for profile - full address - # ----------------------------------------------------------------------------------------------------------------- - - def get_tox_id(self): - return self._tox_id - - tox_id = property(get_tox_id) - - # ----------------------------------------------------------------------------------------------------------------- - # Avatars - # ----------------------------------------------------------------------------------------------------------------- - - def load_avatar(self): - """ - Tries to load avatar of contact or uses default avatar - """ - avatar_path = '{}.png'.format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) - os.chdir(ProfileHelper.get_path() + 'avatars/') - if not os.path.isfile(avatar_path): # load default image - avatar_path = 'avatar.png' - os.chdir(curr_directory() + '/images/') - pixmap = QtGui.QPixmap(QtCore.QSize(64, 64)) - pixmap.load(avatar_path) - self._widget.avatar_label.setScaledContents(False) - self._widget.avatar_label.setPixmap(pixmap.scaled(64, 64, QtCore.Qt.KeepAspectRatio)) - self._widget.avatar_label.repaint() - - def reset_avatar(self): - avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) - if os.path.isfile(avatar_path): - os.remove(avatar_path) - self.load_avatar() - - def set_avatar(self, avatar): - avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) - with open(avatar_path, 'wb') as f: - f.write(avatar) - self.load_avatar() - - def get_pixmap(self): - return self._widget.avatar_label.pixmap() - - -class Friend(Contact): - """ - Friend in list of friends. Can be hidden, properties 'has unread messages' and 'has alias' added - """ - - def __init__(self, message_getter, number, *args): - """ - :param message_getter: gets messages from db - :param number: number of friend. - """ - super(Friend, self).__init__(*args) - self._number = number - self._new_messages = False - self._visible = True - self._alias = False - self._message_getter = message_getter - self._corr = [] - self._unsaved_messages = 0 - self._history_loaded = False - self._receipts = 0 - - def __del__(self): - self.set_visibility(False) - del self._widget - if hasattr(self, '_message_getter'): - del self._message_getter - - # ----------------------------------------------------------------------------------------------------------------- - # History support - # ----------------------------------------------------------------------------------------------------------------- - - def get_receipts(self): - return self._receipts - - receipts = property(get_receipts) - - def inc_receipts(self): - self._receipts += 1 - - def dec_receipt(self): - if self._receipts: - self._receipts -= 1 - self.mark_as_sent() - - def load_corr(self, first_time=True): - """ - :param first_time: friend became active, load first part of messages - """ - if (first_time and self._history_loaded) or (not hasattr(self, '_message_getter')): - return - data = self._message_getter.get(PAGE_SIZE) - if data is not None and len(data): - data.reverse() - else: - return - data = map(lambda tupl: TextMessage(*tupl), data) - self._corr = data + self._corr - self._history_loaded = True - - def get_corr_for_saving(self): - """ - Get data to save in db - :return: list of unsaved messages or [] - """ - if hasattr(self, '_message_getter'): - del self._message_getter - messages = filter(lambda x: x.get_type() <= 1, self._corr) - return map(lambda x: x.get_data(), messages[-self._unsaved_messages:]) if self._unsaved_messages else [] - - def get_corr(self): - return self._corr[:] - - def append_message(self, message): - """ - :param message: text or file transfer message - """ - self._corr.append(message) - if message.get_type() <= 1: - self._unsaved_messages += 1 - - def get_last_message_text(self): - messages = filter(lambda x: x.get_type() <= 1 and x.get_owner() != MESSAGE_OWNER['FRIEND'], self._corr) - if messages: - return messages[-1].get_data()[0] - else: - return '' - - def unsent_messages(self): - """ - :return list of unsent messages - """ - messages = filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr) - return messages - - def mark_as_sent(self): - try: - message = filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr)[0] - message.mark_as_sent() - except Exception as ex: - log('Mark as sent ex: ' + str(ex)) - - def clear_corr(self): - """ - Clear messages list - """ - if hasattr(self, '_message_getter'): - del self._message_getter - # don't delete data about active file transfer - self._corr = filter(lambda x: x.get_type() in (2, 3) and x.get_status() >= 2, self._corr) - self._unsaved_messages = 0 - - def update_transfer_data(self, file_number, status, inline=None): - """ - Update status of active transfer and load inline if needed - """ - try: - tr = filter(lambda x: x.get_type() == MESSAGE_TYPE['FILE_TRANSFER'] and x.is_active(file_number), - self._corr)[0] - tr.set_status(status) - if inline: # inline was loaded - i = self._corr.index(tr) - self._corr.insert(i, inline) - return i - len(self._corr) - except: - pass - - # ----------------------------------------------------------------------------------------------------------------- - # Alias support - # ----------------------------------------------------------------------------------------------------------------- - - def set_name(self, value): - """ - Set new name or ignore if alias exists - :param value: new name - """ - if not self._alias: - super(Friend, self).set_name(value) - - def set_alias(self, alias): - self._alias = bool(alias) - - # ----------------------------------------------------------------------------------------------------------------- - # Visibility in friends' list - # ----------------------------------------------------------------------------------------------------------------- - - def get_visibility(self): - return self._visible - - def set_visibility(self, value): - self._visible = value - - visibility = property(get_visibility, set_visibility) - - # ----------------------------------------------------------------------------------------------------------------- - # Unread messages from friend - # ----------------------------------------------------------------------------------------------------------------- - - def get_messages(self): - return self._new_messages - - def set_messages(self, value): - self._widget.connection_status.messages = self._new_messages = value - self._widget.connection_status.repaint() - - messages = property(get_messages, set_messages) - - # ----------------------------------------------------------------------------------------------------------------- - # Friend's number (can be used in toxcore) - # ----------------------------------------------------------------------------------------------------------------- - - def get_number(self): - return self._number - - def set_number(self, value): - self._number = value - - number = property(get_number, set_number) - - -class Profile(Contact, Singleton): +class Profile(contact.Contact, Singleton): """ Profile of current toxygen user. Contains friends list, tox instance """ diff --git a/src/tox_dns.py b/src/tox_dns.py index ce0d5aa..77fc76a 100644 --- a/src/tox_dns.py +++ b/src/tox_dns.py @@ -1,7 +1,6 @@ import json import urllib2 from util import log -# TODO: add TOX DNS 3 support def tox_dns(email):