# -*- coding: utf-8 -*- """ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . @author: RaNaN @interface-version: 0.1 """ import sys import re from os import stat from os.path import join from time import time from module.network.RequestFactory import getURL from module.plugins.Hook import threaded, Expose, Hook class UpdateManager(Hook): __name__ = "UpdateManager" __version__ = "0.1" __description__ = """checks for updates""" __config__ = [("activated", "bool", "Activated", "True"), ("interval", "int", "Check interval in minutes", "360"), ("debug", "bool", "Check for plugin changes when in debug mode", False)] __author_name__ = ("RaNaN") __author_mail__ = ("ranan@pyload.org") @property def debug(self): return self.core.debug and self.getConfig("debug") def setup(self): if self.debug: self.logDebug("Monitoring file changes") self.interval = 4 self.last_check = 0 #timestamp of updatecheck self.old_periodical = self.periodical self.periodical = self.checkChanges self.mtimes = {} #recordes times else: self.interval = self.getConfig("interval") * 60 self.updated = False self.reloaded = True self.info = {"pyload": False, "plugins": False} @threaded def periodical(self): update = self.checkForUpdate() if update: self.info["pyload"] = True else: self.log.info(_("No Updates for pyLoad")) self.checkPlugins() if self.updated and not self.reloaded: self.info["plugins"] = True self.log.info(_("*** Plugins have been updated, please restart pyLoad ***")) elif self.updated and self.reloaded: self.log.info(_("Plugins updated and reloaded")) self.updated = False else: self.log.info(_("No plugin updates available")) @Expose def recheckForUpdates(self): """recheck if updates are available""" self.periodical() def checkForUpdate(self): """checks if an update is available""" try: version_check = getURL("http://get.pyload.org/check/%s/" % self.core.api.getServerVersion()) if version_check == "": return False else: self.log.info(_("*** New pyLoad Version %s available ***") % version_check) self.log.info(_("*** Get it here: http://pyload.org/download ***")) return True except: self.log.warning(_("Not able to connect server for updates")) return False def checkPlugins(self): """ checks for plugins updates""" # plugins were already updated if self.info["plugins"]: return try: updates = getURL("http://get.pyload.org/plugins/check/") except: self.log.warning(_("Not able to connect server for updates")) return False updates = updates.splitlines() reloads = [] vre = re.compile(r'__version__.*=.*("|\')([0-9.]+)') for plugin in updates: path, version = plugin.split(":") prefix, name = path.split("/") if name.endswith(".pyc"): tmp_name = name[:name.find("_")] else: tmp_name = name.replace(".py", "") if prefix.endswith("s"): type = prefix[:-1] else: type = prefix plugins = getattr(self.core.pluginManager, "%sPlugins" % type) if tmp_name in plugins: if float(plugins[tmp_name]["v"]) >= float(version): continue self.log.info(_("New version of %(type)s|%(name)s : %(version).2f") % { "type": type, "name": name, "version": float(version) }) try: content = getURL("http://get.pyload.org/plugins/get/" + path) except Exception, e: self.logWarning(_("Error when updating %s") % name, str(e)) continue m = vre.search(content) if not m or m.group(2) != version: self.logWarning(_("Error when updating %s") % name, _("Version mismatch")) continue f = open(join("userplugins", prefix, name), "wb") f.write(content) f.close() self.updated = True reloads.append((type, name)) self.reloaded = self.core.pluginManager.reloadPlugins(reloads) def checkChanges(self): if self.last_check + self.getConfig("interval") * 60 < time(): self.old_periodical() self.last_check = time() modules = filter( lambda m: m and (m.__name__.startswith("module.plugins.") or m.__name__.startswith("userplugins.")), sys.modules.itervalues()) reloads = [] for m in modules: root, type, name = m.__name__.rsplit(".", 2) id = (type, name) if type in self.core.pluginManager.plugins: mtime = stat(m.__file__.replace(".pyc", ".py")).st_mtime if id not in self.mtimes: self.mtimes[id] = mtime elif self.mtimes[id] < mtime: reloads.append(id) self.mtimes[id] = mtime self.core.pluginManager.reloadPlugins(reloads)