From 1be8040b45a8180a600cb18db2b60fb4efe4e390 Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Sun, 3 Apr 2016 23:51:46 +0300 Subject: [PATCH] multiprofile. portable mode fixes --- src/file_transfers.py | 4 +- src/history.py | 19 ++++---- src/main.py | 39 +++++++++++---- src/menu.py | 5 +- src/profile.py | 59 +---------------------- src/settings.py | 107 ++++++++++++++++++++++++++++++++++++++++-- tests/tests.py | 1 + 7 files changed, 150 insertions(+), 84 deletions(-) diff --git a/src/file_transfers.py b/src/file_transfers.py index 8e41c21..60a8c31 100644 --- a/src/file_transfers.py +++ b/src/file_transfers.py @@ -3,7 +3,7 @@ from os.path import basename, getsize, exists from os import remove from time import time from tox import Tox -import profile +import settings from PySide import QtCore @@ -163,7 +163,7 @@ class ReceiveAvatar(ReceiveTransfer): MAX_AVATAR_SIZE = 512 * 1024 def __init__(self, tox, friend_number, size, file_number): - path = profile.ProfileHelper.get_path() + '/avatars/{}.png'.format(tox.friend_get_public_key(friend_number)) + path = settings.ProfileHelper.get_path() + '/avatars/{}.png'.format(tox.friend_get_public_key(friend_number)) super(ReceiveAvatar, self).__init__(path, tox, friend_number, size, file_number) if size > self.MAX_AVATAR_SIZE: self.send_control(TOX_FILE_CONTROL['CANCEL']) diff --git a/src/history.py b/src/history.py index 08c7182..980d146 100644 --- a/src/history.py +++ b/src/history.py @@ -1,6 +1,6 @@ # coding=utf-8 from sqlite3 import connect -import profile as pr +import settings from os import chdir @@ -13,9 +13,10 @@ MESSAGE_OWNER = { class History(object): + def __init__(self, name): self._name = name - chdir(pr.ProfileHelper.get_path()) + chdir(settings.ProfileHelper.get_path()) db = connect(name + '.hstr') cursor = db.cursor() cursor.execute('CREATE TABLE IF NOT EXISTS friends(' @@ -24,7 +25,7 @@ class History(object): db.close() def export(self, directory): - path = pr.ProfileHelper.get_path() + self._name + '.hstr' + path = settings.ProfileHelper.get_path() + self._name + '.hstr' new_path = directory + self._name + '.hstr' with open(path, 'rb') as fin: data = fin.read() @@ -33,7 +34,7 @@ class History(object): print 'History exported to: {}'.format(new_path) def add_friend_to_db(self, tox_id): - chdir(pr.ProfileHelper.get_path()) + chdir(settings.ProfileHelper.get_path()) db = connect(self._name + '.hstr') try: cursor = db.cursor() @@ -53,7 +54,7 @@ class History(object): db.close() def delete_friend_from_db(self, tox_id): - chdir(pr.ProfileHelper.get_path()) + chdir(settings.ProfileHelper.get_path()) db = connect(self._name + '.hstr') try: cursor = db.cursor() @@ -67,7 +68,7 @@ class History(object): db.close() def friend_exists_in_db(self, tox_id): - chdir(pr.ProfileHelper.get_path()) + chdir(settings.ProfileHelper.get_path()) db = connect(self._name + '.hstr') cursor = db.cursor() cursor.execute('SELECT 0 FROM friends WHERE tox_id=?', (tox_id, )) @@ -76,7 +77,7 @@ class History(object): return result is not None def save_messages_to_db(self, tox_id, messages_iter): - chdir(pr.ProfileHelper.get_path()) + chdir(settings.ProfileHelper.get_path()) db = connect(self._name + '.hstr') try: cursor = db.cursor() @@ -90,7 +91,7 @@ class History(object): db.close() def delete_messages(self, tox_id): - chdir(pr.ProfileHelper.get_path()) + chdir(settings.ProfileHelper.get_path()) db = connect(self._name + '.hstr') try: cursor = db.cursor() @@ -107,7 +108,7 @@ class History(object): class MessageGetter(object): def __init__(self, name, tox_id): - chdir(pr.ProfileHelper.get_path()) + chdir(settings.ProfileHelper.get_path()) self._db = connect(name + '.hstr') self._cursor = self._db.cursor() self._cursor.execute('SELECT message, owner, unix_time, message_type FROM id' + tox_id + diff --git a/src/main.py b/src/main.py index ddf354f..0bd6378 100644 --- a/src/main.py +++ b/src/main.py @@ -1,10 +1,10 @@ import sys from loginscreen import LoginScreen -from settings import Settings +from settings import * from PySide import QtCore, QtGui from bootstrap import node_generator from mainscreen import MainWindow -from profile import ProfileHelper, tox_factory +from profile import tox_factory from callbacks import init_callbacks from util import curr_directory, get_style import styles.style @@ -18,7 +18,7 @@ class Toxygen(object): 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 = QtGui.QApplication(sys.argv) app.setWindowIcon(QtGui.QIcon(curr_directory() + '/images/icon.png')) @@ -44,24 +44,38 @@ class Toxygen(object): return elif _login.t == 1: # create new profile name = _login.name if _login.name else 'toxygen_user' - settings = Settings(name) self.tox = tox_factory() self.tox.self_set_name(_login.name if _login.name else 'Toxygen User') self.tox.self_set_status_message('Toxing on Toxygen') ProfileHelper.save_profile(self.tox.get_savedata(), name) + path = Settings.get_default_path() + settings = Settings(name) else: # load existing profile path, name = _login.get_data() - settings = Settings(name) if _login.default: Settings.set_auto_profile(path, name) data = ProfileHelper.open_profile(path, name) + settings = Settings(name) self.tox = tox_factory(data, settings) else: path, name = auto_profile - settings = Settings(name) data = ProfileHelper.open_profile(path, name) + settings = Settings(name) self.tox = tox_factory(data, settings) + if ProfileHelper.is_active_profile(path, name): # profile is in use + deactivate = False + reply = QtGui.QMessageBox.question(None, + 'Profile {}'.format(name), + 'Looks like other instance of Toxygen uses this profile! Continue?', + QtGui.QMessageBox.Yes, + QtGui.QMessageBox.No) + if reply != QtGui.QMessageBox.Yes: + return + else: + settings.set_active_profile() + deactivate = True + self.ms = MainWindow(self.tox, self.reset) # tray icon @@ -98,6 +112,8 @@ class Toxygen(object): self.init.wait() data = self.tox.get_savedata() ProfileHelper.save_profile(data) + if deactivate: + settings.close() del self.tox def reset(self): @@ -140,13 +156,20 @@ class Toxygen(object): # bootstrap try: for data in node_generator(): + if self.stop: + return self.tox.bootstrap(*data) except: pass - self.msleep(10000) - while not self.tox.self_get_connection_status() and not self.stop: + for _ in xrange(10): + if self.stop: + return + self.msleep(1000) + while not self.tox.self_get_connection_status(): try: for data in node_generator(): + if self.stop: + return self.tox.bootstrap(*data) except: pass diff --git a/src/menu.py b/src/menu.py index 248bff1..a91d037 100644 --- a/src/menu.py +++ b/src/menu.py @@ -1,10 +1,11 @@ from PySide import QtCore, QtGui -from settings import Settings -from profile import Profile, ProfileHelper +from settings import * +from profile import Profile from util import get_style, curr_directory class CenteredWidget(QtGui.QWidget): + def __init__(self): super(CenteredWidget, self).__init__() self.center() diff --git a/src/profile.py b/src/profile.py index deba509..ac6d134 100644 --- a/src/profile.py +++ b/src/profile.py @@ -3,7 +3,7 @@ from PySide import QtCore, QtGui from tox import Tox import os from messages import * -from settings import Settings +from settings import * from toxcore_enums_and_consts import * from ctypes import * from util import curr_time, log, Singleton, curr_directory, convert_time @@ -13,63 +13,6 @@ from file_transfers import * import time -class ProfileHelper(object): - """ - Class with static methods for search, load and save profiles - """ - @staticmethod - def find_profiles(): - path = Settings.get_default_path() - result = [] - # check default path - if not os.path.exists(path): - os.makedirs(path) - for fl in os.listdir(path): - if fl.endswith('.tox'): - name = fl[:-4] - result.append((path, name)) - path = curr_directory() - # check current directory - for fl in os.listdir(path): - if fl.endswith('.tox'): - name = fl[:-4] - result.append((path + '/', name)) - return result - - @staticmethod - def open_profile(path, name): - ProfileHelper._path = path + name + '.tox' - ProfileHelper._directory = path - with open(ProfileHelper._path, 'rb') as fl: - data = fl.read() - if data: - print 'Data loaded from: {}'.format(ProfileHelper._path) - return data - else: - raise IOError('Save file not found. Path: {}'.format(ProfileHelper._path)) - - @staticmethod - def save_profile(data, name=None): - if name is not None: - ProfileHelper._path = Settings.get_default_path() + name + '.tox' - with open(ProfileHelper._path, 'wb') as fl: - fl.write(data) - print 'Data saved to: {}'.format(ProfileHelper._path) - - @staticmethod - def export_profile(new_path): - new_path += os.path.basename(ProfileHelper._path) - with open(ProfileHelper._path, 'rb') as fin: - data = fin.read() - with open(new_path, 'wb') as fout: - fout.write(data) - print 'Data exported to: {}'.format(new_path) - - @staticmethod - def get_path(): - return ProfileHelper._directory - - class Contact(object): """ Class encapsulating TOX contact diff --git a/src/settings.py b/src/settings.py index 9308e08..a3a8085 100644 --- a/src/settings.py +++ b/src/settings.py @@ -1,13 +1,13 @@ from platform import system import json import os -from util import Singleton +from util import Singleton, curr_directory class Settings(Singleton, dict): def __init__(self, name=''): - self.path = Settings.get_default_path() + str(name) + '.json' + self.path = ProfileHelper.get_path() + str(name) + '.json' self.name = name if os.path.isfile(self.path): with open(self.path) as fl: @@ -24,9 +24,8 @@ class Settings(Singleton, dict): with open(path) as fl: data = fl.read() auto = json.loads(data) - return auto['path'], auto['name'] - else: - return None + if 'path' in auto and 'name' in auto: + return auto['path'], auto['name'] @staticmethod def set_auto_profile(path, name): @@ -66,6 +65,32 @@ class Settings(Singleton, dict): with open(self.path, 'w') as fl: fl.write(text) + def close(self): + path = Settings.get_default_path() + 'toxygen.json' + if os.path.isfile(path): + with open(path) as fl: + data = fl.read() + app_settings = json.loads(data) + app_settings['active_profile'].remove(ProfileHelper.get_path() + self.name + '.tox') + data = json.dumps(app_settings) + with open(path, 'w') as fl: + fl.write(data) + + def set_active_profile(self): + path = Settings.get_default_path() + 'toxygen.json' + if os.path.isfile(path): + with open(path) as fl: + data = fl.read() + app_settings = json.loads(data) + else: + app_settings = {} + if 'active_profile' not in app_settings: + app_settings['active_profile'] = [] + app_settings['active_profile'].append(ProfileHelper.get_path() + str(self.name) + '.tox') + data = json.dumps(app_settings) + with open(path, 'w') as fl: + fl.write(data) + def export(self, path): text = json.dumps(self) with open(path + str(self.name) + '.json', 'w') as fl: @@ -77,3 +102,75 @@ class Settings(Singleton, dict): return os.getenv('HOME') + '/.config/tox/' elif system() == 'Windows': return os.getenv('APPDATA') + '/Tox/' + + +class ProfileHelper(object): + """ + Class with static methods for search, load and save profiles + """ + @staticmethod + def find_profiles(): + path = Settings.get_default_path() + result = [] + # check default path + if not os.path.exists(path): + os.makedirs(path) + for fl in os.listdir(path): + if fl.endswith('.tox'): + name = fl[:-4] + result.append((path, name)) + path = curr_directory() + # check current directory + for fl in os.listdir(path): + if fl.endswith('.tox'): + name = fl[:-4] + result.append((path + '/', name)) + return result + + @staticmethod + def is_active_profile(path, name): + path = path + name + '.tox' + settings = Settings.get_default_path() + 'toxygen.json' + if os.path.isfile(settings): + with open(settings) as fl: + data = fl.read() + data = json.loads(data) + if 'active_profile' in data: + return path in data['active_profile'] + else: + return False + + @staticmethod + def open_profile(path, name): + ProfileHelper._path = path + name + '.tox' + ProfileHelper._directory = path + with open(ProfileHelper._path, 'rb') as fl: + data = fl.read() + if data: + print 'Data loaded from: {}'.format(ProfileHelper._path) + return data + else: + raise IOError('Save file not found. Path: {}'.format(ProfileHelper._path)) + + @staticmethod + def save_profile(data, name=None): + if name is not None: + ProfileHelper._path = Settings.get_default_path() + name + '.tox' + ProfileHelper._directory = Settings.get_default_path() + with open(ProfileHelper._path, 'wb') as fl: + fl.write(data) + print 'Data saved to: {}'.format(ProfileHelper._path) + + @staticmethod + def export_profile(new_path): + new_path += os.path.basename(ProfileHelper._path) + with open(ProfileHelper._path, 'rb') as fin: + data = fin.read() + with open(new_path, 'wb') as fout: + fout.write(data) + print 'Data exported to: {}'.format(new_path) + + @staticmethod + def get_path(): + return ProfileHelper._directory + diff --git a/tests/tests.py b/tests/tests.py index cf31f08..901d20b 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,5 +1,6 @@ from src.bootstrap import node_generator from src.profile import * +from src.settings import ProfileHelper from src.tox_dns import tox_dns