def __init__(self): super(TardisDiff, self).__init__() self.difference = 0 self.clipboard = QtWidgets.QApplication.clipboard() # Set hot keys QtWidgets.QShortcut(QtGui.QKeySequence("Ctrl+Shift+C"), self, self.setClipboard) QtWidgets.QShortcut(QtGui.QKeySequence("Ctrl+Shift+T"), self, self.notify_time_submitters) self.options = TardisOptions() # Get plugins plugnplay.plugin_dirs = ['./plugins', ] plugnplay.load_plugins() # Get directory path # From: http://stackoverflow.com/a/22881871/1963958 if getattr(sys, 'frozen', False): # py2exe, PyInstaller, cx_Freeze script_path = os.path.abspath(sys.executable) else: script_path = inspect.getabsfile(TardisDiff) script_path = os.path.realpath(script_path) script_path = os.path.dirname(script_path) # Google for a fancy tardis icon until I've made one self.setWindowIcon(QtGui.QIcon( os.path.join(script_path, 'icon', 'tardis-by-camilla-isabell-kasbo.ico'))) self.initUI()
def _update_settings_xml(): ''' This function writes a new ``resources/settings.xml`` file which contains all settings for this addon and its plugins. ''' lazy_plugin_scan() plugnplay.load_plugins() try: os.makedirs(os.path.dirname(common.settings_file)) except OSError: pass new_xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>\n' new_xml += '<settings>\n' new_xml += '<category label="URLResolver">\n' new_xml += '\t<setting default="true" id="allow_universal" label="Enable Universal Resolvers" type="bool"/>\n' new_xml += '</category>\n' new_xml += '<category label="Resolvers 1">\n' xml_text = '<settings>' for imp in sorted(PluginSettings.implementors(), key=lambda x: x.name.upper()): xml_text += '<setting label="' + imp.name + '" type="lsep"/>' xml_text += imp.get_settings_xml() xml_text += '</settings>' i = 0 cat_count = 2 settings_xml = xml.dom.minidom.parseString(xml_text) for element in settings_xml.getElementsByTagName('setting'): if i > MAX_SETTINGS and element.getAttribute('type') == 'lsep': new_xml += '</category>\n' new_xml += '<category label="Resolvers %s">\n' % (cat_count) cat_count += 1 i = 0 new_xml += '\t' + element.toprettyxml() i += 1 new_xml += '</category>\n' new_xml += '</settings>\n' try: with open(common.settings_file, 'r') as f: old_xml = f.read() except: old_xml = '' if old_xml != new_xml: common.addon.log_debug('Updating Settings XML') try: with open(common.settings_file, 'w') as f: f.write(new_xml) except: raise else: common.addon.log_notice('No Settings Update Needed')
def test_load_external_py_file(self): self.assertFalse(plugnplay.normalize_path(self.full_path) + '.someplugin' in sys.modules) plugnplay.set_plugin_dirs(self.full_path) plugnplay.load_plugins() self.assertTrue(plugnplay.normalize_path(self.full_path) + '.someplugin' in sys.modules) import someplugin # Test de importing of the new plugin self.assertTrue(someplugin.SomePlugin is not None) p = someplugin.SomePlugin() self.assertTrue(isinstance(p, someplugin.SomePlugin))
def test_load_plugin_with_error(self): import sys plugnplay.set_plugin_dirs(join(self.basepath, 'wrong-plugins/')) mock_logger = Mock() plugnplay.load_plugins(logger = mock_logger) self.assertEquals(1, mock_logger.debug.call_count) call_args = mock_logger.debug.call_args self.assertEquals("Error loading plugin: myplugin", call_args[0][0]) self.assertTrue('exc_info' in call_args[1]) self.assertTrue(call_args[1]['exc_info'] is not None) self.assertTrue('myplugin' not in sys.modules) self.assertTrue('otherplug' in sys.modules)
def _update_settings_xml(): ''' This function writes a new ``resources/settings.xml`` file which contains all settings for this addon and its plugins. ''' lazy_plugin_scan() plugnplay.load_plugins() try: os.makedirs(os.path.dirname(common.settings_file)) except OSError: pass xml_text = "<settings>" for imp in sorted(PluginSettings.implementors(), key=lambda x: x.name.upper()): xml_text += '<setting label="' + imp.name + '" type="lsep"/>' xml_text += imp.get_settings_xml() xml_text += "</settings>" try: with open(common.settings_file, 'w') as f: f.write( '<?xml version="1.0" encoding="utf-8" standalone="yes"?>\n') f.write("<settings>\n") f.write("<category label=\"URLResolver\">\n") f.write("\t<setting default=\"true\" ") f.write("id=\"allow_universal\" ") f.write("label=\"Enable Universal Resolvers\" type=\"bool\"/>\n") f.write("\t<setting default=\"0.0.0\" ") f.write("id=\"addon_version\" visible=\"false\" ") f.write("label=\"URLResolver version\" type=\"text\"/>\n") f.write("</category>\n") f.write('<category label="Resolvers 1">\n') i = 0 cat_count = 2 settings_xml = xml.dom.minidom.parseString(xml_text) elements = settings_xml.getElementsByTagName('setting') for element in elements: if i > MAX_SETTINGS and element.getAttribute('type') == 'lsep': f.write('</category>\n') f.write('<category label="Resolvers %s">\n' % (cat_count)) cat_count += 1 i = 0 element.writexml(f, indent='\t', newl='\n') i += 1 f.write('</category>\n') f.write('</settings>\n') except IOError: common.addon.log_error('error writing ' + common.settings_file)
def test_load_plugin_with_error(self): import sys plugindir = join(self.basepath, 'wrong-plugins/') plugnplay.set_plugin_dirs(plugindir) mock_logger = Mock() plugnplay.load_plugins(logger=mock_logger) self.assertEquals(1, mock_logger.debug.call_count) call_args = mock_logger.debug.call_args self.assertEquals("Error loading plugin: myplugin", call_args[0][0]) self.assertTrue('exc_info' in call_args[1]) self.assertTrue(call_args[1]['exc_info'] is not None) self.assertTrue('myplugin' not in sys.modules) self.assertTrue(plugnplay.normalize_path(plugindir) + '.otherplug' in sys.modules)
def _update_settings_xml(): ''' This function writes a new ``resources/settings.xml`` file which contains all settings for this addon and its plugins. ''' lazy_plugin_scan() plugnplay.load_plugins() try: os.makedirs(os.path.dirname(common.settings_file)) except OSError: pass xml_text = "<settings>" for imp in sorted(PluginSettings.implementors(),key=lambda x:x.name.upper()): xml_text += '<setting label="' + imp.name + '" type="lsep"/>' xml_text += imp.get_settings_xml() xml_text += "</settings>" try: with open(common.settings_file, 'w') as f: f.write('<?xml version="1.0" encoding="utf-8" standalone="yes"?>\n') f.write("<settings>\n") f.write("<category label=\"URLResolver\">\n") f.write("\t<setting default=\"true\" ") f.write("id=\"allow_universal\" ") f.write("label=\"Enable Universal Resolvers\" type=\"bool\"/>\n") f.write("\t<setting default=\"0.0.0\" ") f.write("id=\"addon_version\" visible=\"false\" ") f.write("label=\"URLResolver version\" type=\"text\"/>\n") f.write("</category>\n") f.write('<category label="Resolvers 1">\n') i=0 cat_count = 2 settings_xml = xml.dom.minidom.parseString(xml_text) elements = settings_xml.getElementsByTagName('setting') for element in elements: if i>MAX_SETTINGS and element.getAttribute('type')=='lsep': f.write('</category>\n') f.write('<category label="Resolvers %s">\n' % (cat_count)) cat_count += 1 i=0 element.writexml(f, indent='\t', newl='\n') i += 1 f.write('</category>\n') f.write('</settings>\n') except IOError: common.addon.log_error('error writing ' + common.settings_file)
def test_load_plugin_with_error(self): import sys plugindir = join(self.basepath, "wrong-plugins/") plugnplay.set_plugin_dirs(plugindir) mock_logger = Mock() plugnplay.load_plugins(logger=mock_logger) self.assertEquals(1, mock_logger.debug.call_count) call_args = mock_logger.debug.call_args self.assertEquals("Error loading plugin: myplugin", call_args[0][0]) self.assertTrue("exc_info" in call_args[1]) self.assertTrue(call_args[1]["exc_info"] is not None) self.assertTrue("myplugin" not in sys.modules) self.assertTrue(plugnplay.normalize_path(plugindir) + ".otherplug" in sys.modules)
def load_plugins(self): """ Get path to plugins and load them into plugnplay """ # note: need to update if the setup.py module names change MODULE_NAME = "floss" req = pkg_resources.Requirement.parse(MODULE_NAME) requested_directory = os.path.join(MODULE_NAME, "plugins") try: plugins_path = pkg_resources.resource_filename(req, requested_directory) plugnplay.plugin_dirs = [plugins_path] plugnplay.load_plugins(logging.getLogger("plugin_loader")) except pkg_resources.DistributionNotFound as e: self.i("failed to load extra plugins: %s", e)
def _update_settings_xml(): ''' This function writes a new ``resources/settings.xml`` file which contains all settings for this addon and its plugins. ''' pretty_print = lambda f: '\n'.join( [line for line in f.split('\n') if line.strip()]) lazy_plugin_scan() plugnplay.load_plugins() try: try: os.makedirs(os.path.dirname(common.settings_file)) except OSError: pass f = open(common.settings_file, 'w') xml_text = "<settings>" for imp in PluginSettings.implementors(): xml_text += "<category label=\"" + imp.name + "\">" xml_text += imp.get_settings_xml() xml_text += "</category>" xml_text += "</settings>" try: f.write( '<?xml version="1.0" encoding="utf-8" standalone="yes"?>\n') f.write("<settings>\n") f.write("<category label=\"URLResolver\">\n") f.write("\t<setting default=\"true\" ") f.write("id=\"allow_universal\" ") f.write("label=\"Enable Universal Resolvers\" type=\"bool\"/>\n") f.write("\t<setting default=\"0.0.0\" ") f.write("id=\"addon_version\" visible=\"false\" ") f.write("label=\"URLResolver version\" type=\"text\"/>\n") f.write("</category>\n") settings_xml = xml.dom.minidom.parseString(xml_text) elements = settings_xml.getElementsByTagName('category') elements.sort(key=lambda x: x.getAttribute('label')) for i in elements: xml_text = i.toprettyxml() f.write(pretty_print(xml_text)) f.write('</settings>') finally: f.close except IOError: common.addon.log_error('error writing ' + common.settings_file)
def load_plugins(self): """ Get path to plugins and load them into plugnplay """ # note: need to update if the setup.py module names change MODULE_NAME = "floss" req = pkg_resources.Requirement.parse(MODULE_NAME) requested_directory = os.path.join(MODULE_NAME, "plugins") try: plugins_path = pkg_resources.resource_filename( req, requested_directory) plugnplay.plugin_dirs = [plugins_path] plugnplay.load_plugins(logging.getLogger("plugin_loader")) except pkg_resources.DistributionNotFound as e: self.w("failed to load extra plugins: %s", e)
def display_settings(): ''' Opens the settings dialog for :mod:`urlresolver` and its plugins. This can be called from your addon to provide access to global :mod:`urlresolver` settings. Each resolver plugin is also capable of exposing settings. .. note:: All changes made to these setting by the user are global and will affect any addon that uses :mod:`urlresolver` and its plugins. ''' lazy_plugin_scan() plugnplay.load_plugins() _update_settings_xml() common.addon.show_settings()
def test_load_same_name_different_folders(self): import sys dir1 = join(self.basepath, 'plugin/dir1') dir2 = join(self.basepath, 'plugin/dir2') plugnplay.set_plugin_dirs(dir1, dir2) plugnplay.load_plugins() dir1_norm = plugnplay.normalize_path(dir1) dir2_norm = plugnplay.normalize_path(dir2) self.assertTrue(dir1_norm + '.otherplugin' in sys.modules) self.assertTrue(dir2_norm + '.otherplugin' in sys.modules) mod1 = sys.modules[dir1_norm + '.otherplugin'] self.assertTrue(mod1.MyPlugin.dir1) mod2 = sys.modules[dir2_norm + '.otherplugin'] self.assertTrue(mod2.MyPlugin.dir2)
def run(self): if run_command(): sys.exit(0) options = parser.parse_options() validate_input_params(app_path=options.app_path,\ recv=options.recv, send=options.send) self.options = options # Will be used by the signal handlers try: daemon_options = self._create_daemon_options(options) ctx = daemon.DaemonContext(**daemon_options) with ctx: # Now that we are chrooted (if desired) we should correct # the paths options.app_path = self._normalize_path(options) self._set_loggers(options) wsgidapp = WsgidApp(options.app_path) self.log.debug("Loading plugins from {pluginsdir}".format(pluginsdir=wsgidapp.pluginsdir)) plugnplay.set_plugin_dirs(wsgidapp.pluginsdir) plugnplay.load_plugins(logger = self.log) self.log.debug("Using configs values {cfg}".format(cfg=options)) self.log.debug("Dropping privileges to: uid={uid}, gid={gid}".format(uid=daemon_options['uid'], gid=daemon_options['gid'])) self.log.info("Master process started") self.log.debug("Creating master pid file at {0}".format(self._return_pid_file_path(os.getpid(), self.MASTER))) self._write_pid(os.getpid(), self.MASTER) self._load_plugins(options) self.workers = [] for worker in range(options.workers): pid = self._create_worker(options) self.workers.append(pid) #Now we can register the master process SIGTERM handler signal.signal(signal.SIGTERM, self._sigterm_handler) self._wait_workers() except Exception, e: import traceback exc = sys.exc_info() self.log.info("".join(traceback.format_exception(exc[0], exc[1], exc[2]))) self._remove_pid(os.getpid(), self.MASTER) sys.exit(1)
def test_load_plugins_from_a_python_package(self): """ See github issue #6. """ from allinone.interface import AllInOne import allinone from allinone import interface all_in_one_dir = join(self.basepath, 'allinone') plugnplay.set_plugin_dirs(all_in_one_dir) logger = Mock() plugnplay.load_plugins(logger) # Check that we did not try to load a plugin named __init__. # See Github issue #9 self.assertEquals(0, logger.debug.call_count) self.assertTrue(dirname(all_in_one_dir) in sys.path, "sys.path not modified correctly") self.assertEquals(len(AllInOne.implementors()), 1) self.assertEquals(len(allinone.interface.AllInOne.implementors()), 1) self.assertEquals(len(interface.AllInOne.implementors()), 1)
def loadplugins( interfaces=[] ): import time if not interfaces or len(interfaces) <= 0: return plugin_dirs = [plugins_path] from glob import glob plugin_dirs.extend( glob( os.path.join( os.path.dirname(addon_path), addon_id + '.extn.*', 'plugins' ) ) ) import plugnplay plugnplay.set_plugin_dirs(*plugin_dirs) len_ifcs = len(interfaces) if len_ifcs == 1: interface = interfaces[0] plugnplay.load_plugins(interface.filecode) elif len_ifcs > 1: ifcs = [] for interface in interfaces: ifcs.append(interface.filecode) plugnplay.load_plugins(ifcs)
def test_load_plugins_in_alphabetical_order(self): import os base_dir = os.path.join(self.basepath, 'sortedloading') dir1 = os.path.join(base_dir, 'dir1') dir2 = os.path.join(base_dir, 'dir2') dirs = [base_dir, dir1, dir2] plugnplay.set_plugin_dirs(*dirs) with mock.patch('plugnplay._import_module') as import_mock: plugnplay.load_plugins() assert 7 == import_mock.call_count #``aplug.py, dir1/aplug.py, dir2/bplug.by, dir1/cplug.py, dir2/dplug.py, dir2/pplug.py, zplug.py`` call_list = [ mock.call(base_dir, 'aplug', logger=None), mock.call(dir1, 'aplug', logger=None), mock.call(dir2, 'bplug', logger=None), mock.call(dir1, 'cplug', logger=None), mock.call(dir2, 'dplug', logger=None), mock.call(dir2, 'pplug', logger=None), mock.call(base_dir, 'zplug', logger=None), ] assert call_list == import_mock.call_args_list
def test_load_plugins_in_alphabetical_order(self): import os base_dir = os.path.join(self.basepath, "sortedloading") dir1 = os.path.join(base_dir, "dir1") dir2 = os.path.join(base_dir, "dir2") dirs = [base_dir, dir1, dir2] plugnplay.set_plugin_dirs(*dirs) with mock.patch("plugnplay._import_module") as import_mock: plugnplay.load_plugins() assert 7 == import_mock.call_count # ``aplug.py, dir1/aplug.py, dir2/bplug.by, dir1/cplug.py, dir2/dplug.py, dir2/pplug.py, zplug.py`` call_list = [ mock.call(base_dir, "aplug", logger=None), mock.call(dir1, "aplug", logger=None), mock.call(dir2, "bplug", logger=None), mock.call(dir1, "cplug", logger=None), mock.call(dir2, "dplug", logger=None), mock.call(dir2, "pplug", logger=None), mock.call(base_dir, "zplug", logger=None), ] assert call_list == import_mock.call_args_list
def loadplugins(interfaces=[]): import time if not interfaces or len(interfaces) <= 0: return plugin_dirs = [plugins_path] from glob import glob plugin_dirs.extend( glob( os.path.join(os.path.dirname(addon_path), addon_id + '.extn.*', 'plugins'))) import plugnplay plugnplay.set_plugin_dirs(*plugin_dirs) len_ifcs = len(interfaces) if len_ifcs == 1: interface = interfaces[0] plugnplay.load_plugins(interface.filecode) elif len_ifcs > 1: ifcs = [] for interface in interfaces: ifcs.append(interface.filecode) plugnplay.load_plugins(ifcs)
For most cases you probably want to use :func:`urlresolver.resolve` or :func:`urlresolver.choose_source`. ''' import os import common import plugnplay from plugnplay.interfaces import UrlResolver from plugnplay.interfaces import PluginSettings from plugnplay.interfaces import SiteAuth import xbmcgui #load all available plugins plugnplay.set_plugin_dirs(common.plugins_path) plugnplay.load_plugins() def resolve(web_url): """ Resolve a web page to a media stream. It is usually as simple as:: import urlresolver media_url = urlresolver.resolve(web_url) where ``web_url`` is the address of a web page which is associated with a media file and ``media_url`` is the direct URL to the media. Behind the scenes, :mod:`urlresolver` will check each of the available resolver plugins to see if they accept the ``web_url`` in priority order
def load_modules(): plugnplay.plugin_dirs = ["./modules"] plugnplay.load_plugins()
''' import sys import os import shutil import plugnplay from interfaces import HashChecker if len(sys.argv) <= 1: sys.stdout.write("Need one parameter, the file to duplicate\n") sys.exit(1) plugnplay.plugin_dirs = ['./plugins'] plugnplay.load_plugins() where_to_duplicate = '/tmp/duplicate' original_file = sys.argv[1] if not os.path.exists(original_file): sys.stdout.write("Original file does not exist: %s\n" % original_file) sys.stdout.write("Exiting...\n") sys.exit(1) print "Copying {0} to {1}".format(original_file, where_to_duplicate) shutil.copy(original_file, where_to_duplicate) # This is plugnplay 0.3 #for listener in HashChecker.implementors():
def _load_plugins(self, options): if options.loader_dir: plugnplay.set_plugin_dirs(*options.loader_dir) plugnplay.load_plugins()