toxygen/toxygen/plugin_support.py

157 lines
5.3 KiB
Python
Raw Normal View History

2016-05-28 10:06:13 +00:00
import util
2016-07-06 13:25:04 +00:00
import profile
2016-05-28 10:06:13 +00:00
import os
2016-06-22 11:35:22 +00:00
import importlib
2016-05-28 10:06:13 +00:00
import inspect
import plugins.plugin_super_class as pl
import toxencryptsave
2016-06-22 11:35:22 +00:00
import sys
2016-05-28 10:06:13 +00:00
class PluginLoader(util.Singleton):
def __init__(self, tox, settings):
2016-06-22 11:35:22 +00:00
super().__init__()
2016-07-06 13:25:04 +00:00
self._profile = profile.Profile.get_instance()
2016-05-28 10:06:13 +00:00
self._settings = settings
self._plugins = {} # dict. key - plugin unique short name, value - tuple (plugin instance, is active)
self._tox = tox
2016-07-01 20:15:00 +00:00
self._encr = toxencryptsave.ToxEncryptSave.get_instance()
2016-05-28 10:06:13 +00:00
def set_tox(self, tox):
"""
New tox instance
"""
self._tox = tox
for value in self._plugins.values():
value[0].set_tox(tox)
def load(self):
"""
Load all plugins in plugins folder
"""
path = util.curr_directory() + '/plugins/'
2016-06-08 15:35:40 +00:00
if not os.path.exists(path):
util.log('Plugin dir not found')
return
2016-06-22 11:35:22 +00:00
else:
sys.path.append(path)
2016-05-28 10:06:13 +00:00
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:
2016-06-22 11:35:22 +00:00
module = importlib.import_module(name) # import plugin
2016-05-28 10:06:13 +00:00
except ImportError:
util.log('Import error in module ' + name)
continue
except Exception as ex:
util.log('Exception in module ' + name + ' Exception: ' + str(ex))
continue
for elem in dir(module):
obj = getattr(module, elem)
2016-06-22 11:35:22 +00:00
if inspect.isclass(obj) and hasattr(obj, 'is_plugin') and obj.is_plugin: # looking for plugin class in module
2016-06-21 11:58:11 +00:00
print('Plugin', elem)
2016-05-28 10:06:13 +00:00
try: # create instance of plugin class
inst = obj(self._tox, self._profile, self._settings, self._encr)
autostart = inst.get_short_name() in self._settings['plugins']
if autostart:
inst.start()
except Exception as ex:
util.log('Exception in module ' + name + ' Exception: ' + str(ex))
continue
self._plugins[inst.get_short_name()] = [inst, autostart] # (inst, is active)
break
def callback_lossless(self, friend_number, data, length):
"""
New incoming custom lossless packet (callback)
"""
l = data[0] - pl.LOSSLESS_FIRST_BYTE
name = ''.join(chr(x) for x in data[1:l + 1])
if name in self._plugins and self._plugins[name][1]:
self._plugins[name][0].lossless_packet(''.join(chr(x) for x in data[l + 1:length]), friend_number)
def callback_lossy(self, friend_number, data, length):
"""
New incoming custom lossy packet (callback)
"""
l = data[0] - pl.LOSSY_FIRST_BYTE
name = ''.join(chr(x) for x in data[1:l + 1])
if name in self._plugins and self._plugins[name][1]:
self._plugins[name][0].lossy_packet(''.join(chr(x) for x in data[l + 1:length]), friend_number)
def friend_online(self, friend_number):
2016-05-30 19:26:07 +00:00
"""
Friend with specified number is online
"""
2016-05-28 10:06:13 +00:00
for elem in self._plugins.values():
if elem[1]:
elem[0].friend_connected(friend_number)
def get_plugins_list(self):
"""
Returns list of all plugins
"""
result = []
for data in self._plugins.values():
result.append([data[0].get_name(), # plugin full name
data[1], # is enabled
data[0].get_description(), # plugin description
data[0].get_short_name()]) # key - short unique name
return result
def plugin_window(self, key):
"""
Return window or None for specified plugin
"""
return self._plugins[key][0].get_window()
def toggle_plugin(self, key):
"""
Enable/disable plugin
:param key: plugin short name
"""
plugin = self._plugins[key]
if plugin[1]:
plugin[0].stop()
else:
plugin[0].start()
plugin[1] = not plugin[1]
if plugin[1]:
self._settings['plugins'].append(key)
else:
self._settings['plugins'].remove(key)
self._settings.save()
def command(self, text):
"""
New command for plugin
"""
text = text.strip()
name = text.split()[0]
if name in self._plugins and self._plugins[name][1]:
self._plugins[name][0].command(text[len(name) + 1:])
def get_menu(self, menu, num):
"""
Return list of items for menu
"""
result = []
for elem in self._plugins.values():
if elem[1]:
try:
result.extend(elem[0].get_menu(menu, num))
except:
continue
return result
def stop(self):
"""
App is closing, stop all plugins
"""
2016-06-22 11:35:22 +00:00
for key in list(self._plugins.keys()):
2016-05-28 10:06:13 +00:00
self._plugins[key][0].close()
del self._plugins[key]