diff options
Diffstat (limited to 'module/plugins/hooks/UpdateManager.py')
-rw-r--r-- | module/plugins/hooks/UpdateManager.py | 201 |
1 files changed, 109 insertions, 92 deletions
diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 98d602226..117da0633 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -2,34 +2,23 @@ from __future__ import with_statement +import operator import os import re import sys import time +import traceback -from operator import itemgetter +from module.plugins.internal.Addon import Expose, Addon, threaded +from module.plugins.internal.Plugin import exists +from module.utils import fs_encode, save_join as fs_join -from module.network.RequestFactory import getURL -from module.plugins.Hook import Expose, Hook, threaded -from module.utils import save_join - -# Case-sensitive os.path.exists -def exists(path): - if os.path.exists(path): - if os.name == 'nt': - dir, name = os.path.split(path) - return name in os.listdir(dir) - else: - return True - else: - return False - - -class UpdateManager(Hook): +class UpdateManager(Addon): __name__ = "UpdateManager" __type__ = "hook" - __version__ = "0.52" + __version__ = "0.55" + __status__ = "testing" __config__ = [("activated" , "bool", "Activated" , True ), ("checkinterval", "int" , "Check interval in hours" , 8 ), @@ -39,7 +28,7 @@ class UpdateManager(Hook): ("reloadplugins", "bool", "Monitor plugin code changes in debug mode", True ), ("nodebugupdate", "bool", "Don't update plugins in debug mode" , False)] - __description__ = """ Check for updates """ + __description__ = """Check for updates""" __license__ = "GPLv3" __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] @@ -50,26 +39,26 @@ class UpdateManager(Hook): MIN_CHECK_INTERVAL = 3 * 60 * 60 #: 3 hours - def coreReady(self): + def activate(self): if self.checkonstart: - self.core.api.pauseServer() + self.pyload.api.pauseServer() self.update() if self.do_restart is False: - self.core.api.unpauseServer() + self.pyload.api.unpauseServer() - self.initPeriodical() + self.init_periodical() - def setup(self): + def init(self): self.info = {'pyload': False, 'version': None, 'plugins': False, 'last_check': time.time()} - self.mtimes = {} #: store modification time for each plugin + self.mtimes = {} #: Store modification time for each plugin - self.event_list = ["allDownloadsProcessed"] + self.event_map = {'allDownloadsProcessed': "all_downloads_processed"} self.interval = 10 - if self.getConfig('checkonstart'): - self.core.api.pauseServer() + if self.get_config('checkonstart'): + self.pyload.api.pauseServer() self.checkonstart = True else: self.checkonstart = False @@ -77,32 +66,43 @@ class UpdateManager(Hook): self.do_restart = False - def allDownloadsProcessed(self): + def all_downloads_processed(self): if self.do_restart is True: - self.logWarning(_("Downloads are done, restarting pyLoad to reload the updated plugins")) - self.core.api.restart() + self.log_warning(_("Downloads are done, restarting pyLoad to reload the updated plugins")) + self.pyload.api.restart() def periodical(self): - if self.core.debug: - if self.getConfig('reloadplugins'): - self.autoreloadPlugins() + if self.pyload.debug: + if self.get_config('reloadplugins'): + self.autoreload_plugins() - if self.getConfig('nodebugupdate'): + if self.get_config('nodebugupdate'): return - if self.getConfig('checkperiod') \ - and time.time() - max(self.MIN_CHECK_INTERVAL, self.getConfig('checkinterval') * 60 * 60) > self.info['last_check']: + if self.get_config('checkperiod') \ + and time.time() - max(self.MIN_CHECK_INTERVAL, self.get_config('checkinterval') * 60 * 60) > self.info['last_check']: self.update() + #: Deprecated method, use `autoreload_plugins` instead @Expose - def autoreloadPlugins(self): - """ reload and reindex all modified plugins """ + def autoreloadPlugins(self, *args, **kwargs): + """ + See `autoreload_plugins` + """ + return self.autoreload_plugins(*args, **kwargs) + + + @Expose + def autoreload_plugins(self): + """ + Reload and reindex all modified plugins + """ modules = filter( lambda m: m and (m.__name__.startswith("module.plugins.") or m.__name__.startswith("userplugins.")) and - m.__name__.count(".") >= 2, sys.modules.itervalues() + m.__name__.count(".") >= 2, sys.modules.values() ) reloads = [] @@ -110,12 +110,12 @@ class UpdateManager(Hook): for m in modules: root, type, name = m.__name__.rsplit(".", 2) id = (type, name) - if type in self.core.pluginManager.plugins: + if type in self.pyload.pluginManager.plugins: f = m.__file__.replace(".pyc", ".py") if not os.path.isfile(f): continue - mtime = os.stat(f).st_mtime + mtime = os.path.getmtime(f) if id not in self.mtimes: self.mtimes[id] = mtime @@ -123,29 +123,31 @@ class UpdateManager(Hook): reloads.append(id) self.mtimes[id] = mtime - return True if self.core.pluginManager.reloadPlugins(reloads) else False + return True if self.pyload.pluginManager.reloadPlugins(reloads) else False def server_response(self): try: - return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines() + return self.load(self.SERVER_URL, + get={'v': self.pyload.api.getServerVersion()}).splitlines() except Exception: - self.logWarning(_("Unable to retrieve server to get updates")) + self.log_warning(_("Unable to retrieve server to get updates")) @Expose @threaded def update(self): - """ check for updates """ - - if self._update() is 2 and self.getConfig('autorestart'): - if not self.core.api.statusDownloads(): - self.core.api.restart() + """ + Check for updates + """ + if self._update() == 2 and self.get_config('autorestart'): + if not self.pyload.api.statusDownloads(): + self.pyload.api.restart() else: self.do_restart = True - self.logWarning(_("Downloads are active, will restart once the download is done")) - self.core.api.pauseServer() + self.log_warning(_("Downloads are active, will restart once the download is done")) + self.pyload.api.pauseServer() def _update(self): @@ -157,30 +159,31 @@ class UpdateManager(Hook): exitcode = 0 elif data[0] == "None": - self.logInfo(_("No new pyLoad version available")) - exitcode = self._updatePlugins(data[1:]) + self.log_info(_("No new pyLoad version available")) + exitcode = self._update_plugins(data[1:]) elif onlyplugin: exitcode = 0 else: - self.logInfo(_("*** New pyLoad Version %s available ***") % data[0]) - self.logInfo(_("*** Get it here: https://github.com/pyload/pyload/releases ***")) + self.log_info(_("*** New pyLoad Version %s available ***") % data[0]) + self.log_info(_("*** Get it here: https://github.com/pyload/pyload/releases ***")) self.info['pyload'] = True self.info['version'] = data[0] exitcode = 3 - # Exit codes: - # -1 = No plugin updated, new pyLoad version available - # 0 = No plugin updated - # 1 = Plugins updated - # 2 = Plugins updated, but restart required + #: Exit codes: + #: -1 = No plugin updated, new pyLoad version available + #: 0 = No plugin updated + #: 1 = Plugins updated + #: 2 = Plugins updated, but restart required return exitcode - def _updatePlugins(self, data): - """ check for plugin updates """ - + def _update_plugins(self, data): + """ + Check for plugin updates + """ exitcode = 0 updated = [] @@ -202,7 +205,7 @@ class UpdateManager(Hook): if blacklist: type_plugins = [(plugin['type'], plugin['name'].rsplit('.', 1)[0]) for plugin in blacklist] - # Protect UpdateManager from self-removing + #: Protect UpdateManager from self-removing try: type_plugins.remove(("hook", "UpdateManager")) except ValueError: @@ -210,17 +213,17 @@ class UpdateManager(Hook): for t, n in type_plugins: for idx, plugin in enumerate(updatelist): - if n == plugin['name'] and t == plugin['type']: + if n is plugin['name'] and t is plugin['type']: updatelist.pop(idx) break - for t, n in self.removePlugins(sorted(type_plugins)): - self.logInfo(_("Removed blacklisted plugin: [%(type)s] %(name)s") % { + for t, n in self.remove_plugins(sorted(type_plugins)): + self.log_info(_("Removed blacklisted plugin: [%(type)s] %(name)s") % { 'type': t, 'name': n, }) - for plugin in sorted(updatelist, key=itemgetter("type", "name")): + for plugin in sorted(updatelist, key=operator.itemgetter("type", "name")): filename = plugin['name'] prefix = plugin['type'] version = plugin['version'] @@ -236,7 +239,7 @@ class UpdateManager(Hook): else: type = prefix - plugins = getattr(self.core.pluginManager, "%sPlugins" % type) + plugins = getattr(self.pyload.pluginManager, "%sPlugins" % type) oldver = float(plugins[name]['v']) if name in plugins else None newver = float(version) @@ -248,62 +251,74 @@ class UpdateManager(Hook): else: continue - self.logInfo(_(msg) % {'type' : type, + self.log_info(_(msg) % {'type' : type, 'name' : name, 'oldver': oldver, 'newver': newver}) try: - content = getURL(url % plugin) + content = self.load(url % plugin, decode=False) m = VERSION.search(content) if m and m.group(2) == version: - with open(save_join("userplugins", prefix, filename), "wb") as f: - f.write(content) + with open(fs_join("userplugins", prefix, filename), "wb") as f: + f.write(fs_encode(content)) updated.append((prefix, name)) else: - raise Exception, _("Version mismatch") + raise Exception(_("Version mismatch")) except Exception, e: - self.logError(_("Error updating plugin: %s") % filename, e) + self.log_error(_("Error updating plugin: %s") % filename, e) + if self.pyload.debug: + traceback.print_exc() if updated: - self.logInfo(_("*** Plugins updated ***")) + self.log_info(_("*** Plugins updated ***")) - if self.core.pluginManager.reloadPlugins(updated): + if self.pyload.pluginManager.reloadPlugins(updated): exitcode = 1 else: - self.logWarning(_("pyLoad restart required to reload the updated plugins")) + self.log_warning(_("pyLoad restart required to reload the updated plugins")) self.info['plugins'] = True exitcode = 2 self.manager.dispatchEvent("plugin_updated", updated) else: - self.logInfo(_("No plugin updates available")) + self.log_info(_("No plugin updates available")) - # Exit codes: - # 0 = No plugin updated - # 1 = Plugins updated - # 2 = Plugins updated, but restart required + #: Exit codes: + #: 0 = No plugin updated + #: 1 = Plugins updated + #: 2 = Plugins updated, but restart required return exitcode + #: Deprecated method, use `remove_plugins` instead @Expose - def removePlugins(self, type_plugins): - """ delete plugins from disk """ + def removePlugins(self, *args, **kwargs): + """ + See `remove_plugins` + """ + return self.remove_plugins(*args, **kwargs) + + @Expose + def remove_plugins(self, type_plugins): + """ + Delete plugins from disk + """ if not type_plugins: return removed = set() - self.logDebug("Requested deletion of plugins: %s" % type_plugins) + self.log_debug("Requested deletion of plugins: %s" % type_plugins) for type, name in type_plugins: rootplugins = os.path.join(pypath, "module", "plugins") for dir in ("userplugins", rootplugins): - py_filename = save_join(dir, type, name + ".py") + py_filename = fs_join(dir, type, name + ".py") pyc_filename = py_filename + "c" if type == "hook": @@ -311,7 +326,7 @@ class UpdateManager(Hook): self.manager.deactivateHook(name) except Exception, e: - self.logDebug(e) + self.log_debug(e) for filename in (py_filename, pyc_filename): if not exists(filename): @@ -321,10 +336,12 @@ class UpdateManager(Hook): os.remove(filename) except OSError, e: - self.logError(_("Error removing: %s") % filename, e) + self.log_warning(_("Error removing: %s") % filename, e) + if self.pyload.debug: + traceback.print_exc() else: id = (type, name) removed.add(id) - return list(removed) #: return a list of the plugins successfully removed + return list(removed) #: Return a list of the plugins successfully removed |