ngc - invites, gc menu, callbacks etc

This commit is contained in:
ingvar1995 2018-05-19 18:08:25 +03:00
parent eed31bf61b
commit ef4a1b18fd
12 changed files with 262 additions and 82 deletions

View File

@ -25,7 +25,7 @@ from av.calls_manager import CallsManager
from history.database import Database
from ui.widgets_factory import WidgetsFactory
from smileys.smileys import SmileyLoader
from ui.items_factories import MessagesItemsFactory, FriendItemsFactory
from ui.items_factories import MessagesItemsFactory, ContactItemsFactory
from messenger.messenger import Messenger
from network.tox_dns import ToxDns
from history.history import History
@ -301,9 +301,10 @@ class App:
self._ms = MainWindow(self._settings, self._tray)
db = Database(self._path.replace('.tox', '.db'), self._toxes)
friend_items_factory = FriendItemsFactory(self._settings, self._ms)
self._friend_factory = FriendFactory(self._profile_manager, self._settings, self._tox, db, friend_items_factory)
self._group_factory = GroupFactory()
contact_items_factory = ContactItemsFactory(self._settings, self._ms)
self._friend_factory = FriendFactory(self._profile_manager, self._settings,
self._tox, db, contact_items_factory)
self._group_factory = GroupFactory(self._profile_manager, self._settings, self._tox, db, contact_items_factory)
self._contacts_provider = ContactProvider(self._tox, self._friend_factory, self._group_factory)
profile = Profile(self._profile_manager, self._tox, self._ms, self._contacts_provider, self._reset)
self._plugin_loader = PluginLoader(self._tox, self._toxes, profile, self._settings)
@ -329,7 +330,8 @@ class App:
self._toxes, self._version, self._groups_service)
self._tray = tray.init_tray(profile, self._settings, self._ms)
self._ms.set_dependencies(widgets_factory, self._tray, self._contacts_manager, self._messenger, profile,
self._plugin_loader, self._file_transfer_handler, history, self._calls_manager)
self._plugin_loader, self._file_transfer_handler, history, self._calls_manager,
self._groups_service)
self._tray.show()
self._ms.show()

View File

@ -81,16 +81,28 @@ class BaseContactMenuGenerator:
def __init__(self, contact):
self._contact = contact
def generate(self, plugin_loader, contacts_manager, main_screen, settings, number):
def generate(self, plugin_loader, contacts_manager, main_screen, settings, number, groups_service):
return ContactMenuBuilder().build()
def _generate_copy_menu_builder(self, main_screen):
copy_menu_builder = ContactMenuBuilder()
(copy_menu_builder
.with_name(util_ui.tr('Copy'))
.with_action(util_ui.tr('Name'), lambda: main_screen.copy_text(self._contact.name))
.with_action(util_ui.tr('Status message'), lambda: main_screen.copy_text(self._contact.status_message))
.with_action(util_ui.tr('Public key'), lambda: main_screen.copy_text(self._contact.tox_id))
)
return copy_menu_builder
class FriendMenuGenerator(BaseContactMenuGenerator):
def generate(self, plugin_loader, contacts_manager, main_screen, settings, number):
def generate(self, plugin_loader, contacts_manager, main_screen, settings, number, groups_service):
history_menu_builder = self._generate_history_menu_builder(main_screen, number)
copy_menu_builder = self._generate_copy_menu_builder(main_screen)
plugins_menu_builder = self._generate_plugins_menu_builder(plugin_loader, number)
groups_menu_builder = self._generate_groups_menu(contacts_manager, groups_service)
allowed = self._contact.tox_id in settings['auto_accept_from_friends']
auto = util_ui.tr('Disallow auto accept') if allowed else util_ui.tr('Allow auto accept')
@ -105,6 +117,7 @@ class FriendMenuGenerator(BaseContactMenuGenerator):
.with_action(util_ui.tr('Block friend'), lambda: main_screen.block_friend(number))
.with_action(util_ui.tr('Notes'), lambda: main_screen.show_note(self._contact))
.with_optional_submenu(plugins_menu_builder)
.with_optional_submenu(groups_menu_builder)
).build()
return menu
@ -125,17 +138,6 @@ class FriendMenuGenerator(BaseContactMenuGenerator):
return history_menu_builder
def _generate_copy_menu_builder(self, main_screen):
copy_menu_builder = ContactMenuBuilder()
(copy_menu_builder
.with_name(util_ui.tr('Copy'))
.with_action(util_ui.tr('Name'), lambda: main_screen.copy_text(self._contact.name))
.with_action(util_ui.tr('Status message'), lambda: main_screen.copy_text(self._contact.status_message))
.with_action(util_ui.tr('Public key'), lambda: main_screen.copy_text(self._contact.tox_id))
)
return copy_menu_builder
@staticmethod
def _generate_plugins_menu_builder(plugin_loader, number):
if plugin_loader is None:
@ -151,7 +153,30 @@ class FriendMenuGenerator(BaseContactMenuGenerator):
return plugins_menu_builder
def _generate_groups_menu(self, contacts_manager): # TODO: fix
def _generate_groups_menu(self, contacts_manager, groups_service):
chats = contacts_manager.get_group_chats()
if not len(chats) or self._contact.status is None:
return None
groups_menu_builder = ContactMenuBuilder()
(groups_menu_builder
.with_name(util_ui.tr('Invite to group'))
.with_actions([(g.name, lambda: groups_service.invite_friend(self._contact.number, g.number)) for g in chats])
)
return groups_menu_builder
class GroupMenuGenerator(BaseContactMenuGenerator):
def generate(self, plugin_loader, contacts_manager, main_screen, settings, number, groups_service):
copy_menu_builder = self._generate_copy_menu_builder(main_screen)
builder = ContactMenuBuilder()
menu = (builder
.with_action(util_ui.tr('Set alias'), lambda: main_screen.set_alias(number))
.with_submenu(copy_menu_builder)
.with_action(util_ui.tr('Leave group'), lambda: groups_service.leave_group(self._contact.number))
.with_action(util_ui.tr('Notes'), lambda: main_screen.show_note(self._contact))
).build()
return menu

View File

@ -1,4 +1,5 @@
from contacts.friend import Friend
from contacts.group_chat import GroupChat
from messenger.messages import *
@ -47,7 +48,7 @@ class ContactsManager:
if self.is_active_a_friend():
return False
return self.get_curr_contact().number == friend_number
return self.get_curr_contact().number == group_number
# -----------------------------------------------------------------------------------------------------------------
# Work with active friend
@ -194,8 +195,11 @@ class ContactsManager:
# 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_friend_by_number(self, number):
return list(filter(lambda x: x.number == number and type(x) is Friend, self._contacts))[0]
def get_group_by_number(self, number):
return list(filter(lambda x: x.number == number and type(x) is GroupChat, self._contacts))[0]
def get_last_message(self):
if self._active_contact + 1:
@ -261,8 +265,6 @@ class ContactsManager:
except:
pass
self._settings.save()
# if num == self.get_active_number() and self.is_active_a_friend():
# self.update()
def friend_public_key(self, num):
return self._contacts[num].tox_id
@ -277,22 +279,9 @@ class ContactsManager:
:param num: number of friend in list
"""
friend = self._contacts[num]
try:
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 self._settings['notes']:
del self._settings['notes'][friend.tox_id]
self._settings.save()
self._history.delete_history(friend)
self._cleanup_contact_data(friend)
self._tox.friend_delete(friend.number)
del self._contacts[num]
self._screen.friends_list.takeItem(num)
if num == self._active_contact: # active friend was deleted
self.set_active(0 if len(self._contacts) else -1)
data = self._tox.get_savedata()
self._profile_manager.save_profile(data)
self._delete_contact(num)
def add_friend(self, tox_id):
"""
@ -302,12 +291,8 @@ class ContactsManager:
self._history.add_friend_to_db(tox_id)
friend = self._contact_provider.get_friend_by_public_key(tox_id)
self._contacts.append(friend)
friend.reset_avatar()
def add_group(self, group_number):
group = self._contact_provider.get_group_by_number(group_number)
self._contacts.append(group)
group.reset_avatar()
friend.reset_avatar(self._settings['identicons'])
self._save_profile()
def block_user(self, tox_id):
"""
@ -343,7 +328,19 @@ class ContactsManager:
# -----------------------------------------------------------------------------------------------------------------
def get_group_chats(self):
return list(filter(lambda c: type(c) is not Friend, self._contacts)) # TODO: fix after gc implementation
return list(filter(lambda c: type(c) is GroupChat, self._contacts))
def add_group(self, group_number):
group = self._contact_provider.get_group_by_number(group_number)
self._contacts.append(group)
group.reset_avatar(self._settings['identicons'])
self._save_profile()
def delete_group(self, group_number):
group = self.get_group_by_number(group_number)
self._cleanup_contact_data(group)
num = self._contacts.index(group)
self._delete_contact(num)
# -----------------------------------------------------------------------------------------------------------------
# Friend requests
@ -454,3 +451,25 @@ class ContactsManager:
pixmap = QtGui.QPixmap(avatar_path)
self._screen.account_avatar.setPixmap(pixmap.scaled(width, width,
QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))
def _save_profile(self):
data = self._tox.get_savedata()
self._profile_manager.save_profile(data)
def _cleanup_contact_data(self, contact):
try:
index = list(map(lambda x: x[0], self._settings['friends_aliases'])).index(contact.tox_id)
del self._settings['friends_aliases'][index]
except:
pass
if contact.tox_id in self._settings['notes']:
del self._settings['notes'][contact.tox_id]
self._settings.save()
self._history.delete_history(contact)
def _delete_contact(self, num):
del self._contacts[num]
self._screen.friends_list.takeItem(num)
if num == self._active_contact: # active friend was deleted
self.set_active(0 if len(self._contacts) else -1)
self._save_profile()

View File

@ -39,4 +39,4 @@ class FriendFactory:
Method-factory
:return: new widget for friend instance
"""
return self._items_factory.create_friend_item()
return self._items_factory.create_contact_item()

View File

@ -1,13 +1,14 @@
from contacts import contact
from contacts.contact_menu import GroupMenuGenerator
import utils.util as util
from wrapper.toxcore_enums_and_consts import *
from groups.group_peer import GroupChatPeer
from wrapper import toxcore_enums_and_consts as constants
class GroupChat(contact.Contact):
def __init__(self, profile_manager, name, status_message, widget, tox, group_number):
super().__init__(None, group_number, profile_manager, name, status_message, widget, None)
def __init__(self, tox, 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._tox = tox
self.set_status(constants.TOX_USER_STATUS['NONE'])
self._peers = []
@ -20,25 +21,29 @@ class GroupChat(contact.Contact):
def remove_invalid_unsent_files(self):
pass
def get_names(self):
peers_count = self._tox.group_number_peers(self._number)
names = []
for i in range(peers_count):
name = self._tox.group_peername(self._number, i)
names.append(name)
names = sorted(names, key=lambda n: n.lower())
return names
def get_context_menu_generator(self):
return GroupMenuGenerator(self)
def get_full_status(self):
names = self.get_names()
return '\n'.join(names)
def get_peer_name(self, peer_number):
return self._tox.group_peername(self._number, peer_number)
# -----------------------------------------------------------------------------------------------------------------
# Peers methods
# -----------------------------------------------------------------------------------------------------------------
def get_self_name(self):
return self._peers[0].name
def add_peer(self, peer_id):
peer = GroupChatPeer(peer_id,
self._tox.group_peer_get_name(self._number, peer_id),
self._tox.group_peer_get_status(self._number, peer_id),
self._tox.group_peer_get_role(self._number, peer_id),
self._tox.group_peer_get_public_key(self._number, peer_id))
self._peers.append(peer)
def get_peer(self, peer_id):
peers = list(filter(lambda p: p.id == peer_id, self._peers))
return peers[0]
# -----------------------------------------------------------------------------------------------------------------
# Private methods
# -----------------------------------------------------------------------------------------------------------------
@ -48,4 +53,5 @@ class GroupChat(contact.Contact):
return util.join_path(util.get_images_directory(), 'group.png')
def _add_self_to_gc(self):
pass
peer_id = self._tox.group_self_get_peer_id(self._number)
self.add_peer(peer_id)

View File

@ -1,6 +1,49 @@
from contacts.group_chat import GroupChat
class GroupFactory:
def __init__(self, profile_manager, settings, tox, db, items_factory):
self._profile_manager = profile_manager
self._settings, self._tox = settings, tox
self._db = db
self._items_factory = items_factory
def create_group_by_public_key(self, public_key):
pass
group_number = self._get_group_number_by_chat_id(public_key)
return self.create_group_by_number(group_number)
def create_group_by_number(self, group_number):
aliases = self._settings['friends_aliases']
tox_id = self._tox.group_get_chat_id(group_number)
try:
alias = list(filter(lambda x: x[0] == tox_id, aliases))[0][1]
except:
alias = ''
item = self._create_group_item()
name = alias or self._tox.group_get_name(group_number) or tox_id
status_message = self._tox.group_get_topic(group_number)
message_getter = self._db.messages_getter(tox_id)
group = GroupChat(self._tox, self._profile_manager, message_getter, group_number, name, status_message,
item, tox_id)
group.set_alias(alias)
return group
# -----------------------------------------------------------------------------------------------------------------
# Private methods
# -----------------------------------------------------------------------------------------------------------------
def _create_group_item(self):
"""
Method-factory
:return: new widget for group instance
"""
return self._items_factory.create_contact_item()
def _get_group_number_by_chat_id(self, chat_id):
for i in range(self._tox.group_get_number_groups()):
if self._tox.group_get_chat_id(i) == chat_id:
return i
return -1

View File

@ -2,9 +2,43 @@
class GroupChatPeer:
def __init__(self, peer_number, name, status, role, public_key):
self.peer_number = peer_number
self.name = name
self.status = status
self.role = role
self.public_key = public_key
def __init__(self, peer_id, name, status, role, public_key):
self._peer_id = peer_id
self._name = name
self._status = status
self._role = role
self._public_key = public_key
def get_id(self):
return self._peer_id
id = property(get_id)
def get_name(self):
return self._name
def set_name(self, name):
self._name = name
name = property(get_name, set_name)
def get_status(self):
return self._status
def set_status(self, status):
self._status = status
status = property(get_status, set_status)
def get_role(self):
return self._role
def set_role(self, role):
self._role = role
role = property(get_role, set_role)
def get_public_key(self):
return self._public_key
public_key = property(get_public_key)

View File

@ -1,4 +1,5 @@
import common.tox_save as tox_save
import utils.ui as util_ui
class GroupsService(tox_save.ToxSave):
@ -24,9 +25,38 @@ class GroupsService(tox_save.ToxSave):
group_number = self._tox.group_invite_accept(invite_data, friend_number, password)
self._add_new_group_by_number(group_number)
# -----------------------------------------------------------------------------------------------------------------
# Groups reconnect and leaving
# -----------------------------------------------------------------------------------------------------------------
def leave_group(self, group_number):
group = self._get_group(group_number)
self._tox.group_leave(group_number)
self._contacts_manager.delete_group(group_number)
self._contacts_provider.remove_contact_from_cache(group.tox_id)
# -----------------------------------------------------------------------------------------------------------------
# Group invites
# -----------------------------------------------------------------------------------------------------------------
def invite_friend(self, friend_number, group_number):
self._tox.group_invite_friend(group_number, friend_number)
def process_group_invite(self, friend_number, invite_data):
friend = self._get_friend(friend_number)
text = util_ui.tr('Friend {} invites you to group. Accept?')
if util_ui.question(text.format(friend.name), util_ui.tr('Group invite')):
self.join_gc_via_invite(invite_data, friend_number, None)
# -----------------------------------------------------------------------------------------------------------------
# Private methods
# -----------------------------------------------------------------------------------------------------------------
def _add_new_group_by_number(self, group_number):
self._contacts_manager.add_group(group_number)
def _get_group(self, group_number):
return self._contacts_provider.get_group_by_number(group_number)
def _get_friend(self, friend_number):
return self._contacts_provider.get_friend_by_number(friend_number)

View File

@ -398,8 +398,26 @@ def group_self_join(contacts_provider):
def group_peer_join(contacts_provider):
def wrapped(tox, group_number, peer_id, user_data):
gc = contacts_provider.get_group_by_number(group_number)
gc.add_peer(peer_id)
group = contacts_provider.get_group_by_number(group_number)
group.add_peer(peer_id)
return wrapped
def group_peer_name(contacts_provider):
def wrapped(tox, group_number, peer_id, name, length, user_data):
group = contacts_provider.get_group_by_number(group_number)
peer = group.get_peer(peer_id)
peer.name = str(name[:length])
return wrapped
def group_peer_status(contacts_provider):
def wrapped(tox, group_number, peer_id, peer_status, user_data):
group = contacts_provider.get_group_by_number(group_number)
peer = group.get_peer(peer_id)
peer.status = peer_status
return wrapped
@ -463,3 +481,5 @@ def init_callbacks(tox, profile, settings, plugin_loader, contacts_manager,
tox.callback_group_invite(group_invite(groups_service), 0)
tox.callback_group_self_join(group_self_join(contacts_provider), 0)
tox.callback_group_peer_join(group_peer_join(contacts_provider), 0)
tox.callback_group_peer_name(group_peer_name(contacts_provider), 0)
tox.callback_group_peer_status(group_peer_status(contacts_provider), 0)

View File

@ -2,13 +2,13 @@ from ui.contact_items import *
from ui.messages_widgets import *
class FriendItemsFactory:
class ContactItemsFactory:
def __init__(self, settings, main_screen):
self._settings = settings
self._friends_list = main_screen.friends_list
def create_friend_item(self):
def create_contact_item(self):
item = ContactItem(self._settings)
elem = QtWidgets.QListWidgetItem(self._friends_list)
elem.setSizeHint(QtCore.QSize(250, item.height()))

View File

@ -18,11 +18,11 @@ class MainWindow(QtWidgets.QMainWindow):
self.setAcceptDrops(True)
self._saved = False
self._profile = None
self._file_transfer_handler = self._history_loader = self._calls_manager = None
self._file_transfer_handler = self._history_loader = self._groups_service = self._calls_manager = None
self.initUI()
def set_dependencies(self, widget_factory, tray, contacts_manager, messenger, profile, plugins_loader,
file_transfer_handler, history_loader, calls_manager):
file_transfer_handler, history_loader, calls_manager, groups_service):
self._widget_factory = widget_factory
self._tray = tray
self._contacts_manager = contacts_manager
@ -31,6 +31,7 @@ class MainWindow(QtWidgets.QMainWindow):
self._file_transfer_handler = file_transfer_handler
self._history_loader = history_loader
self._calls_manager = calls_manager
self._groups_service = groups_service
self.messageEdit.set_messenger(messenger)
def show(self):
@ -414,7 +415,6 @@ class MainWindow(QtWidgets.QMainWindow):
self.account_name.setGeometry(QtCore.QRect(100, 15, self.width() - 560, 25))
self.account_status.setGeometry(QtCore.QRect(100, 35, self.width() - 560, 25))
self.messageEdit.setFocus()
#self.profile.update()
def keyPressEvent(self, event):
key, modifiers = event.key(), event.modifiers()
@ -598,7 +598,8 @@ class MainWindow(QtWidgets.QMainWindow):
if contact is None or item is None:
return
generator = contact.get_context_menu_generator()
self.listMenu = generator.generate(self._plugins_loader, self._contacts_manager, self, self._settings, number)
self.listMenu = generator.generate(self._plugins_loader, self._contacts_manager, self, self._settings, number,
self._groups_service)
parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(0, 0))
self.listMenu.move(parent_position + pos)
self.listMenu.show()

View File

@ -1599,7 +1599,7 @@ class Tox:
result = Tox.libtoxcore.tox_group_reconnect(self._tox_pointer, groupnumber, byref(error))
return result
def group_leave(self, groupnumber, message):
def group_leave(self, groupnumber, message=''):
"""
Leaves a group.
@ -1887,7 +1887,7 @@ class Tox:
"""
error = c_int()
result = Tox.libtoxcore.tox_group_get_name_size(self._tox_pointer, groupnumber, byref(error))
return result
return int(result)
def group_get_name(self, groupnumber):
"""