refactoring - login screen, incorrect refs
This commit is contained in:
parent
1bead7d55d
commit
85467e1885
21 changed files with 302 additions and 254 deletions
|
@ -1,50 +1,60 @@
|
|||
import communication.callbacks
|
||||
import threads
|
||||
|
||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||
import ui.password_screen as passwordscreen
|
||||
from util.util import curr_directory, get_platform, get_images_directory, get_styles_directory, log
|
||||
import updater.updater as updater
|
||||
import os
|
||||
from communication.tox_factory import tox_factory
|
||||
import wrapper.libtox as libtox
|
||||
import user_data.toxes
|
||||
from user_data.settings import Settings
|
||||
from ui.login_screen import LoginScreen
|
||||
from user_data.profile_manager import ProfileManager
|
||||
|
||||
|
||||
class App:
|
||||
|
||||
def __init__(self, path_or_uri=None):
|
||||
def __init__(self, path_to_profile=None, uri=None):
|
||||
self.tox = self.ms = self.init = self.app = self.tray = self.mainloop = self.avloop = None
|
||||
if path_or_uri is None:
|
||||
self.uri = self.path = None
|
||||
elif path_or_uri.startswith('tox:'):
|
||||
self.path = None
|
||||
self.uri = path_or_uri[4:]
|
||||
else:
|
||||
self.path = path_or_uri
|
||||
self.uri = None
|
||||
self.uri = self.path = self.toxes = None
|
||||
if uri is not None and uri.startswith('tox:'):
|
||||
self.uri = uri[4:]
|
||||
if path_to_profile is not None:
|
||||
self.path = path_to_profile
|
||||
|
||||
def enter_pass(self, data):
|
||||
"""
|
||||
Show password screen
|
||||
"""
|
||||
tmp = [data]
|
||||
p = PasswordScreen(toxes.ToxES.get_instance(), tmp)
|
||||
p = passwordscreen.PasswordScreen(self.toxes, data)
|
||||
p.show()
|
||||
self.app.lastWindowClosed.connect(self.app.quit)
|
||||
self.app.exec_()
|
||||
if tmp[0] == data:
|
||||
result = p.result
|
||||
if result is None:
|
||||
raise SystemExit()
|
||||
else:
|
||||
return tmp[0]
|
||||
return result
|
||||
|
||||
def main(self):
|
||||
"""
|
||||
Main function of app. loads login screen if needed and starts main screen
|
||||
"""
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
app.setWindowIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
|
||||
app = QtWidgets.QApplication([])
|
||||
icon_file = os.path.join(get_images_directory(), 'icon.png')
|
||||
app.setWindowIcon(QtGui.QIcon(icon_file))
|
||||
self.app = app
|
||||
|
||||
if platform.system() == 'Linux':
|
||||
if get_platform() == 'Linux':
|
||||
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
|
||||
|
||||
with open(curr_directory() + '/styles/dark_style.qss') as fl:
|
||||
with open(os.path.join(get_styles_directory(), 'dark_style.qss')) as fl:
|
||||
style = fl.read()
|
||||
app.setStyleSheet(style)
|
||||
|
||||
encrypt_save = toxes.ToxES()
|
||||
encrypt_save = libtox.LibToxEncryptSave()
|
||||
toxes = user_data.toxes.ToxES(encrypt_save)
|
||||
|
||||
if self.path is not None:
|
||||
path = os.path.dirname(self.path) + '/'
|
||||
|
@ -70,15 +80,13 @@ class App:
|
|||
ls = LoginScreen()
|
||||
ls.setWindowIconText("Toxygen")
|
||||
profiles = ProfileManager.find_profiles()
|
||||
ls.update_select(map(lambda x: x[1], profiles))
|
||||
_login = self.Login(profiles)
|
||||
ls.update_on_close(_login.login_screen_close)
|
||||
ls.update_select(profiles)
|
||||
ls.show()
|
||||
app.exec_()
|
||||
if not _login.t:
|
||||
result = ls.result
|
||||
if result is None:
|
||||
return
|
||||
elif _login.t == 1: # create new profile
|
||||
_login.name = _login.name.strip()
|
||||
elif result.is_new_profile(): # create new profile
|
||||
name = _login.name if _login.name else 'toxygen_user'
|
||||
pr = map(lambda x: x[1], ProfileManager.find_profiles())
|
||||
if name in list(pr):
|
||||
|
@ -130,14 +138,14 @@ class App:
|
|||
settings['language'] = curr_lang
|
||||
settings.save()
|
||||
else: # load existing profile
|
||||
path, name = _login.get_data()
|
||||
if _login.default:
|
||||
Settings.set_auto_profile(path, name)
|
||||
data = ProfileManager(path, name).open_profile()
|
||||
if encrypt_save.is_data_encrypted(data):
|
||||
path = result.profile_path
|
||||
if result.load_as_default:
|
||||
Settings.set_auto_profile(path)
|
||||
settings = Settings(toxes, path)
|
||||
data = ProfileManager(settings, toxes, path).open_profile()
|
||||
if toxes.is_data_encrypted(data):
|
||||
data = self.enter_pass(data)
|
||||
settings = Settings(name)
|
||||
self.tox = profile.tox_factory(data, settings)
|
||||
self.tox = communication.tox_factory.tox_factory(data, settings)
|
||||
else:
|
||||
path, name = auto_profile
|
||||
data = ProfileManager(path, name).open_profile()
|
||||
|
|
|
@ -5,10 +5,7 @@ from contacts.profile import Profile
|
|||
from wrapper.toxcore_enums_and_consts import *
|
||||
from wrapper.toxav_enums import *
|
||||
from wrapper.tox import bin_to_string
|
||||
from plugin_support import PluginLoader
|
||||
import queue
|
||||
import threading
|
||||
import util
|
||||
from plugin_support.plugin_support import PluginLoader
|
||||
import cv2
|
||||
import numpy as np
|
||||
from threads import invoke_in_main_thread, execute
|
||||
|
@ -31,6 +28,7 @@ def self_connection_status(tox, profile):
|
|||
invoke_in_main_thread(profile.set_status, status)
|
||||
elif connection == TOX_CONNECTION['NONE']:
|
||||
invoke_in_main_thread(profile.set_status, None)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
|
@ -132,41 +130,45 @@ def friend_request(contacts_manager):
|
|||
return wrapped
|
||||
|
||||
|
||||
def friend_typing(tox, friend_number, typing, user_data):
|
||||
invoke_in_main_thread(Profile.get_instance().friend_typing, friend_number, typing)
|
||||
def friend_typing(contacts_manager):
|
||||
def wrapped(tox, friend_number, typing, user_data):
|
||||
invoke_in_main_thread(contacts_manager.friend_typing, friend_number, typing)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
def friend_read_receipt(tox, friend_number, message_id, user_data):
|
||||
profile = Profile.get_instance()
|
||||
profile.get_friend_by_number(friend_number).dec_receipt()
|
||||
if friend_number == profile.get_active_number():
|
||||
invoke_in_main_thread(profile.receipt)
|
||||
def friend_read_receipt(contacts_manager):
|
||||
def wrapped(tox, friend_number, message_id, user_data):
|
||||
contacts_manager.get_friend_by_number(friend_number).dec_receipt()
|
||||
if friend_number == contacts_manager.get_active_number():
|
||||
invoke_in_main_thread(contacts_manager.receipt)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Callbacks - file transfers
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def tox_file_recv(window, tray):
|
||||
def tox_file_recv(window, tray, profile, file_transfer_handler, contacts_manager, settings):
|
||||
"""
|
||||
New incoming file
|
||||
"""
|
||||
def wrapped(tox, friend_number, file_number, file_type, size, file_name, file_name_size, user_data):
|
||||
profile = Profile.get_instance()
|
||||
settings = Settings.get_instance()
|
||||
if file_type == TOX_FILE_KIND['DATA']:
|
||||
print('File')
|
||||
try:
|
||||
file_name = str(file_name[:file_name_size], 'utf-8')
|
||||
except:
|
||||
file_name = 'toxygen_file'
|
||||
invoke_in_main_thread(profile.incoming_file_transfer,
|
||||
invoke_in_main_thread(file_transfer_handler.incoming_file_transfer,
|
||||
friend_number,
|
||||
file_number,
|
||||
size,
|
||||
file_name)
|
||||
if not window.isActiveWindow():
|
||||
friend = profile.get_friend_by_number(friend_number)
|
||||
friend = contacts_manager.get_friend_by_number(friend_number)
|
||||
if settings['notifications'] and profile.status != TOX_USER_STATUS['BUSY'] and not settings.locked:
|
||||
file_from = QtWidgets.QApplication.translate("Callback", "File from")
|
||||
invoke_in_main_thread(tray_notification, file_from + ' ' + friend.name, file_name, tray, window)
|
||||
|
@ -175,7 +177,7 @@ def tox_file_recv(window, tray):
|
|||
invoke_in_main_thread(tray.setIcon, QtGui.QIcon(curr_directory() + '/images/icon_new_messages.png'))
|
||||
else: # AVATAR
|
||||
print('Avatar')
|
||||
invoke_in_main_thread(profile.incoming_avatar,
|
||||
invoke_in_main_thread(file_transfer_handler.incoming_avatar,
|
||||
friend_number,
|
||||
file_number,
|
||||
size)
|
||||
|
@ -222,16 +224,19 @@ def file_recv_control(file_transfer_handler):
|
|||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def lossless_packet(tox, friend_number, data, length, user_data):
|
||||
def lossless_packet(plugin_loader):
|
||||
def wrapped(tox, friend_number, data, length, user_data):
|
||||
"""
|
||||
Incoming lossless packet
|
||||
"""
|
||||
data = data[:length]
|
||||
plugin = PluginLoader.get_instance()
|
||||
invoke_in_main_thread(plugin.callback_lossless, friend_number, data)
|
||||
invoke_in_main_thread(plugin_loader.callback_lossless, friend_number, data)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
def lossy_packet(tox, friend_number, data, length, user_data):
|
||||
def lossy_packet(plugin_loader):
|
||||
def wrapped(tox, friend_number, data, length, user_data):
|
||||
"""
|
||||
Incoming lossy packet
|
||||
"""
|
||||
|
@ -239,39 +244,50 @@ def lossy_packet(tox, friend_number, data, length, user_data):
|
|||
plugin = PluginLoader.get_instance()
|
||||
invoke_in_main_thread(plugin.callback_lossy, friend_number, data)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Callbacks - audio
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
def call_state(toxav, friend_number, mask, user_data):
|
||||
def call_state(calls_manager):
|
||||
def wrapped(toxav, friend_number, mask, user_data):
|
||||
"""
|
||||
New call state
|
||||
"""
|
||||
print(friend_number, mask)
|
||||
if mask == TOXAV_FRIEND_CALL_STATE['FINISHED'] or mask == TOXAV_FRIEND_CALL_STATE['ERROR']:
|
||||
invoke_in_main_thread(Profile.get_instance().stop_call, friend_number, True)
|
||||
invoke_in_main_thread(calls_manager.stop_call, friend_number, True)
|
||||
else:
|
||||
Profile.get_instance().call.toxav_call_state_cb(friend_number, mask)
|
||||
calls_manager.toxav_call_state_cb(friend_number, mask)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
def call(toxav, friend_number, audio, video, user_data):
|
||||
def call(calls_manager):
|
||||
def wrapped(toxav, friend_number, audio, video, user_data):
|
||||
"""
|
||||
Incoming call from friend
|
||||
"""
|
||||
print(friend_number, audio, video)
|
||||
invoke_in_main_thread(Profile.get_instance().incoming_call, audio, video, friend_number)
|
||||
invoke_in_main_thread(calls_manager.incoming_call, audio, video, friend_number)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
def callback_audio(toxav, friend_number, samples, audio_samples_per_channel, audio_channels_count, rate, user_data):
|
||||
def callback_audio(calls_manager):
|
||||
def wrapped(toxav, friend_number, samples, audio_samples_per_channel, audio_channels_count, rate, user_data):
|
||||
"""
|
||||
New audio chunk
|
||||
"""
|
||||
Profile.get_instance().call.audio_chunk(
|
||||
calls_manager.call.audio_chunk(
|
||||
bytes(samples[:audio_samples_per_channel * 2 * audio_channels_count]),
|
||||
audio_channels_count,
|
||||
rate)
|
||||
|
||||
return wrapped
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Callbacks - video
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
@ -333,11 +349,6 @@ def video_receive_frame(toxav, friend_number, width, height, y, u, v, ystride, u
|
|||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def group_invite(tox, friend_number, gc_type, data, length, user_data):
|
||||
invoke_in_main_thread(Profile.get_instance().group_invite, friend_number, gc_type,
|
||||
bytes(data[:length]))
|
||||
|
||||
|
||||
def show_gc_notification(window, tray, message, group_number, peer_number):
|
||||
profile = Profile.get_instance()
|
||||
settings = Settings.get_instance()
|
||||
|
@ -350,72 +361,40 @@ def show_gc_notification(window, tray, message, group_number, peer_number):
|
|||
sound_notification(SOUND_NOTIFICATION['MESSAGE'])
|
||||
invoke_in_main_thread(tray.setIcon, QtGui.QIcon(curr_directory() + '/images/icon_new_messages.png'))
|
||||
|
||||
|
||||
def group_message(window, tray):
|
||||
def wrapped(tox, group_number, peer_number, message, length, user_data):
|
||||
message = str(message[:length], 'utf-8')
|
||||
invoke_in_main_thread(Profile.get_instance().new_gc_message, group_number,
|
||||
peer_number, TOX_MESSAGE_TYPE['NORMAL'], message)
|
||||
show_gc_notification(window, tray, message, group_number, peer_number)
|
||||
return wrapped
|
||||
|
||||
|
||||
def group_action(window, tray):
|
||||
def wrapped(tox, group_number, peer_number, message, length, user_data):
|
||||
message = str(message[:length], 'utf-8')
|
||||
invoke_in_main_thread(Profile.get_instance().new_gc_message, group_number,
|
||||
peer_number, TOX_MESSAGE_TYPE['ACTION'], message)
|
||||
show_gc_notification(window, tray, message, group_number, peer_number)
|
||||
return wrapped
|
||||
|
||||
|
||||
def group_title(tox, group_number, peer_number, title, length, user_data):
|
||||
invoke_in_main_thread(Profile.get_instance().new_gc_title, group_number,
|
||||
title[:length])
|
||||
|
||||
|
||||
def group_namelist_change(tox, group_number, peer_number, change, user_data):
|
||||
invoke_in_main_thread(Profile.get_instance().update_gc, group_number)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# Callbacks - initialization
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def init_callbacks(tox, window, tray):
|
||||
def init_callbacks(tox, profile, settings, plugin_loader, contacts_manager,
|
||||
calls_manager, file_transfer_handler, window, tray):
|
||||
"""
|
||||
Initialization of all callbacks.
|
||||
:param tox: tox instance
|
||||
:param window: main window
|
||||
:param tray: tray (for notifications)
|
||||
"""
|
||||
tox.callback_self_connection_status(self_connection_status(tox), 0)
|
||||
tox.callback_self_connection_status(self_connection_status(tox, profile), 0)
|
||||
|
||||
tox.callback_friend_status(friend_status, 0)
|
||||
tox.callback_friend_message(friend_message(window, tray), 0)
|
||||
tox.callback_friend_connection_status(friend_connection_status, 0)
|
||||
tox.callback_friend_name(friend_name, 0)
|
||||
tox.callback_friend_status_message(friend_status_message, 0)
|
||||
tox.callback_friend_request(friend_request, 0)
|
||||
tox.callback_friend_typing(friend_typing, 0)
|
||||
tox.callback_friend_read_receipt(friend_read_receipt, 0)
|
||||
tox.callback_friend_status(friend_status(profile, settings), 0)
|
||||
tox.callback_friend_message(friend_message(profile, settings, window, tray), 0)
|
||||
tox.callback_friend_connection_status(friend_connection_status(profile, settings, plugin_loader), 0)
|
||||
tox.callback_friend_name(friend_name(profile), 0)
|
||||
tox.callback_friend_status_message(friend_status_message(profile), 0)
|
||||
tox.callback_friend_request(friend_request(contacts_manager), 0)
|
||||
tox.callback_friend_typing(friend_typing(contacts_manager), 0)
|
||||
tox.callback_friend_read_receipt(friend_read_receipt(contacts_manager), 0)
|
||||
|
||||
tox.callback_file_recv(tox_file_recv(window, tray), 0)
|
||||
tox.callback_file_recv_chunk(file_recv_chunk, 0)
|
||||
tox.callback_file_chunk_request(file_chunk_request, 0)
|
||||
tox.callback_file_recv_control(file_recv_control, 0)
|
||||
tox.callback_file_recv(tox_file_recv(window, tray, profile, file_transfer_handler, contacts_manager, settings), 0)
|
||||
tox.callback_file_recv_chunk(file_recv_chunk(file_transfer_handler), 0)
|
||||
tox.callback_file_chunk_request(file_chunk_request(file_transfer_handler), 0)
|
||||
tox.callback_file_recv_control(file_recv_control(file_transfer_handler), 0)
|
||||
|
||||
toxav = tox.AV
|
||||
toxav.callback_call_state(call_state, 0)
|
||||
toxav.callback_call(call, 0)
|
||||
toxav.callback_audio_receive_frame(callback_audio, 0)
|
||||
toxav.callback_call_state(call_state(calls_manager), 0)
|
||||
toxav.callback_call(call(calls_manager), 0)
|
||||
toxav.callback_audio_receive_frame(callback_audio(calls_manager), 0)
|
||||
toxav.callback_video_receive_frame(video_receive_frame, 0)
|
||||
|
||||
tox.callback_friend_lossless_packet(lossless_packet, 0)
|
||||
tox.callback_friend_lossy_packet(lossy_packet, 0)
|
||||
tox.callback_friend_lossless_packet(lossless_packet(plugin_loader), 0)
|
||||
tox.callback_friend_lossy_packet(lossy_packet(plugin_loader), 0)
|
||||
|
||||
tox.callback_group_invite(group_invite)
|
||||
tox.callback_group_message(group_message(window, tray))
|
||||
tox.callback_group_action(group_action(window, tray))
|
||||
tox.callback_group_title(group_title)
|
||||
tox.callback_group_namelist_change(group_namelist_change)
|
||||
|
|
|
@ -3,10 +3,9 @@ from PyQt5 import QtWidgets
|
|||
from contacts.friend import *
|
||||
from user_data.settings import *
|
||||
from wrapper.toxcore_enums_and_consts import *
|
||||
from ctypes import *
|
||||
from util import log, Singleton, curr_directory
|
||||
from util.util import log, curr_directory
|
||||
from network.tox_dns import tox_dns
|
||||
from db.database import *
|
||||
from history.database import *
|
||||
from file_transfers.file_transfers import *
|
||||
import time
|
||||
from av import calls
|
||||
|
@ -19,7 +18,7 @@ from contacts.group_chat import *
|
|||
import re
|
||||
|
||||
|
||||
class Profile(basecontact.BaseContact, Singleton):
|
||||
class Profile(basecontact.BaseContact):
|
||||
"""
|
||||
Profile of current toxygen user. Contains friends list, tox instance
|
||||
"""
|
||||
|
@ -33,7 +32,6 @@ class Profile(basecontact.BaseContact, Singleton):
|
|||
tox.self_get_status_message(),
|
||||
screen.user_info,
|
||||
tox.self_get_address())
|
||||
Singleton.__init__(self)
|
||||
self._screen = screen
|
||||
self._messages = screen.messages
|
||||
self._tox = tox
|
||||
|
@ -43,8 +41,6 @@ class Profile(basecontact.BaseContact, Singleton):
|
|||
self._factory = items_factory.ItemsFactory(self._screen.friends_list, self._messages)
|
||||
settings = Settings.get_instance()
|
||||
self._show_avatars = settings['show_avatars']
|
||||
self._paused_file_transfers = dict(settings['paused_file_transfers'])
|
||||
# key - file id, value: [path, friend number, is incoming, start position]
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
|
@ -97,6 +93,7 @@ class Profile(basecontact.BaseContact, Singleton):
|
|||
|
||||
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()
|
||||
|
|
|
@ -9,6 +9,8 @@ class FileTransfersHandler:
|
|||
self._tox = tox
|
||||
self._settings = settings
|
||||
self._file_transfers = {}
|
||||
self._paused_file_transfers = dict(settings['paused_file_transfers'])
|
||||
# key - file id, value: [path, friend number, is incoming, start position]
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------
|
||||
# File transfers support
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import sys
|
||||
import app
|
||||
from user_data.settings import *
|
||||
from util.util import curr_directory, program_version, remove
|
||||
from util.util import curr_directory, remove
|
||||
import argparse
|
||||
|
||||
__maintainer__ = 'Ingvar'
|
||||
__version__ = '0.5.0'
|
||||
|
||||
|
||||
def clean():
|
||||
"""Removes all windows libs from libs folder"""
|
||||
|
@ -15,30 +18,31 @@ def reset():
|
|||
Settings.reset_auto_profile()
|
||||
|
||||
|
||||
def print_toxygen_version():
|
||||
print('Toxygen v' + __version__)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--version')
|
||||
parser.add_argument('--clean')
|
||||
parser.add_argument('--reset')
|
||||
parser.add_argument('--version', help='Prints Toxygen version')
|
||||
parser.add_argument('--clean', help='Deletes toxcore libs from libs folder')
|
||||
parser.add_argument('--reset', help='Resets default profile')
|
||||
parser.add_argument('profile_path', nargs='?', default=None, help='Resets default profile')
|
||||
args = parser.parse_args()
|
||||
if not len(args):
|
||||
toxygen = app.App()
|
||||
else: # started with argument(s)
|
||||
arg = sys.argv[1]
|
||||
if arg == '--version':
|
||||
print('Toxygen v' + program_version)
|
||||
|
||||
if args.version:
|
||||
print_toxygen_version()
|
||||
return
|
||||
elif arg == '--help':
|
||||
print('Usage:\ntoxygen path_to_profile\ntoxygen tox_id\ntoxygen --version\ntoxygen --reset')
|
||||
return
|
||||
elif arg == '--clean':
|
||||
|
||||
if args.clean:
|
||||
clean()
|
||||
return
|
||||
elif arg == '--reset':
|
||||
|
||||
if args.reset:
|
||||
reset()
|
||||
return
|
||||
else:
|
||||
toxygen = app.App(arg)
|
||||
|
||||
toxygen = app.App(path_to_profile=args.profile_path)
|
||||
toxygen.main()
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
import urllib.request
|
||||
from util import log
|
||||
from util.util import log
|
||||
from user_data import settings
|
||||
from PyQt5 import QtNetwork, QtCore
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import util
|
||||
import util.util as util
|
||||
from contacts import profile
|
||||
import os
|
||||
import importlib
|
||||
|
@ -8,15 +8,15 @@ from user_data import toxes
|
|||
import sys
|
||||
|
||||
|
||||
class PluginLoader(util.Singleton):
|
||||
class PluginLoader():
|
||||
|
||||
def __init__(self, tox, settings):
|
||||
def __init__(self, tox, toxes, profile, settings):
|
||||
super().__init__()
|
||||
self._profile = profile.Profile.get_instance()
|
||||
self._profile = profile
|
||||
self._settings = settings
|
||||
self._plugins = {} # dict. key - plugin unique short name, value - tuple (plugin instance, is active)
|
||||
self._tox = tox
|
||||
self._encr = toxes.ToxES.get_instance()
|
||||
self._toxes = toxes
|
||||
|
||||
def set_tox(self, tox):
|
||||
"""
|
||||
|
@ -55,7 +55,7 @@ class PluginLoader(util.Singleton):
|
|||
if inspect.isclass(obj) and hasattr(obj, 'is_plugin') and obj.is_plugin:
|
||||
print('Plugin', elem)
|
||||
try: # create instance of plugin class
|
||||
inst = obj(self._tox, self._profile, self._settings, self._encr)
|
||||
inst = obj(self._tox, self._profile, self._settings, self._toxes)
|
||||
autostart = inst.get_short_name() in self._settings['plugins']
|
||||
if autostart:
|
||||
inst.start()
|
||||
|
@ -158,7 +158,7 @@ class PluginLoader(util.Singleton):
|
|||
try:
|
||||
result.extend(elem[0].get_message_menu(menu, selected_text))
|
||||
except:
|
||||
continue
|
||||
pass
|
||||
return result
|
||||
|
||||
def stop(self):
|
||||
|
|
|
@ -5,7 +5,7 @@ from collections import OrderedDict
|
|||
from PyQt5 import QtCore
|
||||
|
||||
|
||||
class SmileyLoader(util.Singleton):
|
||||
class SmileyLoader:
|
||||
"""
|
||||
Class which loads smileys packs and insert smileys into messages
|
||||
"""
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from PyQt5 import QtCore
|
||||
from communication.callbacks import init_callbacks
|
||||
from bootstrap.bootstrap import *
|
||||
import threading
|
||||
import queue
|
||||
from util import util
|
||||
|
||||
|
||||
|
||||
class InitThread(QtCore.QThread):
|
||||
|
||||
def __init__(self, tox, ms, tray):
|
||||
|
|
|
@ -3,6 +3,19 @@ from util.ui import tr
|
|||
from util.util import curr_directory
|
||||
|
||||
|
||||
class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
|
||||
|
||||
leftClicked = QtCore.pyqtSignal()
|
||||
|
||||
def __init__(self, icon, parent=None):
|
||||
super().__init__(self, icon, parent)
|
||||
self.activated.connect(self.iconActivated)
|
||||
|
||||
def iconActivated(self, reason):
|
||||
if reason == QtGui.QSystemTrayIcon.Trigger:
|
||||
self.leftClicked.emit()
|
||||
|
||||
|
||||
class Menu(QtWidgets.QMenu):
|
||||
|
||||
def __init__(self, settings, profile, *args):
|
||||
|
@ -39,7 +52,7 @@ class Menu(QtWidgets.QMenu):
|
|||
|
||||
|
||||
def init_tray(profile, settings, main_screen):
|
||||
tray = QtWidgets.QSystemTrayIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
|
||||
tray = SystemTrayIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
|
||||
tray.setObjectName('tray')
|
||||
|
||||
m = Menu(settings, profile)
|
||||
|
|
|
@ -5,7 +5,7 @@ import util
|
|||
import pyaudio
|
||||
import wave
|
||||
from user_data import settings
|
||||
from util import curr_directory
|
||||
from util.util import curr_directory
|
||||
|
||||
|
||||
class IncomingCallWidget(widgets.CenteredWidget):
|
||||
|
|
|
@ -2,7 +2,7 @@ from wrapper.toxcore_enums_and_consts import *
|
|||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from contacts import profile
|
||||
from file_transfers.file_transfers import TOX_FILE_TRANSFER_STATE, PAUSED_FILE_TRANSFERS, DO_NOT_SHOW_ACCEPT_BUTTON, ACTIVE_FILE_TRANSFERS, SHOW_PROGRESS_BAR
|
||||
from util import curr_directory, convert_time, curr_time
|
||||
from util.util import curr_directory, convert_time, curr_time
|
||||
from ui.widgets import DataLabel, create_menu
|
||||
import html as h
|
||||
import smileys
|
||||
|
@ -60,8 +60,8 @@ class MessageEdit(QtWidgets.QTextBrowser):
|
|||
def quote_text(self):
|
||||
text = self.textCursor().selection().toPlainText()
|
||||
if text:
|
||||
from ui import mainscreen
|
||||
window = mainscreen.MainWindow.get_instance()
|
||||
from ui import main_screen
|
||||
window = main_screen.MainWindow.get_instance()
|
||||
text = '>' + '\n>'.join(text.split('\n'))
|
||||
if window.messageEdit.toPlainText():
|
||||
text = '\n' + text
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from ui.widgets import *
|
||||
import os.path
|
||||
|
||||
|
||||
class NickEdit(LineEdit):
|
||||
|
@ -14,12 +15,40 @@ class NickEdit(LineEdit):
|
|||
super(NickEdit, self).keyPressEvent(event)
|
||||
|
||||
|
||||
class LoginScreen(CenteredWidget):
|
||||
class LoginScreenResult:
|
||||
|
||||
def __init__(self, profile_path, load_as_default, password=None):
|
||||
self._profile_path = profile_path
|
||||
self._load_as_default = load_as_default
|
||||
self._password = password
|
||||
|
||||
def get_profile_path(self):
|
||||
return self._profile_path
|
||||
|
||||
profile_path = property(get_profile_path)
|
||||
|
||||
def get_load_as_default(self):
|
||||
return self._load_as_default
|
||||
|
||||
load_as_default = property(get_load_as_default)
|
||||
|
||||
def get_password(self):
|
||||
return self._password
|
||||
|
||||
password = property(get_password)
|
||||
|
||||
def is_new_profile(self):
|
||||
return not os.path.isfile(self._profile_path)
|
||||
|
||||
|
||||
class LoginScreen(CenteredWidget, DialogWithResult):
|
||||
|
||||
def __init__(self):
|
||||
super(LoginScreen, self).__init__()
|
||||
CenteredWidget.__init__(self)
|
||||
DialogWithResult.__init__(self)
|
||||
self.initUI()
|
||||
self.center()
|
||||
self._profiles = []
|
||||
|
||||
def initUI(self):
|
||||
self.resize(400, 200)
|
||||
|
@ -34,7 +63,7 @@ class LoginScreen(CenteredWidget):
|
|||
self.new_name.setGeometry(QtCore.QRect(20, 100, 171, 31))
|
||||
self.load_profile = QtWidgets.QPushButton(self)
|
||||
self.load_profile.setGeometry(QtCore.QRect(220, 150, 161, 27))
|
||||
self.load_profile.clicked.connect(self.load_ex_profile)
|
||||
self.load_profile.clicked.connect(self.load_existing_profile)
|
||||
self.default = QtWidgets.QCheckBox(self)
|
||||
self.default.setGeometry(QtCore.QRect(220, 110, 131, 22))
|
||||
self.groupBox = QtWidgets.QGroupBox(self)
|
||||
|
@ -44,6 +73,7 @@ class LoginScreen(CenteredWidget):
|
|||
self.groupBox_2 = QtWidgets.QGroupBox(self)
|
||||
self.groupBox_2.setGeometry(QtCore.QRect(10, 40, 191, 151))
|
||||
self.toxygen = QtWidgets.QLabel(self)
|
||||
self.toxygen.setGeometry(QtCore.QRect(160, 8, 90, 25))
|
||||
self.groupBox.raise_()
|
||||
self.groupBox_2.raise_()
|
||||
self.comboBox.raise_()
|
||||
|
@ -51,16 +81,11 @@ class LoginScreen(CenteredWidget):
|
|||
self.load_profile.raise_()
|
||||
self.new_name.raise_()
|
||||
self.new_profile.raise_()
|
||||
self.toxygen.setGeometry(QtCore.QRect(160, 8, 90, 25))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Impact")
|
||||
font.setPointSize(16)
|
||||
self.toxygen.setFont(font)
|
||||
self.toxygen.setObjectName("toxygen")
|
||||
self.type = 0
|
||||
self.number = -1
|
||||
self.load_as_default = False
|
||||
self.name = None
|
||||
self.retranslateUi()
|
||||
QtCore.QMetaObject.connectSlotsByName(self)
|
||||
|
||||
|
@ -80,19 +105,18 @@ class LoginScreen(CenteredWidget):
|
|||
self.name = self.new_name.text()
|
||||
self.close()
|
||||
|
||||
def load_ex_profile(self):
|
||||
if not self.create_only:
|
||||
self.type = 2
|
||||
self.number = self.comboBox.currentIndex()
|
||||
self.load_as_default = self.default.isChecked()
|
||||
self.close()
|
||||
def load_existing_profile(self):
|
||||
index = self.comboBox.currentIndex()
|
||||
load_as_default = self.default.isChecked()
|
||||
path = os.path.join(self._profiles[index][0], self._profiles[index][1] + '.tox')
|
||||
result = LoginScreenResult(path, load_as_default)
|
||||
self.close_with_result(result)
|
||||
|
||||
def update_select(self, data):
|
||||
list_of_profiles = []
|
||||
for elem in data:
|
||||
list_of_profiles.append(elem)
|
||||
self.comboBox.addItems(list_of_profiles)
|
||||
self.create_only = not list_of_profiles
|
||||
def update_select(self, profiles):
|
||||
profiles = sorted(profiles, key=lambda p: p[1])
|
||||
self._profiles = list(profiles)
|
||||
self.comboBox.addItems(list(map(lambda p: p[1], profiles)))
|
||||
self.load_profile.setEnabled(len(profiles) > 0)
|
||||
|
||||
def update_on_close(self, func):
|
||||
self.onclose = func
|
|
@ -3,7 +3,7 @@ from contacts.profile import *
|
|||
from ui.list_items import *
|
||||
from ui.widgets import MultilineEdit, ComboBox
|
||||
import plugin_support
|
||||
from ui.mainscreen_widgets import *
|
||||
from ui.main_screen_widgets import *
|
||||
from user_data import toxes, settings
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from ui.widgets import CenteredWidget, LineEdit
|
||||
from ui.widgets import CenteredWidget, LineEdit, DialogWithResult
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
|
||||
|
@ -16,10 +16,11 @@ class PasswordArea(LineEdit):
|
|||
super(PasswordArea, self).keyPressEvent(event)
|
||||
|
||||
|
||||
class PasswordScreenBase(CenteredWidget):
|
||||
class PasswordScreenBase(CenteredWidget, DialogWithResult):
|
||||
|
||||
def __init__(self, encrypt):
|
||||
super(PasswordScreenBase, self).__init__()
|
||||
CenteredWidget.__init__(self)
|
||||
DialogWithResult.__init__(self)
|
||||
self._encrypt = encrypt
|
||||
self.initUI()
|
||||
|
||||
|
@ -73,13 +74,12 @@ class PasswordScreen(PasswordScreenBase):
|
|||
if self.password.text():
|
||||
try:
|
||||
self._encrypt.set_password(self.password.text())
|
||||
new_data = self._encrypt.pass_decrypt(self._data[0])
|
||||
new_data = self._encrypt.pass_decrypt(self._data)
|
||||
except Exception as ex:
|
||||
self.warning.setVisible(True)
|
||||
print('Decryption error:', ex)
|
||||
else:
|
||||
self._data[0] = new_data
|
||||
self.close()
|
||||
self.close_with_result(new_data)
|
||||
|
||||
|
||||
class UnlockAppScreen(PasswordScreenBase):
|
|
@ -32,6 +32,22 @@ class CenteredWidget(QtWidgets.QWidget):
|
|||
self.move(qr.topLeft())
|
||||
|
||||
|
||||
class DialogWithResult(QtWidgets.QWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._result = None
|
||||
|
||||
def get_result(self):
|
||||
return self._result
|
||||
|
||||
result = property(get_result)
|
||||
|
||||
def close_with_result(self, result):
|
||||
self._result = result
|
||||
self.close()
|
||||
|
||||
|
||||
class LineEdit(QtWidgets.QLineEdit):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
import util.util as util
|
||||
import os
|
||||
from user_data.settings import Settings
|
||||
|
||||
|
||||
class ProfileManager:
|
||||
"""
|
||||
Class with methods for search, load and save profiles
|
||||
"""
|
||||
def __init__(self, path, name):
|
||||
path = append_slash(path)
|
||||
self._path = path + name + '.tox'
|
||||
self._directory = path
|
||||
def __init__(self, settings, toxes, path):
|
||||
self._settings = settings
|
||||
self._toxes = toxes
|
||||
self._path = path
|
||||
self._directory = os.path.basename(path)
|
||||
# create /avatars if not exists:
|
||||
directory = path + 'avatars'
|
||||
if not os.path.exists(directory):
|
||||
|
@ -23,9 +29,8 @@ class ProfileManager:
|
|||
return self._directory
|
||||
|
||||
def save_profile(self, data):
|
||||
inst = ToxES.get_instance()
|
||||
if inst.has_password():
|
||||
data = inst.pass_encrypt(data)
|
||||
if self._toxes.has_password():
|
||||
data = self._toxes.pass_encrypt(data)
|
||||
with open(self._path, 'wb') as fl:
|
||||
fl.write(data)
|
||||
print('Profile saved successfully')
|
||||
|
@ -37,11 +42,11 @@ class ProfileManager:
|
|||
with open(path, 'wb') as fout:
|
||||
fout.write(data)
|
||||
print('Profile exported successfully')
|
||||
copy(self._directory + 'avatars', new_path + 'avatars')
|
||||
util.copy(self._directory + 'avatars', new_path + 'avatars')
|
||||
if use_new_path:
|
||||
self._path = new_path + os.path.basename(self._path)
|
||||
self._directory = new_path
|
||||
Settings.get_instance().update_path()
|
||||
self._settings.update_path()
|
||||
|
||||
@staticmethod
|
||||
def find_profiles():
|
||||
|
@ -57,7 +62,7 @@ class ProfileManager:
|
|||
if fl.endswith('.tox'):
|
||||
name = fl[:-4]
|
||||
result.append((path, name))
|
||||
path = curr_directory()
|
||||
path = util.get_base_directory(__file__)
|
||||
# check current directory
|
||||
for fl in os.listdir(path):
|
||||
if fl.endswith('.tox'):
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
from platform import system
|
||||
import json
|
||||
import os
|
||||
from util import Singleton, curr_directory, log, copy, append_slash
|
||||
from util.util import log, curr_directory, append_slash
|
||||
import pyaudio
|
||||
from user_data.toxes import ToxES
|
||||
import smileys
|
||||
import smileys_and_stickers as smileys
|
||||
|
||||
|
||||
class Settings(dict, Singleton):
|
||||
class Settings(dict):
|
||||
"""
|
||||
Settings of current profile + global app settings
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
Singleton.__init__(self)
|
||||
self.path = ProfileManager.get_path() + str(name) + '.json'
|
||||
self.name = name
|
||||
if os.path.isfile(self.path):
|
||||
with open(self.path, 'rb') as fl:
|
||||
def __init__(self, toxes, path):
|
||||
self._path = path
|
||||
self._toxes = toxes
|
||||
if os.path.isfile(path):
|
||||
with open(path, 'rb') as fl:
|
||||
data = fl.read()
|
||||
inst = ToxES.get_instance()
|
||||
try:
|
||||
if inst.is_data_encrypted(data):
|
||||
data = inst.pass_decrypt(data)
|
||||
if toxes.is_data_encrypted(data):
|
||||
data = toxes.pass_decrypt(data)
|
||||
info = json.loads(str(data, 'utf-8'))
|
||||
except Exception as ex:
|
||||
info = Settings.get_default_settings()
|
||||
|
@ -175,12 +173,11 @@ class Settings(dict, Singleton):
|
|||
|
||||
def save(self):
|
||||
text = json.dumps(self)
|
||||
inst = ToxES.get_instance()
|
||||
if inst.has_password():
|
||||
text = bytes(inst.pass_encrypt(bytes(text, 'utf-8')))
|
||||
if self._toxes.has_password():
|
||||
text = bytes(self._toxes.pass_encrypt(bytes(text, 'utf-8')))
|
||||
else:
|
||||
text = bytes(text, 'utf-8')
|
||||
with open(self.path, 'wb') as fl:
|
||||
with open(self._path, 'wb') as fl:
|
||||
fl.write(text)
|
||||
|
||||
def close(self):
|
||||
|
|
|
@ -3,9 +3,7 @@ import time
|
|||
import shutil
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
program_version = '0.5.0'
|
||||
import platform
|
||||
|
||||
|
||||
def cached(func):
|
||||
|
@ -33,6 +31,18 @@ def curr_directory(current_file=None):
|
|||
return os.path.dirname(os.path.realpath(current_file or __file__))
|
||||
|
||||
|
||||
def get_base_directory(current_file=None):
|
||||
return os.path.dirname(curr_directory())
|
||||
|
||||
|
||||
def get_images_directory():
|
||||
return os.path.join(get_base_directory(), 'images')
|
||||
|
||||
|
||||
def get_styles_directory():
|
||||
return os.path.join(get_base_directory(), 'styles')
|
||||
|
||||
|
||||
def curr_time():
|
||||
return time.strftime('%H:%M')
|
||||
|
||||
|
@ -95,12 +105,5 @@ def is_re_valid(regex):
|
|||
return True
|
||||
|
||||
|
||||
class Singleton:
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
self.__class__._instance = self
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls):
|
||||
return cls._instance
|
||||
def get_platform():
|
||||
return platform.system()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from platform import system
|
||||
from ctypes import CDLL
|
||||
import util
|
||||
import util.util as util
|
||||
|
||||
|
||||
class LibToxCore:
|
||||
|
|
Loading…
Reference in a new issue