refactoring - app.py, files moved to different folders

This commit is contained in:
ingvar1995 2018-04-17 15:14:05 +03:00
parent 91d3f885c0
commit 8a2665ed4d
26 changed files with 287 additions and 302 deletions

View File

@ -2,11 +2,11 @@ from setuptools import setup
from setuptools.command.install import install from setuptools.command.install import install
from platform import system from platform import system
from subprocess import call from subprocess import call
from toxygen.util import program_version import main
import sys import sys
version = program_version + '.0' version = main.__version__ + '.0'
if system() == 'Windows': if system() == 'Windows':

View File

@ -8,6 +8,8 @@ import toxygen.util as util
import time import time
# TODO: fic
class TestTox: class TestTox:
def test_creation(self): def test_creation(self):

View File

@ -1,11 +1,10 @@
import communication.callbacks from middleware import threads
import threads
from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5 import QtWidgets, QtGui, QtCore
import ui.password_screen as passwordscreen import ui.password_screen as passwordscreen
from util.util import * from util.util import *
import updater.updater as updater import updater.updater as updater
import os import os
from communication.tox_factory import tox_factory from middleware.tox_factory import tox_factory
import wrapper.toxencryptsave as tox_encrypt_save import wrapper.toxencryptsave as tox_encrypt_save
import user_data.toxes import user_data.toxes
from user_data.settings import Settings from user_data.settings import Settings
@ -13,6 +12,8 @@ from ui.login_screen import LoginScreen
from user_data.profile_manager import ProfileManager from user_data.profile_manager import ProfileManager
from plugin_support.plugin_support import PluginLoader from plugin_support.plugin_support import PluginLoader
from ui.main_screen import MainWindow from ui.main_screen import MainWindow
from ui import tray
import util.ui as util_ui
class App: class App:
@ -20,21 +21,20 @@ class App:
def __init__(self, version, path_to_profile=None, uri=None): def __init__(self, version, path_to_profile=None, uri=None):
self._version = version self._version = version
self._app = None self._app = 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._main_loop = self._av_loop = None
self.uri = self.path = self.toxes = None self.uri = self._toxes = self._tray = None
if uri is not None and uri.startswith('tox:'): if uri is not None and uri.startswith('tox:'):
self.uri = uri[4:] self.uri = uri[4:]
if path_to_profile is not None: self._path = path_to_profile
self.path = path_to_profile
def enter_pass(self, data): def enter_pass(self, data):
""" """
Show password screen Show password screen
""" """
p = passwordscreen.PasswordScreen(self.toxes, data) p = passwordscreen.PasswordScreen(self._toxes, data)
p.show() p.show()
self.app.lastWindowClosed.connect(self.app.quit) self._app.lastWindowClosed.connect(self._app.quit)
self.app.exec_() self._app.exec_()
result = p.result result = p.result
if result is None: if result is None:
raise SystemExit() raise SystemExit()
@ -45,30 +45,29 @@ class App:
""" """
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([]) self._app= QtWidgets.QApplication([])
icon_file = os.path.join(get_images_directory(), 'icon.png') icon_file = os.path.join(get_images_directory(), 'icon.png')
app.setWindowIcon(QtGui.QIcon(icon_file)) self._app.setWindowIcon(QtGui.QIcon(icon_file))
self._app = app
if get_platform() == 'Linux': if get_platform() == 'Linux':
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads) QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
with open(os.path.join(get_styles_directory(), '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) self._app.setStyleSheet(style)
encrypt_save = tox_encrypt_save.ToxEncryptSave() encrypt_save = tox_encrypt_save.ToxEncryptSave()
self._toxes = user_data.toxes.ToxES(encrypt_save) self._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) + '/'
name = os.path.basename(self.path)[:-4] name = os.path.basename(self._path)[:-4]
self._settings = Settings(self._toxes, self.path.replace('.tox', '.json')) self._settings = Settings(self._toxes, self._path.replace('.tox', '.json'))
self._profile_manager = ProfileManager(self._settings, self._toxes, path) self._profile_manager = ProfileManager(self._settings, self._toxes, path)
data = self._profile_manager.open_profile() data = self._profile_manager.open_profile()
if encrypt_save.is_data_encrypted(data): if encrypt_save.is_data_encrypted(data):
data = self.enter_pass(data) data = self.enter_pass(data)
self.tox = tox_factory(data, self._settings) self._tox = self.create_tox(data)
else: else:
auto_profile = Settings.get_auto_profile() auto_profile = Settings.get_auto_profile()
if not auto_profile[0]: if not auto_profile[0]:
@ -79,15 +78,15 @@ class App:
if curr_lang in langs: if curr_lang in langs:
lang_path = langs[curr_lang] lang_path = langs[curr_lang]
translator = QtCore.QTranslator() translator = QtCore.QTranslator()
translator.load(curr_directory() + '/translations/' + lang_path) translator.load(get_translations_directory() + lang_path)
app.installTranslator(translator) self._app.installTranslator(translator)
app.translator = translator self._app.translator = translator
ls = LoginScreen() ls = LoginScreen()
ls.setWindowIconText("Toxygen") ls.setWindowIconText("Toxygen")
profiles = ProfileManager.find_profiles() profiles = ProfileManager.find_profiles()
ls.update_select(profiles) ls.update_select(profiles)
ls.show() ls.show()
app.exec_() self._app.exec_()
result = ls.result result = ls.result
if result is None: if result is None:
return return
@ -95,47 +94,22 @@ class App:
name = get_profile_name_from_path(result.profile_path) or 'toxygen_user' name = get_profile_name_from_path(result.profile_path) or '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):
msgBox = QtWidgets.QMessageBox() util_ui.message_box(util_ui.tr('Profile with this name already exists'),
msgBox.setWindowTitle( util_ui.tr('Error'))
QtWidgets.QApplication.translate("MainWindow", "Error"))
text = (QtWidgets.QApplication.translate("MainWindow",
'Profile with this name already exists'))
msgBox.setText(text)
msgBox.exec_()
return return
self.tox = tox_factory() self._tox = tox_factory()
self.tox.self_set_name(bytes(name, 'utf-8') if name else b'Toxygen User') self._tox.self_set_name(bytes(name, 'utf-8') if name else b'Toxygen User')
self.tox.self_set_status_message(b'Toxing on Toxygen') self._tox.self_set_status_message(b'Toxing on Toxygen')
reply = QtWidgets.QMessageBox.question(None, # TODO: set profile password
'Profile {}'.format(name), path = result.profile_path
QtWidgets.QApplication.translate("login", self._profile_manager = ProfileManager(self._toxes, path)
'Do you want to set profile password?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
set_pass = SetProfilePasswordScreen(encrypt_save)
set_pass.show()
self.app.lastWindowClosed.connect(self.app.quit)
self.app.exec_()
reply = QtWidgets.QMessageBox.question(None,
'Profile {}'.format(name),
QtWidgets.QApplication.translate("login",
'Do you want to save profile in default folder? If no, profile will be saved in program folder'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
path = Settings.get_default_path()
else:
path = curr_directory() + '/'
try: try:
ProfileManager(path, name).save_profile(self.tox.get_savedata()) self._profile_manager.save_profile(self._tox.get_savedata())
except Exception as ex: except Exception as ex:
print(str(ex)) print(str(ex))
log('Profile creation exception: ' + str(ex)) log('Profile creation exception: ' + str(ex))
msgBox = QtWidgets.QMessageBox() text = util_ui.tr('Profile saving error! Does Toxygen have permission to write to this directory?')
msgBox.setText(QtWidgets.QApplication.translate("login", util_ui.message_box(text, util_ui.tr('Error'))
'Profile saving error! Does Toxygen have permission to write to this directory?'))
msgBox.exec_()
return return
path = Settings.get_default_path() path = Settings.get_default_path()
self._settings = Settings() self._settings = Settings()
@ -151,7 +125,7 @@ class App:
data = self._profile_manager.open_profile() data = self._profile_manager.open_profile()
if self._toxes.is_data_encrypted(data): if self._toxes.is_data_encrypted(data):
data = self.enter_pass(data) data = self.enter_pass(data)
self._tox = tox_factory(data, self._settings) self._tox = self.create_tox(data)
else: else:
path, name = auto_profile path, name = auto_profile
self._settings = Settings(self._toxes, path + name + '.json') self._settings = Settings(self._toxes, path + name + '.json')
@ -159,15 +133,13 @@ class App:
data = self._profile_manager.open_profile() data = self._profile_manager.open_profile()
if encrypt_save.is_data_encrypted(data): if encrypt_save.is_data_encrypted(data):
data = self.enter_pass(data) data = self.enter_pass(data)
self.tox = tox_factory(data, self._settings) self.tox = self.create_tox(data)
if Settings.is_active_profile(path, get_profile_name_from_path(path)): # profile is in use if Settings.is_active_profile(path, get_profile_name_from_path(path)): # profile is in use
reply = QtWidgets.QMessageBox.question(None, title = util_ui.tr('Profile {}').format(name)
'Profile {}'.format(name), text = util_ui.tr('Other instance of Toxygen uses this profile or profile was not properly closed. Continue?')
QtWidgets.QApplication.translate("login", 'Other instance of Toxygen uses this profile or profile was not properly closed. Continue?'), reply = util_ui.question(text, title)
QtWidgets.QMessageBox.Yes, if not reply:
QtWidgets.QMessageBox.No)
if reply != QtWidgets.QMessageBox.Yes:
return return
else: else:
self._settings.set_active_profile() self._settings.set_active_profile()
@ -175,82 +147,49 @@ class App:
self.load_app_styles() self.load_app_styles()
self.load_app_translations() self.load_app_translations()
# tray icon if self.try_to_update():
self.ms = MainWindow(self._settings, self._tox, self.reset, self.tray)
self._profile = self.ms.profile
self.ms.show()
updating = updater.start_update_if_needed(self._version, self._settings)
if updating:
data = self.tox.get_savedata()
self._profile_manager.save_profile(data)
self._settings.close()
del self.tox
return return
plugin_helper = PluginLoader(self._tox, self._toxes, self._profile, self._settings) # plugin support self._ms = MainWindow(self._settings, self._tox, self.reset, self._tray)
plugin_helper.load() self._profile = self._ms.profile
self._ms.show()
# init thread self._tray = tray.init_tray(self._profile, self._settings, self._ms)
self.init = threads.InitThread(self.tox, self.ms, self.tray) self._tray.show()
self.init.start()
# starting threads for tox iterate and toxav iterate self._plugin_loader = PluginLoader(self._tox, self._toxes, self._profile, self._settings) # plugins support
self.mainloop = threads.ToxIterateThread(self._tox) self._plugin_loader.load() # TODO; move to separate thread?
self.mainloop.start()
self.avloop = threads.ToxAVIterateThread(self._tox.AV)
self.avloop.start()
if self.uri is not None: if self.uri is not None:
self.ms.add_contact(self.uri) self._ms.add_contact(self.uri)
app.lastWindowClosed.connect(app.quit) self._app.lastWindowClosed.connect(self._app.quit)
app.exec_() self._app.exec_()
self.init.stop = True self._plugin_loader.stop()
self.mainloop.stop = True self.stop_threads()
self.avloop.stop = True self._tray.hide()
plugin_helper.stop() data = self._tox.get_savedata()
self.mainloop.wait()
self.init.wait()
self.avloop.wait()
self.tray.hide()
data = self.tox.get_savedata()
self._profile_manager.save_profile(data) self._profile_manager.save_profile(data)
self._settings.close() self._settings.close()
del self.tox del self._tox
def reset(self): def reset(self):
""" """
Create new tox instance (new network settings) Create new tox instance (new network settings)
:return: tox instance :return: tox instance
""" """
self.mainloop.stop = True self.stop_threads()
self.init.stop = True data = self._tox.get_savedata()
self.avloop.stop = True
self.mainloop.wait()
self.init.wait()
self.avloop.wait()
data = self.tox.get_savedata()
self._profile_manager.save_profile(data) self._profile_manager.save_profile(data)
del self.tox del self._tox
# create new tox instance # create new tox instance
self.tox = tox_factory(data, self._settings) self._tox = tox_factory(data, self._settings)
# init thread self.start_threads()
self.init = threads.InitThread(self.tox, self.ms, self.tray)
self.init.start()
# starting threads for tox iterate and toxav iterate self._plugin_loader.set_tox(self._tox)
self.mainloop = threads.ToxIterateThread(self.tox)
self.mainloop.start()
self.avloop = threads.ToxAVIterateThread(self.tox.AV) return self._tox
self.avloop.start()
self._plugin_loader.set_tox(self.tox)
return self.tox
def load_app_styles(self): def load_app_styles(self):
# application color scheme # application color scheme
@ -266,3 +205,32 @@ class App:
translator.load(curr_directory(__file__) + '/translations/' + lang) translator.load(curr_directory(__file__) + '/translations/' + lang)
self._app.installTranslator(translator) self._app.installTranslator(translator)
self._app.translator = translator self._app.translator = translator
def try_to_update(self):
updating = updater.start_update_if_needed(self._version, self._settings)
if updating:
data = self._tox.get_savedata()
self._profile_manager.save_profile(data)
self._settings.close()
del self._tox
return updating
def start_threads(self):
# init thread
self._init = threads.InitThread(self._tox, self._ms, self._tray)
self._init.start()
# starting threads for tox iterate and toxav iterate
self._main_loop = threads.ToxIterateThread(self._tox)
self._main_loop.start()
self._av_loop = threads.ToxAVIterateThread(self._tox.AV)
self._av_loop.start()
def stop_threads(self):
self._init.stop_thread()
self._main_loop.stop_thread()
self._av_loop.stop_thread()
def create_tox(self, data):
return tox_factory(data, self._settings)

View File

@ -11,7 +11,7 @@ import time
from av import calls from av import calls
import plugin_support import plugin_support
from contacts import basecontact from contacts import basecontact
from ui import items_factory, avwidgets from ui import items_factory, av_widgets
import cv2 import cv2
import threading import threading
from contacts.group_chat import * from contacts.group_chat import *

View File

@ -1,19 +0,0 @@
class Login:
def __init__(self, arr):
self.arr = arr
def login_screen_close(self, t, number=-1, default=False, name=None):
""" Function which processes data from login screen
:param t: 0 - window was closed, 1 - new profile was created, 2 - profile loaded
:param number: num of chosen profile in list (-1 by default)
:param default: was or not chosen profile marked as default
:param name: name of new profile
"""
self.t = t
self.num = number
self.default = default
self.name = name
def get_data(self):
return self.arr[self.num]

View File

@ -4,6 +4,7 @@ from user_data.settings import *
from util.util import curr_directory, remove from util.util import curr_directory, remove
import argparse import argparse
__maintainer__ = 'Ingvar' __maintainer__ = 'Ingvar'
__version__ = '0.5.0' __version__ = '0.5.0'

View File

@ -1,5 +1,4 @@
from PyQt5 import QtGui from PyQt5 import QtGui
from notifications import *
from user_data.settings import Settings from user_data.settings import Settings
from contacts.profile import Profile from contacts.profile import Profile
from wrapper.toxcore_enums_and_consts import * from wrapper.toxcore_enums_and_consts import *
@ -8,7 +7,7 @@ from wrapper.tox import bin_to_string
from plugin_support.plugin_support import PluginLoader from plugin_support.plugin_support import PluginLoader
import cv2 import cv2
import numpy as np import numpy as np
from threads import invoke_in_main_thread, execute from middleware.threads import invoke_in_main_thread, execute
# TODO: use closures # TODO: use closures

View File

@ -1,17 +1,26 @@
from PyQt5 import QtCore
from bootstrap.bootstrap import * from bootstrap.bootstrap import *
import threading import threading
import queue import queue
from util import util from util import util
import time
class BaseThread(threading.Thread):
class InitThread(QtCore.QThread): def __init__(self):
super().__init__()
self._stop = False
def stop_thread(self):
self._stop = True
self.join()
class InitThread(BaseThread):
def __init__(self, tox, ms, tray): def __init__(self, tox, ms, tray):
QtCore.QThread.__init__(self) super().__init__()
self.tox, self.ms, self.tray = tox, ms, tray self.tox, self.ms, self.tray = tox, ms, tray
self.stop = False
def run(self): def run(self):
# initializing callbacks # initializing callbacks
@ -21,71 +30,65 @@ class InitThread(QtCore.QThread):
# bootstrap # bootstrap
try: try:
for data in generate_nodes(): for data in generate_nodes():
if self.stop: if self._stop:
return return
self.tox.bootstrap(*data) self.tox.bootstrap(*data)
self.tox.add_tcp_relay(*data) self.tox.add_tcp_relay(*data)
except: except:
pass pass
for _ in range(10): for _ in range(10):
if self.stop: if self._stop:
return return
self.msleep(1000) time.sleep(1)
while not self.tox.self_get_connection_status(): while not self.tox.self_get_connection_status():
try: try:
for data in generate_nodes(): for data in generate_nodes():
if self.stop: if self._stop:
return return
self.tox.bootstrap(*data) self.tox.bootstrap(*data)
self.tox.add_tcp_relay(*data) self.tox.add_tcp_relay(*data)
except: except:
pass pass
finally: finally:
self.msleep(5000) time.sleep(5)
class ToxIterateThread(QtCore.QThread): class ToxIterateThread(BaseThread):
def __init__(self, tox): def __init__(self, tox):
QtCore.QThread.__init__(self) super().__init__()
self.tox = tox self._tox = tox
self.stop = False
def run(self): def run(self):
while not self.stop: while not self._stop:
self.tox.iterate() self._tox.iterate()
self.msleep(self.tox.iteration_interval()) time.sleep(self._tox.iteration_interval() / 1000)
class ToxAVIterateThread(QtCore.QThread): class ToxAVIterateThread(BaseThread):
def __init__(self, toxav): def __init__(self, toxav):
QtCore.QThread.__init__(self) super().__init__()
self.toxav = toxav self._toxav = toxav
self.stop = False
def run(self): def run(self):
while not self.stop: while not self._stop:
self.toxav.iterate() self._toxav.iterate()
self.msleep(self.toxav.iteration_interval()) time.sleep(self._toxav.iteration_interval() / 1000)
class FileTransfersThread(threading.Thread): class FileTransfersThread(BaseThread):
def __init__(self): def __init__(self):
super().__init__()
self._queue = queue.Queue() self._queue = queue.Queue()
self._timeout = 0.01 self._timeout = 0.01
self._continue = True
super().__init__()
def execute(self, func, *args, **kwargs): def execute(self, func, *args, **kwargs):
self._queue.put((func, args, kwargs)) self._queue.put((func, args, kwargs))
def stop(self):
self._continue = False
def run(self): def run(self):
while self._continue: while not self._stop:
try: try:
func, args, kwargs = self._queue.get(timeout=self._timeout) func, args, kwargs = self._queue.get(timeout=self._timeout)
func(*args, **kwargs) func(*args, **kwargs)
@ -105,8 +108,7 @@ def start():
def stop(): def stop():
_thread.stop() _thread.stop_thread()
_thread.join()
def execute(func, *args, **kwargs): def execute(func, *args, **kwargs):

View File

@ -1,71 +0,0 @@
from PyQt5 import QtCore, QtWidgets
from util.util import curr_directory
import wave
import pyaudio
SOUND_NOTIFICATION = {
'MESSAGE': 0,
'FRIEND_CONNECTION_STATUS': 1,
'FILE_TRANSFER': 2
}
def tray_notification(title, text, tray, window):
"""
Show tray notification and activate window icon
NOTE: different behaviour on different OS
:param title: Name of user who sent message or file
:param text: text of message or file info
:param tray: ref to tray icon
:param window: main window
"""
if QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
if len(text) > 30:
text = text[:27] + '...'
tray.showMessage(title, text, QtWidgets.QSystemTrayIcon.NoIcon, 3000)
QtWidgets.QApplication.alert(window, 0)
def message_clicked():
window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
window.activateWindow()
tray.messageClicked.connect(message_clicked)
class AudioFile:
chunk = 1024
def __init__(self, fl):
self.wf = wave.open(fl, 'rb')
self.p = pyaudio.PyAudio()
self.stream = self.p.open(
format=self.p.get_format_from_width(self.wf.getsampwidth()),
channels=self.wf.getnchannels(),
rate=self.wf.getframerate(),
output=True)
def play(self):
data = self.wf.readframes(self.chunk)
while data:
self.stream.write(data)
data = self.wf.readframes(self.chunk)
def close(self):
self.stream.close()
self.p.terminate()
def sound_notification(t):
"""
Plays sound notification
:param t: type of notification
"""
if t == SOUND_NOTIFICATION['MESSAGE']:
f = curr_directory() + '/sounds/message.wav'
elif t == SOUND_NOTIFICATION['FILE_TRANSFER']:
f = curr_directory() + '/sounds/file.wav'
else:
f = curr_directory() + '/sounds/contact.wav'
a = AudioFile(f)
a.play()
a.close()

View File

View File

@ -0,0 +1,54 @@
import util.util
import wave
import pyaudio
import os.path
SOUND_NOTIFICATION = {
'MESSAGE': 0,
'FRIEND_CONNECTION_STATUS': 1,
'FILE_TRANSFER': 2
}
class AudioFile:
chunk = 1024
def __init__(self, fl):
self.wf = wave.open(fl, 'rb')
self.p = pyaudio.PyAudio()
self.stream = self.p.open(
format=self.p.get_format_from_width(self.wf.getsampwidth()),
channels=self.wf.getnchannels(),
rate=self.wf.getframerate(),
output=True)
def play(self):
data = self.wf.readframes(self.chunk)
while data:
self.stream.write(data)
data = self.wf.readframes(self.chunk)
def close(self):
self.stream.close()
self.p.terminate()
def sound_notification(t):
"""
Plays sound notification
:param t: type of notification
"""
if t == SOUND_NOTIFICATION['MESSAGE']:
f = get_file_path('message.wav')
elif t == SOUND_NOTIFICATION['FILE_TRANSFER']:
f = get_file_path('file.wav')
else:
f = get_file_path('contact.wav')
a = AudioFile(f)
a.play()
a.close()
def get_file_path(file_name):
return os.path.join(util.util.get_sounds_directory(), file_name)

View File

@ -0,0 +1,22 @@
from PyQt5 import QtCore, QtWidgets
def tray_notification(title, text, tray, window):
"""
Show tray notification and activate window icon
NOTE: different behaviour on different OS
:param title: Name of user who sent message or file
:param text: text of message or file info
:param tray: ref to tray icon
:param window: main window
"""
if QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
if len(text) > 30:
text = text[:27] + '...'
tray.showMessage(title, text, QtWidgets.QSystemTrayIcon.NoIcon, 3000)
QtWidgets.QApplication.alert(window, 0)
def message_clicked():
window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
window.activateWindow()
tray.messageClicked.connect(message_clicked)

View File

View File

@ -47,6 +47,7 @@ class SmileyLoader:
def get_smileys_path(self): def get_smileys_path(self):
return util.curr_directory() + '/smileys/' + self._curr_pack + '/' if self._curr_pack is not None else None return util.curr_directory() + '/smileys/' + self._curr_pack + '/' if self._curr_pack is not None else None
@staticmethod
def get_packs_list(self): def get_packs_list(self):
d = util.curr_directory() + '/smileys/' d = util.curr_directory() + '/smileys/'
return [x[1] for x in os.walk(d)][0] return [x[1] for x in os.walk(d)][0]
@ -71,18 +72,3 @@ class SmileyLoader:
if file_name.endswith('.gif'): # animated smiley if file_name.endswith('.gif'): # animated smiley
edit.addAnimation(QtCore.QUrl(file_name), self.get_smileys_path() + file_name) edit.addAnimation(QtCore.QUrl(file_name), self.get_smileys_path() + file_name)
return ' '.join(arr) return ' '.join(arr)
def sticker_loader():
"""
:return list of stickers
"""
result = []
d = util.curr_directory() + '/stickers/'
keys = [x[1] for x in os.walk(d)][0]
for key in keys:
path = d + key + '/'
files = filter(lambda f: f.endswith('.png'), os.listdir(path))
files = map(lambda f: str(path + f), files)
result.extend(files)
return result

View File

View File

@ -0,0 +1,18 @@
import os
import util.util as util
def load_stickers():
"""
:return list of stickers
"""
result = []
d = util.get_stickers_directory()
keys = [x[1] for x in os.walk(d)][0]
for key in keys:
path = d + key + '/'
files = filter(lambda f: f.endswith('.png'), os.listdir(path))
files = map(lambda f: str(path + f), files)
result.extend(files)
return result

View File

@ -6,6 +6,7 @@ import plugin_support
from ui.main_screen_widgets import * from ui.main_screen_widgets import *
from user_data import toxes, settings from user_data import toxes, settings
import util.util as util import util.util as util
import util.ui as util_ui
class MainWindow(QtWidgets.QMainWindow): class MainWindow(QtWidgets.QMainWindow):
@ -414,12 +415,10 @@ class MainWindow(QtWidgets.QMainWindow):
# ----------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------------------------
def about_program(self): def about_program(self):
import util text = util_ui.tr('Toxygen is Tox client written on Python.\nVersion: ')
msgBox = QtWidgets.QMessageBox() text += '' + '\nGitHub: https://github.com/toxygen-project/toxygen/'
msgBox.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "About")) title = util_ui.tr('About')
text = (QtWidgets.QApplication.translate("MainWindow", 'Toxygen is Tox client written on Python.\nVersion: ')) util_ui.message_box(text, title)
msgBox.setText(text + util.program_version + '\nGitHub: https://github.com/toxygen-project/toxygen/')
msgBox.exec_()
def network_settings(self): def network_settings(self):
self.n_s = NetworkSettings(self.reset) self.n_s = NetworkSettings(self.reset)

View File

@ -2,7 +2,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from ui.widgets import RubberBandWindow, create_menu, QRightClickButton, CenteredWidget, LineEdit from ui.widgets import RubberBandWindow, create_menu, QRightClickButton, CenteredWidget, LineEdit
from contacts.profile import Profile from contacts.profile import Profile
import smileys import smileys
import util import util.util as util
class MessageArea(QtWidgets.QPlainTextEdit): class MessageArea(QtWidgets.QPlainTextEdit):
@ -194,7 +194,7 @@ class DropdownMenu(QtWidgets.QWidget):
self.stickerButton = QtWidgets.QPushButton(self) self.stickerButton = QtWidgets.QPushButton(self)
self.stickerButton.setGeometry(QtCore.QRect(60, 0, 60, 60)) self.stickerButton.setGeometry(QtCore.QRect(60, 0, 60, 60))
pixmap = QtGui.QPixmap(util.curr_directory() + '/images/file.png') pixmap = QtGui.QPixmap(util.get_images_directory() + 'file.png')
icon = QtGui.QIcon(pixmap) icon = QtGui.QIcon(pixmap)
self.fileTransferButton.setIcon(icon) self.fileTransferButton.setIcon(icon)
self.fileTransferButton.setIconSize(QtCore.QSize(50, 50)) self.fileTransferButton.setIconSize(QtCore.QSize(50, 50))

View File

@ -1,6 +1,7 @@
from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5 import QtWidgets, QtGui, QtCore
from util.ui import tr from util.ui import tr
from util.util import curr_directory from util.util import get_images_directory
import os.path
class SystemTrayIcon(QtWidgets.QSystemTrayIcon): class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
@ -8,11 +9,11 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
leftClicked = QtCore.pyqtSignal() leftClicked = QtCore.pyqtSignal()
def __init__(self, icon, parent=None): def __init__(self, icon, parent=None):
super().__init__(self, icon, parent) super().__init__(icon, parent)
self.activated.connect(self.iconActivated) self.activated.connect(self.icon_activated)
def iconActivated(self, reason): def icon_activated(self, reason):
if reason == QtGui.QSystemTrayIcon.Trigger: if reason == QtWidgets.QSystemTrayIcon.Trigger:
self.leftClicked.emit() self.leftClicked.emit()
@ -52,20 +53,21 @@ class Menu(QtWidgets.QMenu):
def init_tray(profile, settings, main_screen): def init_tray(profile, settings, main_screen):
tray = SystemTrayIcon(QtGui.QIcon(curr_directory() + '/images/icon.png')) icon = os.path.join(get_images_directory(), 'icon.png')
tray = SystemTrayIcon(QtGui.QIcon(icon))
tray.setObjectName('tray') tray.setObjectName('tray')
m = Menu(settings, profile) menu = Menu(settings, profile)
show = m.addAction(tr('Open Toxygen')) show = menu.addAction(tr('Open Toxygen'))
sub = m.addMenu(tr('Set status')) sub = menu.addMenu(tr('Set status'))
online = sub.addAction(tr('Online')) online = sub.addAction(tr('Online'))
away = sub.addAction(tr('Away')) away = sub.addAction(tr('Away'))
busy = sub.addAction(tr('Busy')) busy = sub.addAction(tr('Busy'))
online.setCheckable(True) online.setCheckable(True)
away.setCheckable(True) away.setCheckable(True)
busy.setCheckable(True) busy.setCheckable(True)
m.act = sub menu.act = sub
exit = m.addAction(tr('Exit')) exit = menu.addAction(tr('Exit'))
def show_window(): def show_window():
def show(): def show():
@ -96,12 +98,12 @@ def init_tray(profile, settings, main_screen):
show.triggered.connect(show_window) show.triggered.connect(show_window)
exit.triggered.connect(close_app) exit.triggered.connect(close_app)
m.aboutToShow.connect(lambda: m.aboutToShowHandler()) menu.aboutToShow.connect(lambda: menu.aboutToShowHandler())
online.triggered.connect(lambda: m.newStatus(0)) online.triggered.connect(lambda: menu.newStatus(0))
away.triggered.connect(lambda: m.newStatus(1)) away.triggered.connect(lambda: menu.newStatus(1))
busy.triggered.connect(lambda: m.newStatus(2)) busy.triggered.connect(lambda: menu.newStatus(2))
tray.setContextMenu(m) tray.setContextMenu(menu)
tray.show() tray.show()
tray.activated.connect(tray_activated) tray.activated.connect(tray_activated)

View File

@ -118,14 +118,8 @@ def start_update_if_needed(version, settings):
download(version) download(version)
updating = True updating = True
else: else:
reply = QtWidgets.QMessageBox.question(None, reply = util_ui.question(util_ui.tr('Update for Toxygen was found. Download and install it?'))
'Toxygen', if reply:
QtWidgets.QApplication.translate("login",
'Update for Toxygen was found. Download and install it?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
download(version) download(version)
updating = True updating = True
return updating return updating

View File

@ -4,7 +4,7 @@ import os
from util.util import log, curr_directory, 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_and_stickers as smileys import smileys.smileys as smileys
class Settings(dict): class Settings(dict):

View File

@ -5,10 +5,17 @@ def tr(s):
return PyQt5.QtWidgets.QApplication.translate('Toxygen', s) return PyQt5.QtWidgets.QApplication.translate('Toxygen', s)
def question(text): def question(text, title=None):
reply = PyQt5.QtWidgets.QMessageBox.question(None, 'Toxygen', text, reply = PyQt5.QtWidgets.QMessageBox.question(None, title or 'Toxygen', text,
PyQt5.QtWidgets.QMessageBox.Yes, PyQt5.QtWidgets.QMessageBox.Yes,
PyQt5.QtWidgets.QMessageBox.No) PyQt5.QtWidgets.QMessageBox.No)
return reply == PyQt5.QtWidgets.QMessageBox.Yes return reply == PyQt5.QtWidgets.QMessageBox.Yes
def message_box(text, title=None):
m_box = PyQt5.QtWidgets.QMessageBox()
m_box.setText(tr(text))
m_box.setWindowTitle(title or 'Toxygen')
m_box.exec_()
# TODO: move all dialogs here # TODO: move all dialogs here

View File

@ -35,12 +35,33 @@ def get_base_directory(current_file=None):
return os.path.dirname(curr_directory(current_file or __file__)) return os.path.dirname(curr_directory(current_file or __file__))
@cached
def get_images_directory(): def get_images_directory():
return os.path.join(get_base_directory(), 'images') return get_app_directory('images')
@cached
def get_styles_directory(): def get_styles_directory():
return os.path.join(get_base_directory(), 'styles') return get_app_directory('styles')
@cached
def get_sounds_directory():
return get_app_directory('sounds')
@cached
def get_stickers_directory():
return get_app_directory('stickers')
@cached
def get_translations_directory():
return get_app_directory('translations')
def get_app_directory(directory_name):
return os.path.join(get_base_directory(), directory_name)
def get_profile_name_from_path(path): def get_profile_name_from_path(path):