diff --git a/toxygen/av/calls_manager.py b/toxygen/av/calls_manager.py index 26a06f4..5e84573 100644 --- a/toxygen/av/calls_manager.py +++ b/toxygen/av/calls_manager.py @@ -2,7 +2,6 @@ import threading import cv2 import av.calls from messenger.messages import * -import time from ui import av_widgets import common.event as event @@ -37,11 +36,6 @@ class CallsManager: # AV support # ----------------------------------------------------------------------------------------------------------------- - def get_call(self): - return self._call - - call = property(get_call) - def call_click(self, audio=True, video=False): """User clicked audio button in main window""" num = self._contacts_manager.get_active_number() @@ -53,8 +47,6 @@ class CallsManager: self._call(num, audio, video) self._screen.active_call() self._call_started_event(num, audio, video, True) - self._contacts_manager.get_curr_friend().append_message(InfoMessage(text, time.time())) - self._screen.messages.scrollToBottom() elif num in self._call: # finish or cancel call if you call with active friend self.stop_call(num, False) @@ -66,13 +58,13 @@ class CallsManager: return friend = self._contacts_manager.get_friend_by_number(friend_number) self._call_started_event(friend_number, audio, video, False) - friend.append_message(InfoMessage(text, time.time())) self._incoming_calls.add(friend_number) if friend_number == self._contacts_manager.get_active_number(): self._screen.incoming_call() else: friend.actions = True - self._call_widgets[friend_number] = av_widgets.IncomingCallWidget(friend_number, text, friend.name) + text = util_ui.tr("Incoming video call") if video else util_ui.tr("Incoming audio call") + self._call_widgets[friend_number] = self._get_incoming_call_widget(friend_number, text, friend.name) self._call_widgets[friend_number].set_pixmap(friend.get_pixmap()) self._call_widgets[friend_number].show() @@ -93,16 +85,14 @@ class CallsManager: if friend_number in self._incoming_calls: self._incoming_calls.remove(friend_number) is_declined = True - text = util_ui.tr("Call declined") else: is_declined = False - text = util_ui.tr("Call finished") self._screen.call_finished() is_video = self._call.is_video_call(friend_number) self._call.finish_call(friend_number, by_friend) # finish or decline call - if hasattr(self, '_call_widget'): - self._call_widget[friend_number].close() - del self._call_widget[friend_number] + if friend_number in self._call_widgets: + self._call_widgets[friend_number].close() + del self._call_widgets[friend_number] def destroy_window(): if is_video: @@ -114,3 +104,10 @@ class CallsManager: def friend_exit(self, friend_number): if friend_number in self._call: self._call.finish_call(friend_number, True) + + # ----------------------------------------------------------------------------------------------------------------- + # Private methods + # ----------------------------------------------------------------------------------------------------------------- + + def _get_incoming_call_widget(self, friend_number, text, friend_name): + return av_widgets.IncomingCallWidget(self._settings, self, friend_number, text, friend_name) diff --git a/toxygen/contacts/contact.py b/toxygen/contacts/contact.py index fb0267c..a142c61 100644 --- a/toxygen/contacts/contact.py +++ b/toxygen/contacts/contact.py @@ -74,7 +74,7 @@ class Contact(basecontact.BaseContact): Get data to save in db :return: list of unsaved messages or [] """ - messages = list(filter(lambda x: x.get_type() in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']), self._corr)) + messages = list(filter(lambda x: x.type in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']), self._corr)) return messages[-self._unsaved_messages:] if self._unsaved_messages else [] def get_corr(self): @@ -85,12 +85,12 @@ class Contact(basecontact.BaseContact): :param message: text or file transfer message """ self._corr.append(message) - if message.get_type() in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']): + if message.type in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']): self._unsaved_messages += 1 def get_last_message_text(self): - messages = list(filter(lambda x: x.get_type() in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']) - and x.get_owner() != MESSAGE_AUTHOR['FRIEND'], self._corr)) + messages = list(filter(lambda m: m.type in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']) + and m.author.type != MESSAGE_AUTHOR['FRIEND'], self._corr)) if messages: return messages[-1].text else: @@ -125,9 +125,9 @@ class Contact(basecontact.BaseContact): """ :return list of unsent messages for saving """ - messages = filter(lambda x: x.get_type() in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']) + messages = filter(lambda x: x.type in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']) and x.author.type == MESSAGE_AUTHOR['NOT_SENT'], self._corr) - return list(map(lambda x: x.get_data(), messages)) + return list(messages) def mark_as_sent(self, tox_message_id): try: @@ -144,7 +144,7 @@ class Contact(basecontact.BaseContact): def delete_message(self, message_id): elem = list(filter(lambda x: type(x) in (TextMessage, GroupChatMessage) and x.message_id == message_id, self._corr))[0] - tmp = list(filter(lambda x: x.get_type() in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']), self._corr)) + tmp = list(filter(lambda x: x.type in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']), self._corr)) if elem in tmp[-self._unsaved_messages:] and self._unsaved_messages: self._unsaved_messages -= 1 self._corr.remove(elem) @@ -156,13 +156,13 @@ class Contact(basecontact.BaseContact): Delete old messages (reduces RAM usage if messages saving is not enabled) """ def save_message(x): - if x.get_type() == 2 and (x.get_status() >= 2 or x.get_status() is None): # FIXME MAGIC NUMBERS + if x.type == MESSAGE_TYPE['FILE_TRANSFER'] and (x.state not in ACTIVE_FILE_TRANSFERS): return True - return x.get_owner() == MESSAGE_AUTHOR['NOT_SENT'] + return x.author.type == MESSAGE_AUTHOR['NOT_SENT'] old = filter(save_message, self._corr[:-SAVE_MESSAGES]) self._corr = list(old) + self._corr[-SAVE_MESSAGES:] - text_messages = filter(lambda x: x.get_type() in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']), self._corr) + text_messages = filter(lambda m: m.type in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']), self._corr) self._unsaved_messages = min(self._unsaved_messages, len(list(text_messages))) self._search_index = 0 @@ -175,13 +175,14 @@ class Contact(basecontact.BaseContact): self._search_index = 0 # don't delete data about active file transfer if not save_unsent: - self._corr = list(filter(lambda x: x.get_type() == 2 and - x.get_status() in ft.ACTIVE_FILE_TRANSFERS, self._corr)) + self._corr = list(filter(lambda m: m.type == MESSAGE_TYPE['FILE_TRANSFER'] and + m.state in ft.ACTIVE_FILE_TRANSFERS, self._corr)) self._unsaved_messages = 0 else: - self._corr = list(filter(lambda x: (x.get_type() == 2 and x.get_status() in ft.ACTIVE_FILE_TRANSFERS) - or (x.get_type() in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']) - and x.get_owner() == MESSAGE_AUTHOR['NOT_SENT']), + self._corr = list(filter(lambda m: (m.type == MESSAGE_TYPE['FILE_TRANSFER'] + and m.state in ft.ACTIVE_FILE_TRANSFERS) + or (m.type in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']) + and m.author.type == MESSAGE_AUTHOR['NOT_SENT']), self._corr)) self._unsaved_messages = len(self.get_unsent_messages()) @@ -197,7 +198,7 @@ class Contact(basecontact.BaseContact): while True: l = len(self._corr) for i in range(self._search_index - 1, -l - 1, -1): - if self._corr[i].get_type() > 1: + if self._corr[i].type not in (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']): continue message = self._corr[i].text if re.search(self._search_string, message, re.IGNORECASE) is not None: @@ -212,7 +213,7 @@ class Contact(basecontact.BaseContact): if not self._search_index: return None for i in range(self._search_index + 1, 0): - if self._corr[i].get_type() > 1: + if self._corr[i].get_type() > (MESSAGE_TYPE['TEXT'], MESSAGE_TYPE['ACTION']): continue message = self._corr[i].text if re.search(self._search_string, message, re.IGNORECASE) is not None: @@ -259,10 +260,6 @@ class Contact(basecontact.BaseContact): visibility = property(get_visibility, set_visibility) - def set_widget(self, widget): - self._widget = widget - self.init_widget() - # ----------------------------------------------------------------------------------------------------------------- # Unread messages and other actions from friend # ----------------------------------------------------------------------------------------------------------------- diff --git a/toxygen/file_transfers/file_transfers.py b/toxygen/file_transfers/file_transfers.py index 166cc7f..61a379f 100644 --- a/toxygen/file_transfers/file_transfers.py +++ b/toxygen/file_transfers/file_transfers.py @@ -13,7 +13,8 @@ FILE_TRANSFER_STATE = { 'FINISHED': 3, 'PAUSED_BY_FRIEND': 4, 'INCOMING_NOT_STARTED': 5, - 'OUTGOING_NOT_STARTED': 6 + 'OUTGOING_NOT_STARTED': 6, + 'UNSENT': 7 } ACTIVE_FILE_TRANSFERS = (0, 1, 4, 5, 6) diff --git a/toxygen/file_transfers/file_transfers_handler.py b/toxygen/file_transfers/file_transfers_handler.py index c46ee58..1f5c9d0 100644 --- a/toxygen/file_transfers/file_transfers_handler.py +++ b/toxygen/file_transfers/file_transfers_handler.py @@ -41,15 +41,15 @@ class FileTransfersHandler: file_id = self._tox.file_get_file_id(friend_number, file_number) accepted = True if file_id in self._paused_file_transfers: - data = self._paused_file_transfers[file_id] - pos = data[-1] if os.path.exists(data[0]) else 0 + (path, ft_friend_number, is_incoming, start_position) = self._paused_file_transfers[file_id] + pos = start_position if os.path.exists(path) else 0 if pos >= size: self._tox.file_control(friend_number, file_number, TOX_FILE_CONTROL['CANCEL']) return self._tox.file_seek(friend_number, file_number, pos) self._file_transfers_message_service.add_incoming_transfer_message( friend, accepted, size, file_name, file_number) - self.accept_transfer(data[0], friend_number, file_number, size, False, pos) + self.accept_transfer(path, friend_number, file_number, size, False, pos) elif inline and size < 1024 * 1024: self._file_transfers_message_service.add_incoming_transfer_message( friend, accepted, size, file_name, file_number) diff --git a/toxygen/messenger/messages.py b/toxygen/messenger/messages.py index 85b16f7..c356485 100644 --- a/toxygen/messenger/messages.py +++ b/toxygen/messenger/messages.py @@ -189,14 +189,16 @@ class UnsentFileMessage(Message): data = property(get_data) + def get_state(self): + return FILE_TRANSFER_STATE['UNSENT'] + + state = property(get_state) + def get_path(self): return self._path path = property(get_path) - def get_status(self): - return None - def _create_widget(self, *args): return UnsentFileItem(self, *args) diff --git a/toxygen/ui/av_widgets.py b/toxygen/ui/av_widgets.py index f9eb6ed..e5773a8 100644 --- a/toxygen/ui/av_widgets.py +++ b/toxygen/ui/av_widgets.py @@ -1,17 +1,16 @@ from PyQt5 import QtCore, QtGui, QtWidgets from ui import widgets -from contacts import profile -import utils +import utils.util as util import pyaudio import wave -from user_data import settings -from utils.util import * class IncomingCallWidget(widgets.CenteredWidget): - def __init__(self, friend_number, text, name): + def __init__(self, settings, calls_manager, friend_number, text, name): super().__init__() + self._settings = settings + self._calls_manager = calls_manager self.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowStaysOnTopHint) self.resize(QtCore.QSize(500, 270)) self.avatar_label = QtWidgets.QLabel(self) @@ -21,7 +20,7 @@ class IncomingCallWidget(widgets.CenteredWidget): self.name.setGeometry(QtCore.QRect(90, 20, 300, 25)) self._friend_number = friend_number font = QtGui.QFont() - font.setFamily(settings.Settings.get_instance()['font']) + font.setFamily(settings['font']) font.setPointSize(16) font.setBold(True) self.name.setFont(font) @@ -34,13 +33,13 @@ class IncomingCallWidget(widgets.CenteredWidget): self.accept_video.setGeometry(QtCore.QRect(170, 100, 150, 150)) self.decline = QtWidgets.QPushButton(self) self.decline.setGeometry(QtCore.QRect(320, 100, 150, 150)) - pixmap = QtGui.QPixmap(utils.curr_directory() + '/images/accept_audio.png') + pixmap = QtGui.QPixmap(util.join_path(util.get_images_directory(), 'accept_audio.png')) icon = QtGui.QIcon(pixmap) self.accept_audio.setIcon(icon) - pixmap = QtGui.QPixmap(utils.curr_directory() + '/images/accept_video.png') + pixmap = QtGui.QPixmap(util.join_path(util.get_images_directory(), 'accept_video.png')) icon = QtGui.QIcon(pixmap) self.accept_video.setIcon(icon) - pixmap = QtGui.QPixmap(utils.curr_directory() + '/images/decline_call.png') + pixmap = QtGui.QPixmap(util.join_path(util.get_images_directory(), 'decline_call.png')) icon = QtGui.QIcon(pixmap) self.decline.setIcon(icon) self.accept_audio.setIconSize(QtCore.QSize(150, 150)) @@ -90,11 +89,11 @@ class IncomingCallWidget(widgets.CenteredWidget): self.stream.close() self.p.terminate() - self.a = AudioFile(curr_directory() + '/sounds/call.wav') + self.a = AudioFile(util.join_path(util.get_sounds_directory(), 'call.wav')) self.a.play() self.a.close() - if settings.Settings.get_instance()['calls_sound']: + if self._settings['calls_sound']: self.thread = SoundPlay() self.thread.start() else: @@ -110,24 +109,21 @@ class IncomingCallWidget(widgets.CenteredWidget): if self._processing: return self._processing = True - pr = profile.Profile.get_instance() - pr.accept_call(self._friend_number, True, False) + self._calls_manager.accept_call(self._friend_number, True, False) self.stop() def accept_call_with_video(self): if self._processing: return self._processing = True - pr = profile.Profile.get_instance() - pr.accept_call(self._friend_number, True, True) + self._calls_manager.accept_call(self._friend_number, True, True) self.stop() def decline_call(self): if self._processing: return self._processing = True - pr = profile.Profile.get_instance() - pr.stop_call(self._friend_number, False) + self._calls_manager.stop_call(self._friend_number, False) self.stop() def set_pixmap(self, pixmap): diff --git a/toxygen/ui/messages_widgets.py b/toxygen/ui/messages_widgets.py index f69cbfb..c676783 100644 --- a/toxygen/ui/messages_widgets.py +++ b/toxygen/ui/messages_widgets.py @@ -134,8 +134,9 @@ class MessageItem(QtWidgets.QWidget): font.setFamily(settings['font']) font.setPointSize(11) font.setBold(True) - self.name.setFont(font) - self.name.setText(text_message.author.name) + if text_message.author is not None: + self.name.setFont(font) + self.name.setText(text_message.author.name) self.time = QtWidgets.QLabel(self) self.time.setGeometry(QtCore.QRect(parent.width() - 60, 0, 50, 25)) @@ -143,7 +144,7 @@ class MessageItem(QtWidgets.QWidget): font.setBold(False) self.time.setFont(font) self._time = text_message.time - if text_message.author.type == MESSAGE_AUTHOR['NOT_SENT']: + if text_message.author and text_message.author.type == MESSAGE_AUTHOR['NOT_SENT']: movie = QtGui.QMovie(util.join_path(util.get_images_directory(), 'spinner.gif')) self.time.setMovie(movie) movie.start()