toxygen/toxygen/plugin_support/plugin_support.py

195 lines
6.2 KiB
Python
Raw Normal View History

2018-05-10 17:47:34 +00:00
import utils.util as util
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
2016-06-22 11:35:22 +00:00
import sys
2016-05-28 10:06:13 +00:00
2018-07-16 18:29:15 +00:00
class Plugin:
2016-05-28 10:06:13 +00:00
2018-07-16 18:29:15 +00:00
def __init__(self, plugin, is_active):
self._instance = plugin
self._is_active = is_active
def get_instance(self):
return self._instance
instance = property(get_instance)
def get_is_active(self):
return self._is_active
def set_is_active(self, is_active):
self._is_active = is_active
is_active = property(get_is_active, set_is_active)
class PluginLoader:
def __init__(self, settings, app):
2016-05-28 10:06:13 +00:00
self._settings = settings
2018-07-16 18:29:15 +00:00
self._app = app
self._plugins = {} # dict. key - plugin unique short name, value - Plugin instance
2016-05-28 10:06:13 +00:00
def set_tox(self, tox):
"""
New tox instance
"""
2018-07-16 18:29:15 +00:00
for plugin in self._plugins.values():
plugin.instance.set_tox(tox)
2016-05-28 10:06:13 +00:00
def load(self):
"""
Load all plugins in plugins folder
"""
2018-07-16 18:29:15 +00:00
path = util.get_plugins_directory()
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)
2017-03-25 15:21:25 +00:00
# looking for plugin class in module
2018-07-16 18:29:15 +00:00
if not inspect.isclass(obj) or not hasattr(obj, 'is_plugin') or not obj.is_plugin:
continue
print('Plugin', elem)
try: # create instance of plugin class
instance = obj(self._app)
is_active = instance.get_short_name() in self._settings['plugins']
if is_active:
instance.start()
except Exception as ex:
util.log('Exception in module ' + name + ' Exception: ' + str(ex))
continue
self._plugins[instance.get_short_name()] = Plugin(instance, is_active)
break
2016-05-28 10:06:13 +00:00
2016-10-15 16:03:33 +00:00
def callback_lossless(self, friend_number, data):
2016-05-28 10:06:13 +00:00
"""
New incoming custom lossless packet (callback)
"""
l = data[0] - pl.LOSSLESS_FIRST_BYTE
name = ''.join(chr(x) for x in data[1:l + 1])
2018-07-16 18:29:15 +00:00
if name in self._plugins and self._plugins[name].is_active:
self._plugins[name].instance.lossless_packet(''.join(chr(x) for x in data[l + 1:]), friend_number)
2016-05-28 10:06:13 +00:00
2016-10-15 16:03:33 +00:00
def callback_lossy(self, friend_number, data):
2016-05-28 10:06:13 +00:00
"""
New incoming custom lossy packet (callback)
"""
l = data[0] - pl.LOSSY_FIRST_BYTE
name = ''.join(chr(x) for x in data[1:l + 1])
2018-07-16 18:29:15 +00:00
if name in self._plugins and self._plugins[name].is_active:
self._plugins[name].instance.lossy_packet(''.join(chr(x) for x in data[l + 1:]), friend_number)
2016-05-28 10:06:13 +00:00
def friend_online(self, friend_number):
2016-05-30 19:26:07 +00:00
"""
Friend with specified number is online
"""
2018-07-16 18:29:15 +00:00
for plugin in self._plugins.values():
if plugin.is_active:
plugin.instance.friend_connected(friend_number)
2016-05-28 10:06:13 +00:00
def get_plugins_list(self):
"""
Returns list of all plugins
"""
result = []
2018-07-16 18:29:15 +00:00
for plugin in self._plugins.values():
2017-08-30 19:20:31 +00:00
try:
2018-07-16 18:29:15 +00:00
result.append([plugin.instance.get_name(), # plugin full name
plugin.is_active, # is enabled
plugin.instance.get_description(), # plugin description
plugin.instance.get_short_name()]) # key - short unique name
2017-08-30 19:20:31 +00:00
except:
continue
2018-07-16 18:29:15 +00:00
2016-05-28 10:06:13 +00:00
return result
def plugin_window(self, key):
"""
Return window or None for specified plugin
"""
2018-07-16 18:29:15 +00:00
return self._plugins[key].instance.get_window()
2016-05-28 10:06:13 +00:00
def toggle_plugin(self, key):
"""
Enable/disable plugin
:param key: plugin short name
"""
plugin = self._plugins[key]
2018-07-16 18:29:15 +00:00
if plugin.is_active:
plugin.instance.stop()
2016-05-28 10:06:13 +00:00
else:
2018-07-16 18:29:15 +00:00
plugin.instance.start()
plugin.is_active = not plugin.is_active
if plugin.is_active:
2016-05-28 10:06:13 +00:00
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]
2018-07-16 18:29:15 +00:00
if name in self._plugins and self._plugins[name].is_active:
self._plugins[name].instance.command(text[len(name) + 1:])
2016-05-28 10:06:13 +00:00
def get_menu(self, num):
2016-05-28 10:06:13 +00:00
"""
Return list of items for menu
"""
result = []
2018-07-16 18:29:15 +00:00
for plugin in self._plugins.values():
if not plugin.is_active:
continue
try:
result.extend(plugin.instance.get_menu(num))
except:
continue
2016-05-28 10:06:13 +00:00
return result
2016-07-19 20:19:42 +00:00
def get_message_menu(self, menu, selected_text):
result = []
2018-07-16 18:29:15 +00:00
for plugin in self._plugins.values():
if not plugin.is_active:
continue
try:
result.extend(plugin.instance.get_message_menu(menu, selected_text))
except:
pass
2016-07-19 20:19:42 +00:00
return result
2016-05-28 10:06:13 +00:00
def stop(self):
"""
App is closing, stop all plugins
"""
2016-06-22 11:35:22 +00:00
for key in list(self._plugins.keys()):
2018-07-16 18:29:15 +00:00
if self._plugins[key].is_active:
self._plugins[key].instance.close()
2016-05-28 10:06:13 +00:00
del self._plugins[key]
2017-03-25 15:21:25 +00:00
def reload(self):
print('Reloading plugins')
self.stop()
self.load()