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