refactoring - login screen, incorrect refs

This commit is contained in:
ingvar1995 2018-04-16 00:11:51 +03:00
parent 1bead7d55d
commit 85467e1885
21 changed files with 302 additions and 254 deletions

View File

@ -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()
@ -264,4 +272,4 @@ class App:
plugin_helper = PluginLoader.get_instance()
plugin_helper.set_tox(self.tox)
return self.tox
return self.tox

View File

@ -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,55 +224,69 @@ def file_recv_control(file_transfer_handler):
# -----------------------------------------------------------------------------------------------------------------
def lossless_packet(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)
def lossless_packet(plugin_loader):
def wrapped(tox, friend_number, data, length, user_data):
"""
Incoming lossless packet
"""
data = data[:length]
invoke_in_main_thread(plugin_loader.callback_lossless, friend_number, data)
return wrapped
def lossy_packet(tox, friend_number, data, length, user_data):
"""
Incoming lossy packet
"""
data = data[:length]
plugin = PluginLoader.get_instance()
invoke_in_main_thread(plugin.callback_lossy, friend_number, data)
def lossy_packet(plugin_loader):
def wrapped(tox, friend_number, data, length, user_data):
"""
Incoming lossy packet
"""
data = data[:length]
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):
"""
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)
else:
Profile.get_instance().call.toxav_call_state_cb(friend_number, mask)
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(calls_manager.stop_call, friend_number, True)
else:
calls_manager.toxav_call_state_cb(friend_number, mask)
return wrapped
def call(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)
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(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):
"""
New audio chunk
"""
Profile.get_instance().call.audio_chunk(
bytes(samples[:audio_samples_per_channel * 2 * audio_channels_count]),
audio_channels_count,
rate)
def callback_audio(calls_manager):
def wrapped(toxav, friend_number, samples, audio_samples_per_channel, audio_channels_count, rate, user_data):
"""
New 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)

View File

@ -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()

View File

@ -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

View File

@ -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)
return
elif arg == '--help':
print('Usage:\ntoxygen path_to_profile\ntoxygen tox_id\ntoxygen --version\ntoxygen --reset')
return
elif arg == '--clean':
clean()
return
elif arg == '--reset':
reset()
return
else:
toxygen = app.App(arg)
if args.version:
print_toxygen_version()
return
if args.clean:
clean()
return
if args.reset:
reset()
return
toxygen = app.App(path_to_profile=args.profile_path)
toxygen.main()

View File

@ -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

View File

@ -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):

View File

@ -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
"""

View File

@ -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):

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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'):

View File

@ -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):

View File

@ -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()

View File

@ -1,6 +1,6 @@
from platform import system
from ctypes import CDLL
import util
import util.util as util
class LibToxCore: