From 5a0843d98b8669fc351d7d8a9c408552e2d93dce Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Wed, 22 Jun 2016 14:35:22 +0300 Subject: [PATCH] plugins fixes, improvements --- src/avwidgets.py | 2 +- src/bootstrap.py | 2 +- src/calls.py | 2 +- src/contact.py | 2 +- src/history.py | 4 ++-- src/libtox.py | 6 +++--- src/main.py | 4 ++-- src/messages.py | 2 +- src/notifications.py | 2 +- src/plugin_support.py | 13 ++++++++----- src/plugins/plugin_super_class.py | 23 ++++++++++++++--------- src/profile.py | 11 ++++++----- src/settings.py | 4 ++-- src/smileys.py | 2 +- src/tox.py | 2 +- src/toxav.py | 2 +- src/toxencryptsave.py | 2 +- src/util.py | 3 +++ 18 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/avwidgets.py b/src/avwidgets.py index fd0c614..511fd8c 100644 --- a/src/avwidgets.py +++ b/src/avwidgets.py @@ -65,7 +65,7 @@ class IncomingCallWidget(widgets.CenteredWidget): QtCore.QThread.__init__(self) def run(self): - class AudioFile(object): + class AudioFile: chunk = 1024 def __init__(self, fl): diff --git a/src/bootstrap.py b/src/bootstrap.py index 9650446..b4446b2 100644 --- a/src/bootstrap.py +++ b/src/bootstrap.py @@ -1,7 +1,7 @@ import random -class Node(object): +class Node: def __init__(self, ip, port, tox_key, rand): self._ip, self._port, self._tox_key, self.rand = ip, port, tox_key, rand diff --git a/src/calls.py b/src/calls.py index 4c87541..6e0d936 100644 --- a/src/calls.py +++ b/src/calls.py @@ -13,7 +13,7 @@ CALL_TYPE = { } -class AV(object): +class AV: def __init__(self, toxav): self._toxav = toxav diff --git a/src/contact.py b/src/contact.py index 9ffa2bb..3ee1b90 100644 --- a/src/contact.py +++ b/src/contact.py @@ -7,7 +7,7 @@ except ImportError: from toxcore_enums_and_consts import TOX_PUBLIC_KEY_SIZE -class Contact(object): +class Contact: """ Class encapsulating TOX contact Properties: name (alias of contact or name), status_message, status (connection status) diff --git a/src/history.py b/src/history.py index 4435d3f..92e6d91 100644 --- a/src/history.py +++ b/src/history.py @@ -15,7 +15,7 @@ MESSAGE_OWNER = { } -class History(object): +class History: def __init__(self, name): self._name = name @@ -148,7 +148,7 @@ class History(object): def messages_getter(self, tox_id): return History.MessageGetter(self._name, tox_id) - class MessageGetter(object): + class MessageGetter: def __init__(self, name, tox_id): chdir(settings.ProfileHelper.get_path()) self._db = connect(name + '.hstr') diff --git a/src/libtox.py b/src/libtox.py index 10bf8c0..16dc2a4 100644 --- a/src/libtox.py +++ b/src/libtox.py @@ -2,7 +2,7 @@ from platform import system from ctypes import CDLL -class LibToxCore(object): +class LibToxCore: def __init__(self): if system() == 'Linux': @@ -17,7 +17,7 @@ class LibToxCore(object): return self._libtoxcore.__getattr__(item) -class LibToxAV(object): +class LibToxAV: def __init__(self): if system() == 'Linux': @@ -33,7 +33,7 @@ class LibToxAV(object): return self._libtoxav.__getattr__(item) -class LibToxEncryptSave(object): +class LibToxEncryptSave: def __init__(self): if system() == 'Linux': diff --git a/src/main.py b/src/main.py index 058cc9d..7b725cf 100644 --- a/src/main.py +++ b/src/main.py @@ -18,7 +18,7 @@ import profile from plugin_support import PluginLoader -class Toxygen(object): +class Toxygen: def __init__(self, path_or_uri=None): super(Toxygen, self).__init__() @@ -322,7 +322,7 @@ class Toxygen(object): self.toxav.iterate() self.msleep(self.toxav.iteration_interval()) - class Login(object): + class Login: def __init__(self, arr): self.arr = arr diff --git a/src/messages.py b/src/messages.py index f04151d..87a1cc2 100644 --- a/src/messages.py +++ b/src/messages.py @@ -9,7 +9,7 @@ MESSAGE_TYPE = { } -class Message(object): +class Message: def __init__(self, message_type, owner, time): self._time = time diff --git a/src/notifications.py b/src/notifications.py index dd0e014..81a8a05 100644 --- a/src/notifications.py +++ b/src/notifications.py @@ -35,7 +35,7 @@ def tray_notification(title, text, tray, window): tray.connect(tray, QtCore.SIGNAL("messageClicked()"), message_clicked) -class AudioFile(object): +class AudioFile: chunk = 1024 def __init__(self, fl): diff --git a/src/plugin_support.py b/src/plugin_support.py index 0b1206a..2a1aebf 100644 --- a/src/plugin_support.py +++ b/src/plugin_support.py @@ -1,16 +1,17 @@ import util import profile import os -import imp +import importlib import inspect import plugins.plugin_super_class as pl import toxencryptsave +import sys class PluginLoader(util.Singleton): def __init__(self, tox, settings): - PluginLoader._instance = self + super().__init__() self._profile = profile.Profile.get_instance() self._settings = settings self._plugins = {} # dict. key - plugin unique short name, value - tuple (plugin instance, is active) @@ -33,13 +34,15 @@ class PluginLoader(util.Singleton): if not os.path.exists(path): util.log('Plugin dir not found') return + else: + sys.path.append(path) files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] for fl in files: if fl in ('plugin_super_class.py', '__init__.py') or not fl.endswith('.py'): continue name = fl[:-3] # module name without .py try: - module = imp.load_source('plugins.' + name, path + fl) # import plugin + module = importlib.import_module(name) # import plugin except ImportError: util.log('Import error in module ' + name) continue @@ -48,7 +51,7 @@ class PluginLoader(util.Singleton): continue for elem in dir(module): obj = getattr(module, elem) - if inspect.isclass(obj) and issubclass(obj, pl.PluginSuperClass): # looking for plugin class in module + if inspect.isclass(obj) and hasattr(obj, 'is_plugin') and obj.is_plugin: # looking for plugin class in module print('Plugin', elem) try: # create instance of plugin class inst = obj(self._tox, self._profile, self._settings, self._encr) @@ -148,6 +151,6 @@ class PluginLoader(util.Singleton): """ App is closing, stop all plugins """ - for key in self._plugins.keys(): + for key in list(self._plugins.keys()): self._plugins[key][0].close() del self._plugins[key] diff --git a/src/plugins/plugin_super_class.py b/src/plugins/plugin_super_class.py index f5f3402..c2aa673 100644 --- a/src/plugins/plugin_super_class.py +++ b/src/plugins/plugin_super_class.py @@ -26,13 +26,14 @@ def log(name, data): :param data: data for saving in log """ with open(path_to_data(name) + 'logs.txt', 'a') as fl: - fl.write(str(data) + '\n') + fl.write(bytes(data, 'utf-8') + b'\n') -class PluginSuperClass(object): +class PluginSuperClass: """ Superclass for all plugins. Plugin is python module with at least one class derived from PluginSuperClass. """ + is_plugin = True def __init__(self, name, short_name, tox=None, profile=None, settings=None, encrypt_save=None): """ @@ -159,9 +160,9 @@ class PluginSuperClass(object): """ This method loads settings of plugin and returns raw data """ - with open(path_to_data(self._short_name) + 'settings.json') as fl: + with open(path_to_data(self._short_name) + 'settings.json', 'rb') as fl: data = fl.read() - return data + return str(data, 'utf-8') def save_settings(self, data): """ @@ -169,7 +170,7 @@ class PluginSuperClass(object): :param data: string with data """ with open(path_to_data(self._short_name) + 'settings.json', 'wb') as fl: - fl.write(data) + fl.write(bytes(data, 'utf-8')) # ----------------------------------------------------------------------------------------------------------------- # Callbacks @@ -212,8 +213,10 @@ class PluginSuperClass(object): data = '' try: return self._tox.friend_send_lossless_packet(friend_number, - chr(len(self._short_name) + LOSSLESS_FIRST_BYTE) + - self._short_name + str(data)) + bytes([ord(x) for x in + chr(len(self._short_name) + LOSSLESS_FIRST_BYTE) + + self._short_name + str(data) + ])) except: return False @@ -228,7 +231,9 @@ class PluginSuperClass(object): data = '' try: return self._tox.friend_send_lossy_packet(friend_number, - chr(len(self._short_name) + LOSSY_FIRST_BYTE) + - self._short_name + str(data)) + bytes([ord(x) for x in + chr(len(self._short_name) + LOSSY_FIRST_BYTE) + + self._short_name + str(data) + ])) except: return False diff --git a/src/profile.py b/src/profile.py index 3a40da6..ac567c7 100644 --- a/src/profile.py +++ b/src/profile.py @@ -26,11 +26,12 @@ class Profile(contact.Contact, Singleton): :param tox: tox instance :param screen: ref to main screen """ - super(Profile, self).__init__(tox.self_get_name(), - tox.self_get_status_message(), - screen.user_info, - tox.self_get_address()) - Profile._instance = self + contact.Contact.__init__(self, + tox.self_get_name(), + tox.self_get_status_message(), + screen.user_info, + tox.self_get_address()) + Singleton.__init__(self) self._screen = screen self._messages = screen.messages self._tox = tox diff --git a/src/settings.py b/src/settings.py index 45b2bc1..544f5ac 100644 --- a/src/settings.py +++ b/src/settings.py @@ -14,7 +14,7 @@ class Settings(dict, Singleton): """ def __init__(self, name): - Settings._instance = self + Singleton.__init__(self) self.path = ProfileHelper.get_path() + str(name) + '.json' self.name = name if os.path.isfile(self.path): @@ -201,7 +201,7 @@ class ProfileHelper(Singleton): Class with methods for search, load and save profiles """ def __init__(self, path, name): - ProfileHelper._instance = self + Singleton.__init__(self) self._path = path + name + '.tox' self._directory = path # create /avatars if not exists: diff --git a/src/smileys.py b/src/smileys.py index bf1eb84..f64c6f7 100644 --- a/src/smileys.py +++ b/src/smileys.py @@ -14,7 +14,7 @@ class SmileyLoader(util.Singleton): """ def __init__(self, settings): - SmileyLoader._instance = self + super().__init__() self._settings = settings self._curr_pack = None # current pack name self._smileys = {} # smileys dict. key - smiley (str), value - path to image (str) diff --git a/src/tox.py b/src/tox.py index 96c01d1..862badd 100644 --- a/src/tox.py +++ b/src/tox.py @@ -31,7 +31,7 @@ def bin_to_string(raw_id, length): return res.upper() -class Tox(object): +class Tox: libtoxcore = LibToxCore() diff --git a/src/toxav.py b/src/toxav.py index 29e3d52..a9f46b3 100644 --- a/src/toxav.py +++ b/src/toxav.py @@ -4,7 +4,7 @@ from libtox import LibToxAV from toxav_enums import * -class ToxAV(object): +class ToxAV: """ The ToxAV instance type. Each ToxAV instance can be bound to only one Tox instance, and Tox instance can have only one ToxAV instance. One must make sure to close ToxAV instance prior closing Tox instance otherwise undefined diff --git a/src/toxencryptsave.py b/src/toxencryptsave.py index 633586f..03d8b1c 100644 --- a/src/toxencryptsave.py +++ b/src/toxencryptsave.py @@ -39,7 +39,7 @@ class LibToxEncryptSave(util.Singleton): libtoxencryptsave = libtox.LibToxEncryptSave() def __init__(self): - LibToxEncryptSave._instance = self + super().__init__() self._passphrase = None def set_password(self, passphrase): diff --git a/src/util.py b/src/util.py index 2c114d6..d66a065 100644 --- a/src/util.py +++ b/src/util.py @@ -29,6 +29,9 @@ def convert_time(t): class Singleton: _instance = None + def __init__(self): + self.__class__._instance = self + @classmethod def get_instance(cls): return cls._instance