diff options
Diffstat (limited to 'module/plugins/hooks/ExternalScripts.py')
-rw-r--r-- | module/plugins/hooks/ExternalScripts.py | 197 |
1 files changed, 107 insertions, 90 deletions
diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py index 99427dfab..3f4fa74db 100644 --- a/module/plugins/hooks/ExternalScripts.py +++ b/module/plugins/hooks/ExternalScripts.py @@ -4,17 +4,17 @@ import os import subprocess from module.plugins.internal.Addon import Addon, Expose -from module.plugins.internal.utils import encode, fs_join +from module.plugins.internal.misc import encode class ExternalScripts(Addon): __name__ = "ExternalScripts" __type__ = "hook" - __version__ = "0.55" + __version__ = "0.60" __status__ = "testing" - __config__ = [("activated", "bool", "Activated" , True ), - ("lock" , "bool", "Wait for script to terminate", False)] + __config__ = [("activated", "bool", "Activated" , True ), + ("unlock" , "bool", "Execute script concurrently", False)] __description__ = """Run external scripts""" __license__ = "GPLv3" @@ -32,8 +32,14 @@ class ExternalScripts(Addon): 'package_extract_failed': "package_extract_failed" , 'package_extracted' : "package_extracted" , 'all_archives_extracted': "all_archives_extracted" , - 'all_archives_processed': "all_archives_processed" } + 'all_archives_processed': "all_archives_processed" , + 'pyload_updated' : "pyload_updated" } + self.periodical.start(60) + self.pyload_start() + + + def make_folders(self): folders = ["pyload_start", "pyload_restart", "pyload_stop", "before_reconnect", "after_reconnect", "download_preparing", "download_failed", "download_finished", @@ -43,176 +49,187 @@ class ExternalScripts(Addon): "all_archives_extracted", "all_archives_processed"] for folder in folders: - path = os.path.join("scripts", folder) - self.init_folder(folder, path) + dir = os.path.join("scripts", folder) - for folder, scripts in self.scripts.items(): - if scripts: - self.log_info(_("Installed scripts in folder `%s`: %s") - % (folder, ", ".join(scripts))) + if os.path.isdir(dir): + continue - self.pyload_start() + try: + os.makedirs(dir) + except OSError, e: + self.log_debug(e, trace=True) - def init_folder(self, name, path): - self.scripts[name] = [] - if not os.path.isdir(path): - try: - os.makedirs(path) + def periodical_task(self): + self.make_folders() - except OSError, e: - self.log_debug(e) - return + folders = [entry for entry in os.listdir("scripts") \ + if os.path.isdir(os.path.join("scripts", entry))] - for filename in os.listdir(path): - file = fs_join(path, filename) - if not os.path.isfile(file): - continue + for folder in folders: + self.scripts[folder] = [] - if file[0] in ("#", "_") or file.endswith("~") or file.endswith(".swp"): - continue + dirname = os.path.join("scripts", folder) + + for entry in os.listdir(dirname): + file = os.path.join(dirname, entry) + + if not os.path.isfile(file): + continue + + if file[0] in ("#", "_") or file.endswith("~") or file.endswith(".swp"): + continue + + if not os.access(file, os.X_OK): + self.log_warning(_("Script `%s` is not executable") % entry) - if not os.access(file, os.X_OK): - self.log_warning(_("Script not executable: [%s] %s") % (name, file)) + self.scripts[folder].append(file) - self.scripts[name].append(file) - self.log_info(_("Registered script: [%s] %s") % (name, file)) + script_names = map(os.path.basename, self.scripts[folder]) + self.log_info(_("Activated %s scripts: %s") + % (folder, ", ".join(script_names) or None)) + + + def call_cmd(self, command, *args, **kwargs): + call = [command] + args + self.log_debug("EXECUTE " + " ".join(call)) + + call = map(encode, call) + p = subprocess.Popen(call, bufsize=-1) #@NOTE: output goes to pyload + + return p @Expose - def call(self, script, args=[], lock=None): - if lock is None: - lock = self.get_config('lock') + def call_script(self, folder, *args, **kwargs): + scripts = self.scripts.get(folder) + + if folder not in scripts: + self.log_debug("Folder `%s` not found" % folder) + return + + scripts = self.scripts.get(folder) + + if not scripts: + self.log_debug("No script found under folder `%s`" % folder) + return + + self.log_info(_("Executing %s scripts...") % folder) - try: - script = os.path.abspath(script) - args = [script] + map(lambda arg: encode(arg) if isinstance(arg, basestring) else encode(str(arg)), args) + for file in scripts: + try: + p = self.call_cmd(file, args) - self.log_info(_("EXECUTE [%s] %s") % (os.path.dirname(script), args)) - p = subprocess.Popen(args, bufsize=-1) #@NOTE: output goes to pyload - if lock: - p.communicate() + except Exception, e: + self.log_error(_("Runtime error: %s") % file, + e or _("Unknown error")) - except Exception, e: - self.log_error(_("Runtime error: %s") % script, - e or _("Unknown error")) + else: + if kwargs.get('lock') or not self.config.get('unlock'): + p.communicate() - def _call(self, folder, args=[], lock=None): - for script in self.scripts[folder]: - self.call(script, args, lock) + def pyload_updated(self, etag): + self.call_script("pyload_updated", etag) def pyload_start(self): - self._call('pyload_start') + self.call_script('pyload_start') def exit(self): - folder = "pyload_restart" if self.pyload.do_restart else "pyload_stop" - self._call(folder, lock=True) + event = "restart" if self.pyload.do_restart else "stop" + self.call_script("pyload_" + event, lock=True) def before_reconnect(self, ip): - args = [ip] - self._call("before_reconnect", args) + self.call_script("before_reconnect", ip) def after_reconnect(self, ip, oldip): - args = [ip, oldip] - self._call("after_reconnect", args) + self.call_script("after_reconnect", ip, oldip) def download_preparing(self, pyfile): args = [pyfile.id, pyfile.name, None, pyfile.pluginname, pyfile.url] - self._call("download_preparing", args) + self.call_script("download_preparing", *args) def download_failed(self, pyfile): - if self.pyload.config.get("general", "folder_per_package"): - dl_folder = fs_join(self.pyload.config.get("general", "download_folder"), pyfile.package().folder) - else: - dl_folder = self.pyload.config.get("general", "download_folder") - - file = fs_join(dl_folder, pyfile.name) + file = pyfile.plugin.last_download args = [pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url] - self._call("download_failed", args) + self.call_script("download_failed", *args) def download_finished(self, pyfile): - if self.pyload.config.get("general", "folder_per_package"): - dl_folder = fs_join(self.pyload.config.get("general", "download_folder"), pyfile.package().folder) - else: - dl_folder = self.pyload.config.get("general", "download_folder") - - file = fs_join(dl_folder, pyfile.name) + file = pyfile.plugin.last_download args = [pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url] - self._call("download_finished", args) + self.call_script("download_finished", *args) def archive_extract_failed(self, pyfile, archive): args = [pyfile.id, pyfile.name, archive.filename, archive.out, archive.files] - self._call("archive_extract_failed", args) + self.call_script("archive_extract_failed", *args) def archive_extracted(self, pyfile, archive): args = [pyfile.id, pyfile.name, archive.filename, archive.out, archive.files] - self._call("archive_extracted", args) + self.call_script("archive_extracted", *args) def package_finished(self, pypack): + dl_folder = self.pyload.config.get("general", "download_folder") + if self.pyload.config.get("general", "folder_per_package"): - dl_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder) - else: - dl_folder = self.pyload.config.get("general", "download_folder") + dl_folder = os.path.join(dl_folder, pypack.folder) args = [pypack.id, pypack.name, dl_folder, pypack.password] - self._call("package_finished", args) + self.call_script("package_finished", *args) def package_deleted(self, pid): + dl_folder = self.pyload.config.get("general", "download_folder") pdata = self.pyload.api.getPackageInfo(pid) if self.pyload.config.get("general", "folder_per_package"): - dl_folder = fs_join(self.pyload.config.get("general", "download_folder"), pdata.folder) - else: - dl_folder = self.pyload.config.get("general", "download_folder") + dl_folder = os.path.join(dl_folder, pdata.folder) args = [pdata.pid, pdata.name, dl_folder, pdata.password] - self._call("package_deleted", args) + self.call_script("package_deleted", *args) def package_extract_failed(self, pypack): + dl_folder = self.pyload.config.get("general", "download_folder") + if self.pyload.config.get("general", "folder_per_package"): - dl_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder) - else: - dl_folder = self.pyload.config.get("general", "download_folder") + dl_folder = os.path.join(dl_folder, pypack.folder) args = [pypack.id, pypack.name, dl_folder, pypack.password] - self._call("package_extract_failed", args) + self.call_script("package_extract_failed", *args) def package_extracted(self, pypack): + dl_folder = self.pyload.config.get("general", "download_folder") + if self.pyload.config.get("general", "folder_per_package"): - dl_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder) - else: - dl_folder = self.pyload.config.get("general", "download_folder") + dl_folder = os.path.join(dl_folder, pypack.folder) args = [pypack.id, pypack.name, dl_folder] - self._call("package_extracted", args) + self.call_script("package_extracted", *args) def all_downloads_finished(self): - self._call("all_downloads_finished") + self.call_script("all_downloads_finished") def all_downloads_processed(self): - self._call("all_downloads_processed") + self.call_script("all_downloads_processed") def all_archives_extracted(self): - self._call("all_archives_extracted") + self.call_script("all_archives_extracted") def all_archives_processed(self): - self._call("all_archives_processed") + self.call_script("all_archives_processed") |