From 89acc0ff595f73956572c8892ccb860c06fba33a Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 4 Jan 2010 20:35:26 +0100 Subject: added hook system --- module/HookManager.py | 73 +++++++++++++++++++++++++++++++ module/plugins/hooks/ContainerDownload.py | 42 ++++++++++++++++++ module/plugins/hooks/Hook.py | 51 +++++++++++++++++++++ module/plugins/hooks/__init__.py | 1 + module/thread_list.py | 23 +++------- pyLoadCore.py | 24 +++------- scripts/Readme.txt | 23 ---------- 7 files changed, 177 insertions(+), 60 deletions(-) create mode 100644 module/HookManager.py create mode 100644 module/plugins/hooks/ContainerDownload.py create mode 100644 module/plugins/hooks/Hook.py create mode 100644 module/plugins/hooks/__init__.py delete mode 100644 scripts/Readme.txt diff --git a/module/HookManager.py b/module/HookManager.py new file mode 100644 index 000000000..a0caae728 --- /dev/null +++ b/module/HookManager.py @@ -0,0 +1,73 @@ +# -*- 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: mkaay + @interface-version: 0.1 +""" +import logging + +from os.path import basename, join +from glob import glob + +from threading import Lock + +class HookManager(): + def __init__(self, core): + self.core = core + self.logger = logging.getLogger("log") + self.plugins = [] + self.lock = Lock() + self.createIndex() + + def createIndex(self): + self.lock.acquire() + pluginFiles = glob(join(self.core.plugin_folder, "hooks", "*.py")) + plugins = [] + for pluginFile in pluginFiles: + pluginName = basename(pluginFile).replace(".py", "") + if pluginName == "Hook" or pluginName == "__init__": + continue + module = __import__("module.plugins.hooks."+pluginName, globals(), locals(), [pluginName], -1) + pluginClass = getattr(module, pluginName) + plugins.append(pluginClass(self.core)) + + self.logger.info("Installed Hook: %s" % pluginName) + self.plugins = plugins + self.lock.release() + + def downloadStarts(self, pyfile): + self.lock.acquire() + for plugin in self.plugins: + plugin.downloadStarts(pyfile) + self.lock.release() + + def downloadFinished(self, pyfile): + self.lock.acquire() + for plugin in self.plugins: + plugin.downloadFinished(pyfile) + self.lock.release() + + def beforeReconnecting(self, ip): + self.lock.acquire() + for plugin in self.plugins: + plugin.beforeReconnecting(ip) + self.lock.release() + + def afterReconnecting(self, ip): + self.lock.acquire() + for plugin in self.plugins: + plugin.afterReconnecting(ip) + self.lock.release() diff --git a/module/plugins/hooks/ContainerDownload.py b/module/plugins/hooks/ContainerDownload.py new file mode 100644 index 000000000..d031cdf69 --- /dev/null +++ b/module/plugins/hooks/ContainerDownload.py @@ -0,0 +1,42 @@ +# -*- 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: mkaay + @interface-version: 0.1 +""" + +from module.plugins.hooks.Hook import Hook + +from os.path import join, abspath + +class ContainerDownload(Hook): + def __init__(self, core): + Hook.__init__(self, core) + props = {} + props['name'] = "ContainerDownload" + props['version'] = "0.1" + props['description'] = """add the downloaded container to current package""" + props['author_name'] = ("mkaay") + props['author_mail'] = ("mkaay@mkaay.de") + self.props = props + + def downloadFinished(self, pyfile): + filename = pyfile.status.filename + if filename.endswith(".dlc") or filename.endswith(".ccf") or filename.endswith(".rsdf"): + self.logger.info("ContainerDownload hook: adding container file") + location = abspath(join(pyfile.folder, filename)) + newFile = self.core.file_list.collector.addLink(location) + self.core.file_list.packager.addFileToPackage(pyfile.package.data["id"], self.core.file_list.collector.popFile(newFile)) diff --git a/module/plugins/hooks/Hook.py b/module/plugins/hooks/Hook.py new file mode 100644 index 000000000..f02432718 --- /dev/null +++ b/module/plugins/hooks/Hook.py @@ -0,0 +1,51 @@ +# -*- 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: mkaay + @interface-version: 0.1 +""" + +import logging + +class Hook(): + def __init__(self, core): + self.logger = logging.getLogger("log") + props = {} + props['name'] = "Hook" + props['version'] = "0.1" + props['description'] = """interface for hook""" + props['author_name'] = ("mkaay") + props['author_mail'] = ("mkaay@mkaay.de") + self.props = props + self.core = core + + def downloadStarts(self, pyfile): + pass + + def downloadFinished(self, pyfile): + pass + + def packageFinished(self, pypack): + """ + not implemented! + """ + pass + + def beforeReconnecting(self, ip): + pass + + def afterReconnecting(self, ip): + pass diff --git a/module/plugins/hooks/__init__.py b/module/plugins/hooks/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/module/plugins/hooks/__init__.py @@ -0,0 +1 @@ + diff --git a/module/thread_list.py b/module/thread_list.py index 5d0bcf53a..55b21093f 100644 --- a/module/thread_list.py +++ b/module/thread_list.py @@ -76,7 +76,7 @@ class Thread_List(object): if pyfile: self.py_downloading.append(pyfile) - self.scripts_download_preparing(pyfile.modul.__name__, pyfile.url) + self.parent.hookManager.downloadStarts(pyfile) if not pyfile.plugin.multi_dl: self.occ_plugins.append(pyfile.modul.__name__) pyfile.active = True @@ -153,7 +153,7 @@ class Thread_List(object): self.list.save() - self.scripts_download_finished(pyfile.modul.__name__, pyfile.url, pyfile.status.filename, pyfile.folder) + self.parent.hookManager.downloadFinished(pyfile) self.lock.release() return True @@ -200,6 +200,8 @@ class Thread_List(object): def reconnect(self): self.parent.logger.info("Start reconnect") + ip = re.match(".*Current IP Address: (.*).*", urllib2.urlopen("http://checkip.dyndns.org/").read()).group(1) + self.parent.hookManager.beforeReconnecting(ip) reconn = subprocess.Popen(self.parent.config['activated']['method'])#, stdout=subprocess.PIPE) reconn.wait() time.sleep(1) @@ -210,23 +212,8 @@ class Thread_List(object): except: ip = "" time.sleep(1) - self.scripts_reconnected(ip) + self.parent.hookManager.afterReconnecting(ip) self.parent.logger.info("Reconnected, new IP: " + ip) - - - def scripts_download_preparing(self, pluginname, url): - for script in self.parent.scripts['download_preparing']: - out = subprocess.Popen([script, pluginname, url], stdout=subprocess.PIPE) - out.wait() - - def scripts_download_finished(self, pluginname, url, filename, location): - map(lambda script: subprocess.Popen([script, pluginname, url, filename, location], stdout=subprocess.PIPE), self.parent.scripts['download_finished']) - - def scripts_package_finished(self, name, location): #@TODO Implement! - map(lambda script: subprocess.Popen([script, name, location], stdout=subprocess.PIPE), self.parent.scripts['download_finished']) - - def scripts_reconnected(self, ip): - map(lambda script: subprocess.Popen([script, ip], stdout=subprocess.PIPE), self.parent.scripts['download_finished']) def stopAllDownloads(self): for pyfile in self.py_downloading: diff --git a/pyLoadCore.py b/pyLoadCore.py index e586ee080..a5521cd70 100755 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -57,7 +57,8 @@ from module.XMLConfigParser import XMLConfigParser from module.file_list import File_List from module.thread_list import Thread_List from module.web.ServerThread import WebServer -from module.CaptchaManager import CaptchaManager +from module.CaptchaManager import CaptchaManager +from module.HookManager import HookManager from xmlrpclib import Binary @@ -106,10 +107,6 @@ class Core(object): self.check_file(self.config['general']['link_file'], _("file for links")) self.check_file(self.config['general']['failed_file'], _("file for failed links")) - script_folders = ['scripts/download_preparing/', 'scripts/download_finished/', 'scripts/package_finished/', 'scripts/reconnected/'] # @TODO: windows save? - - self.check_file(script_folders, _("folders for scripts"), True) - if self.config['ssl']['activated']: self.check_install("OpenSSL", "OpenSSL for secure connection", True) self.check_file(self.config['ssl']['cert'], _("ssl certificate"), False, True) @@ -122,7 +119,7 @@ class Core(object): else: self.init_logger(logging.INFO) # logging level - self.init_scripts() + self.init_hooks() path.append(self.plugin_folder) self.create_plugin_index() @@ -216,19 +213,8 @@ class Core(object): self.logger.addHandler(console) #if console logging self.logger.setLevel(level) - def init_scripts(self): - """ scan directory for scripts to execute""" - f = lambda x: False if x.startswith("#") or x.endswith("~") else True - self.scripts = {} - #@TODO: windows save?! - self.scripts['download_preparing'] = map(lambda x: 'scripts/download_preparing/' + x, filter(f, listdir('scripts/download_preparing'))) - self.scripts['download_finished'] = map(lambda x: 'scripts/download_finished/' + x, filter(f, listdir('scripts/download_finished'))) - self.scripts['package_finished'] = map(lambda x: 'scripts/package_finished/' + x, filter(f, listdir('scripts/package_finished'))) - self.scripts['reconnected'] = map(lambda x: 'scripts/reconnected/' + x, filter(f, listdir('scripts/reconnected'))) - - for script_type, script_name in self.scripts.iteritems(): - if script_name != []: - self.logger.info("Installed %s Scripts: %s" % (script_type, ", ".join(script_name))) + def init_hooks(self): + self.hookManager = HookManager(self) def check_install(self, check_name, legend, python=True, essential=False): """check wether needed tools are installed""" diff --git a/scripts/Readme.txt b/scripts/Readme.txt deleted file mode 100644 index 138b40b9b..000000000 --- a/scripts/Readme.txt +++ /dev/null @@ -1,23 +0,0 @@ - ############################# - ### pyLoad Script Support ### - ############################# - -pyLoad is able to start any kind of scripts at given events. -Simply put your script in a suitable folder and pyLoad will execute it at the given events and pass some arguments to them. - ---> Note: Scripts, which starts with # will be ignored! -For Example: #converter.sh will not be executed. - ---> Note: You have to restart pyload when you change script names or locations. - -Below you see the list of arguments, which are passed to the scripts. - -## Argument list ## - -download_preparing: pluginname url - -download_finished: pluginname url filename filelocation - -package_finshed: packagename packagelocation - -reconnected: newip \ No newline at end of file -- cgit v1.2.3