profile.py refactoring, over9000 callbacks added, tests fixed
This commit is contained in:
parent
d7f1f15b04
commit
2441d2b690
4 changed files with 151 additions and 92 deletions
|
@ -2,8 +2,8 @@ from PySide import QtCore
|
||||||
from notifications import *
|
from notifications import *
|
||||||
from settings import Settings
|
from settings import Settings
|
||||||
from profile import Profile
|
from profile import Profile
|
||||||
|
from toxcore_enums_and_consts import *
|
||||||
# TODO: add all callbacks (remove test callbacks and use wrappers)
|
# TODO: add all callbacks (remove test callbacks and use wrappers)
|
||||||
# NOTE: don't forget to call repaint
|
|
||||||
|
|
||||||
|
|
||||||
class InvokeEvent(QtCore.QEvent):
|
class InvokeEvent(QtCore.QEvent):
|
||||||
|
@ -41,29 +41,82 @@ def self_connection_status(st, tox_link):
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
def friend_status(a, b, c, d):
|
def friend_status(tox, friend_num, new_status, user_data):
|
||||||
print "Friend connected! Friend's data: ", str(a), str(b), str(c)
|
"""
|
||||||
|
Check friend's status (none, busy, away)
|
||||||
|
"""
|
||||||
|
print "Friend's #{} status changed! New status: ".format(friend_num, new_status)
|
||||||
|
profile = Profile.get_instance()
|
||||||
|
friend = filter(lambda x: x.number == friend_num, profile.friends)[0]
|
||||||
|
invoke_in_main_thread(friend.set_status, new_status)
|
||||||
|
|
||||||
|
|
||||||
|
def friend_connection_status(tox, friend_num, new_status, user_data):
|
||||||
|
"""
|
||||||
|
Check friend's connection status (offline, udp, tcp)
|
||||||
|
"""
|
||||||
|
print "Friend #{} connected! Friend's status: ".format(friend_num, new_status)
|
||||||
|
profile = Profile.get_instance()
|
||||||
|
friend = filter(lambda x: x.number == friend_num, profile.friends)[0]
|
||||||
|
if new_status == TOX_CONNECTION['NONE']:
|
||||||
|
invoke_in_main_thread(friend.set_status, None)
|
||||||
|
elif friend.status is None:
|
||||||
|
invoke_in_main_thread(friend.set_status, TOX_USER_STATUS['NONE'])
|
||||||
|
|
||||||
|
|
||||||
|
def friend_name(window):
|
||||||
|
"""
|
||||||
|
:param window: main window
|
||||||
|
:return: function for callback friend_name. It updates friend's name
|
||||||
|
and calls window repaint
|
||||||
|
"""
|
||||||
|
def wrapped(tox, friend_num, name, size, user_data):
|
||||||
|
profile = Profile.get_instance()
|
||||||
|
friend = filter(lambda x: x.number == friend_num, profile.friends)[0]
|
||||||
|
print 'New name: ', str(friend_num), str(name)
|
||||||
|
invoke_in_main_thread(friend.set_name, name)
|
||||||
|
invoke_in_main_thread(window.update_active_friend)
|
||||||
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
|
def friend_status_message(window):
|
||||||
|
"""
|
||||||
|
:param window: main window
|
||||||
|
:return: function for callback friend_status_message. It updates friend's status message
|
||||||
|
and calls window repaint
|
||||||
|
"""
|
||||||
|
def wrapped(tox, friend_num, status_message, size, user_data):
|
||||||
|
profile = Profile.get_instance()
|
||||||
|
friend = filter(lambda x: x.number == friend_num, profile.friends)[0]
|
||||||
|
invoke_in_main_thread(friend.set_status_message, status_message)
|
||||||
|
print 'User #{} has new status: {}'.format(friend_num, status_message)
|
||||||
|
invoke_in_main_thread(window.update_active_friend)
|
||||||
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
def friend_message(window):
|
def friend_message(window):
|
||||||
"""
|
"""
|
||||||
:param window: main window
|
:param window: main window
|
||||||
:return: function for tox.callback_friend_message
|
:return: function for tox.callback_friend_message. Adds new message to list
|
||||||
"""
|
"""
|
||||||
def wrapped(tox, friend_number, message_type, message, size, user_data):
|
def wrapped(tox, friend_number, message_type, message, size, user_data):
|
||||||
print 'Message: ', message.decode('utf8')
|
print 'Message: ', message.decode('utf8')
|
||||||
if not window.isActiveWindow() and Settings()['notifications']:
|
if not window.isActiveWindow() and Settings()['notifications']:
|
||||||
tray_notification('Message', message.decode('utf8'))
|
tray_notification('Message', message.decode('utf8'))
|
||||||
profile = Profile.getInstance()
|
profile = Profile.get_instance()
|
||||||
invoke_in_main_thread(profile.newMessage, friend_number, message_type, message)
|
invoke_in_main_thread(profile.new_message, friend_number, message_type, message)
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
def init_callbacks(tox, window):
|
def init_callbacks(tox, window):
|
||||||
"""
|
"""
|
||||||
|
Initialization of all callbacks.
|
||||||
:param tox: tox instance
|
:param tox: tox instance
|
||||||
:param window: main window
|
:param window: main window
|
||||||
"""
|
"""
|
||||||
tox.callback_friend_status(friend_status, 0)
|
tox.callback_friend_status(friend_status, 0)
|
||||||
tox.callback_friend_message(friend_message(window), 0)
|
tox.callback_friend_message(friend_message(window), 0)
|
||||||
tox.callback_self_connection_status(self_connection_status(window.connection_status, tox), 0)
|
tox.callback_self_connection_status(self_connection_status(window.connection_status, tox), 0)
|
||||||
|
tox.callback_friend_connection_status(friend_connection_status, 0)
|
||||||
|
tox.callback_friend_name(friend_name(window), 0)
|
||||||
|
tox.callback_friend_status_message(friend_status_message(window), 0)
|
||||||
|
|
|
@ -5,9 +5,9 @@ from PySide import QtGui, QtCore
|
||||||
from menu import *
|
from menu import *
|
||||||
from profile import *
|
from profile import *
|
||||||
from toxcore_enums_and_consts import *
|
from toxcore_enums_and_consts import *
|
||||||
from util import curr_time
|
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: move list items to new file
|
||||||
class MessageItem(QtGui.QListWidget):
|
class MessageItem(QtGui.QListWidget):
|
||||||
|
|
||||||
def __init__(self, text, time, user='', message_type=TOX_MESSAGE_TYPE['NORMAL'], parent=None):
|
def __init__(self, text, time, user='', message_type=TOX_MESSAGE_TYPE['NORMAL'], parent=None):
|
||||||
|
@ -372,23 +372,20 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
|
|
||||||
def send_message(self):
|
def send_message(self):
|
||||||
text = self.messageEdit.toPlainText()
|
text = self.messageEdit.toPlainText()
|
||||||
if self.profile.sendMessage(text):
|
if self.profile.send_message(text):
|
||||||
self.messageEdit.clear()
|
self.messageEdit.clear()
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Functions which called when user click somewhere else
|
# Functions which called when user click somewhere else
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def friend_click(self, index):
|
def update_active_friend(self):
|
||||||
print 'row:', index.row()
|
friend = self.profile.get_active_friend_data()
|
||||||
num = index.row()
|
|
||||||
self.profile.setActive(num)
|
|
||||||
friend = self.profile.getActiveFriendData()
|
|
||||||
self.account_name.setText(friend[0])
|
self.account_name.setText(friend[0])
|
||||||
self.account_status.setText(friend[1])
|
self.account_status.setText(friend[1])
|
||||||
|
|
||||||
|
def friend_click(self, index):
|
||||||
if __name__ == '__main__':
|
print 'row:', index.row()
|
||||||
app = QtGui.QApplication(sys.argv)
|
num = index.row()
|
||||||
ex = MainWindow()
|
self.profile.set_active(num)
|
||||||
sys.exit(app.exec_())
|
self.update_active_friend()
|
||||||
|
|
147
src/profile.py
147
src/profile.py
|
@ -62,37 +62,39 @@ class Contact(object):
|
||||||
widget.name.setText(name)
|
widget.name.setText(name)
|
||||||
widget.status_message.setText(status_message)
|
widget.status_message.setText(status_message)
|
||||||
|
|
||||||
def getName(self):
|
def get_name(self):
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
def setName(self, value):
|
def set_name(self, value):
|
||||||
self._name = value
|
self._name = value
|
||||||
self._widget.name.setText(value)
|
self._widget.name.setText(value)
|
||||||
|
self._widget.name.repaint()
|
||||||
|
|
||||||
name = property(getName, setName)
|
name = property(get_name, set_name)
|
||||||
|
|
||||||
def getStatusMessage(self):
|
def get_status_message(self):
|
||||||
return self._status_message
|
return self._status_message
|
||||||
|
|
||||||
def setStatusMessage(self, value):
|
def set_status_message(self, value):
|
||||||
self._status_message = value
|
self._status_message = value
|
||||||
self._widget.status_message.setText(value)
|
self._widget.status_message.setText(value)
|
||||||
|
self._widget.status_message.repaint()
|
||||||
|
|
||||||
status_message = property(getStatusMessage, setStatusMessage)
|
status_message = property(get_status_message, set_status_message)
|
||||||
|
|
||||||
def getStatus(self):
|
def get_status(self):
|
||||||
return self._status
|
return self._status
|
||||||
|
|
||||||
def setStatus(self, value):
|
def set_status(self, value):
|
||||||
# TODO: status repaint
|
# TODO: status repaint
|
||||||
self._status = value
|
self._status = value
|
||||||
|
|
||||||
status = property(getStatus, setStatus)
|
status = property(get_status, set_status)
|
||||||
|
|
||||||
|
|
||||||
class Friend(Contact):
|
class Friend(Contact):
|
||||||
"""
|
"""
|
||||||
Friend in list of friends. Can be hidden, unread messages added
|
Friend in list of friends. Can be hidden, property 'has unread messages' added
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, number, *args):
|
def __init__(self, number, *args):
|
||||||
|
@ -101,32 +103,37 @@ class Friend(Contact):
|
||||||
self._new_messages = False
|
self._new_messages = False
|
||||||
self._visible = True
|
self._visible = True
|
||||||
|
|
||||||
def getVisibility(self):
|
def get_visibility(self):
|
||||||
return self._visible
|
return self._visible
|
||||||
|
|
||||||
def setVisibility(self, value):
|
def set_visibility(self, value):
|
||||||
self._widget.setVisibility(value)
|
self._widget.setVisibility(value)
|
||||||
self._visible = value
|
self._visible = value
|
||||||
|
|
||||||
visibility = property(getVisibility, setVisibility)
|
visibility = property(get_visibility, set_visibility)
|
||||||
|
|
||||||
def setMessages(self, value):
|
def get_messages(self):
|
||||||
|
return self._new_messages
|
||||||
|
|
||||||
|
def set_messages(self, value):
|
||||||
self._new_messages = value
|
self._new_messages = value
|
||||||
|
|
||||||
messages = property(None, setMessages)
|
messages = property(get_messages, set_messages)
|
||||||
|
|
||||||
def getNumber(self):
|
def get_number(self):
|
||||||
return self._number
|
return self._number
|
||||||
|
|
||||||
number = property(getNumber)
|
number = property(get_number)
|
||||||
# TODO: check if setNumber needed
|
# TODO: check if setNumber needed
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
del self._widget
|
||||||
|
|
||||||
|
|
||||||
class Profile(Contact):
|
class Profile(Contact):
|
||||||
"""
|
"""
|
||||||
Profile of current toxygen user. Contains friends list, tox instance
|
Profile of current toxygen user. Contains friends list, tox instance, list of messages
|
||||||
"""
|
"""
|
||||||
# TODO: add unicode support in messages
|
|
||||||
def __init__(self, tox, widgets, widget, messages_list):
|
def __init__(self, tox, widgets, widget, messages_list):
|
||||||
self._widget = widget
|
self._widget = widget
|
||||||
self._messages = messages_list
|
self._messages = messages_list
|
||||||
|
@ -144,50 +151,58 @@ class Profile(Contact):
|
||||||
Profile._instance = self
|
Profile._instance = self
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getInstance():
|
def get_instance():
|
||||||
return Profile._instance
|
return Profile._instance
|
||||||
|
|
||||||
def getActive(self):
|
def change_status(self):
|
||||||
return self._active_friend
|
if self._status is not None:
|
||||||
|
self._status += 1
|
||||||
def setActive(self, value):
|
self._status %= 3
|
||||||
try:
|
|
||||||
visible_friends = filter(lambda num, friend: friend.visibility, enumerate(self.friends))
|
|
||||||
self._active_friend = visible_friends[value][0]
|
|
||||||
self._messages.clear()
|
|
||||||
# TODO: load history
|
|
||||||
except: # no friend found. ignore
|
|
||||||
log('Incorrect friend value: ' + str(value))
|
|
||||||
|
|
||||||
active_friend = property(getActive, setActive)
|
|
||||||
|
|
||||||
def getActiveFriendData(self):
|
|
||||||
friend = self.friends[self._active_friend]
|
|
||||||
return friend.name, friend.status_message
|
|
||||||
|
|
||||||
def getActiveNumber(self):
|
|
||||||
return self.friends[self._active_friend].number
|
|
||||||
|
|
||||||
def getActiveName(self):
|
|
||||||
return self.friends[self._active_friend].name
|
|
||||||
|
|
||||||
def isActiveOnline(self):
|
|
||||||
if not self._active_friend + 1: # no active friend
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
# TODO: callbacks!
|
|
||||||
return True
|
|
||||||
status = self.friends[self._active_friend].status
|
|
||||||
return status is not None
|
|
||||||
|
|
||||||
def filtration(self, show_online=True, filter_str=''):
|
def filtration(self, show_online=True, filter_str=''):
|
||||||
for friend in self.friends:
|
for friend in self.friends:
|
||||||
friend.visibility = (friend.status is not None or not show_online) and (filter_str in friend.name)
|
friend.visibility = (friend.status is not None or not show_online) and (filter_str in friend.name)
|
||||||
|
|
||||||
def newMessage(self, id, message_type, message):
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
# Work with active friend
|
||||||
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def get_active(self):
|
||||||
|
return self._active_friend
|
||||||
|
|
||||||
|
def set_active(self, value):
|
||||||
|
try:
|
||||||
|
visible_friends = filter(lambda elem: elem[1].visibility, enumerate(self.friends))
|
||||||
|
self._active_friend = visible_friends[value][0]
|
||||||
|
self._messages.clear()
|
||||||
|
self._messages.repaint()
|
||||||
|
# TODO: load history
|
||||||
|
except: # no friend found. ignore
|
||||||
|
log('Incorrect friend value: ' + str(value))
|
||||||
|
|
||||||
|
active_friend = property(get_active, set_active)
|
||||||
|
|
||||||
|
def get_active_friend_data(self):
|
||||||
|
friend = self.friends[self._active_friend]
|
||||||
|
return friend.name, friend.status_message
|
||||||
|
|
||||||
|
def get_active_number(self):
|
||||||
|
return self.friends[self._active_friend].number
|
||||||
|
|
||||||
|
def get_active_name(self):
|
||||||
|
return self.friends[self._active_friend].name
|
||||||
|
|
||||||
|
def is_active_online(self):
|
||||||
|
return self._active_friend + 1 and self.friends[self._active_friend].status is not None
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
# Private messages
|
||||||
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def new_message(self, id, message_type, message):
|
||||||
if id == self._active_friend: # add message to list
|
if id == self._active_friend: # add message to list
|
||||||
user_name = Profile.getInstance().getActiveName()
|
user_name = Profile.get_instance().get_active_name()
|
||||||
item = mainscreen.MessageItem(message, curr_time(), user_name, message_type)
|
item = mainscreen.MessageItem(message.decode('utf-8'), curr_time(), user_name, message_type)
|
||||||
elem = QtGui.QListWidgetItem(self._messages)
|
elem = QtGui.QListWidgetItem(self._messages)
|
||||||
elem.setSizeHint(QtCore.QSize(500, 100))
|
elem.setSizeHint(QtCore.QSize(500, 100))
|
||||||
self._messages.addItem(elem)
|
self._messages.addItem(elem)
|
||||||
|
@ -195,17 +210,17 @@ class Profile(Contact):
|
||||||
self._messages.scrollToBottom()
|
self._messages.scrollToBottom()
|
||||||
self._messages.repaint()
|
self._messages.repaint()
|
||||||
else:
|
else:
|
||||||
friend = filter(lambda x: x.getNumber() == id, self.friends)[0]
|
friend = filter(lambda x: x.number == id, self.friends)[0]
|
||||||
friend.setMessages(True)
|
friend.set_messages(True)
|
||||||
|
|
||||||
def sendMessage(self, text):
|
def send_message(self, text):
|
||||||
if self.isActiveOnline() and text:
|
if self.is_active_online() and text:
|
||||||
if text.startswith('/me'):
|
if text.startswith('/me'):
|
||||||
message_type = TOX_MESSAGE_TYPE['ACTION']
|
message_type = TOX_MESSAGE_TYPE['ACTION']
|
||||||
text = text[3:]
|
text = text[3:]
|
||||||
else:
|
else:
|
||||||
message_type = TOX_MESSAGE_TYPE['NORMAL']
|
message_type = TOX_MESSAGE_TYPE['NORMAL']
|
||||||
self.tox.friend_send_message(self._active_friend, message_type, text)
|
self.tox.friend_send_message(self._active_friend, message_type, text.encode('utf-8'))
|
||||||
item = mainscreen.MessageItem(text, curr_time(), self._name, message_type)
|
item = mainscreen.MessageItem(text, curr_time(), self._name, message_type)
|
||||||
elem = QtGui.QListWidgetItem(self._messages)
|
elem = QtGui.QListWidgetItem(self._messages)
|
||||||
elem.setSizeHint(QtCore.QSize(500, 100))
|
elem.setSizeHint(QtCore.QSize(500, 100))
|
||||||
|
@ -217,10 +232,14 @@ class Profile(Contact):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def changeStatus(self):
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
if self._status is not None:
|
# Work with friends (add, remove)
|
||||||
self._status += 1
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
self._status %= 3
|
|
||||||
|
def delete_friend(self, num):
|
||||||
|
self.tox.friend_delete(num)
|
||||||
|
friend = filter(lambda x: x.number == num, self.friends)[0]
|
||||||
|
del friend
|
||||||
|
|
||||||
|
|
||||||
def tox_factory(data=None, settings=None):
|
def tox_factory(data=None, settings=None):
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from src.settings import Settings
|
from src.settings import Settings
|
||||||
from src.util import bin_to_string, string_to_bin
|
|
||||||
import sys
|
import sys
|
||||||
from src.bootstrap import node_generator
|
from src.bootstrap import node_generator
|
||||||
from src.profile import *
|
from src.profile import *
|
||||||
|
@ -37,15 +36,6 @@ class TestProfile():
|
||||||
assert new_data == data
|
assert new_data == data
|
||||||
|
|
||||||
|
|
||||||
class TestUtils():
|
|
||||||
|
|
||||||
def test_convert(self):
|
|
||||||
id = 'C4CEB8C7AC607C6B374E2E782B3C00EA3A63B80D4910B8649CCACDD19F260819'
|
|
||||||
data = string_to_bin(id)
|
|
||||||
new_id = bin_to_string(data)
|
|
||||||
assert id == new_id
|
|
||||||
|
|
||||||
|
|
||||||
class TestNodeGen():
|
class TestNodeGen():
|
||||||
|
|
||||||
def test_generator(self):
|
def test_generator(self):
|
||||||
|
|
Loading…
Reference in a new issue