# -*- coding: utf-8 -*- import os import subprocess from module.plugins.internal.Addon import Addon, Expose from module.utils import fs_encode, save_join as fs_join class ExternalScripts(Addon): __name__ = "ExternalScripts" __type__ = "hook" __version__ = "0.45" __status__ = "testing" __config__ = [("activated", "bool", "Activated" , True ), ("lock" , "bool", "Wait script ending", False)] __description__ = """Run external scripts""" __license__ = "GPLv3" __authors__ = [("mkaay" , "mkaay@mkaay.de" ), ("RaNaN" , "ranan@pyload.org" ), ("spoob" , "spoob@pyload.org" ), ("Walter Purcaro", "vuolter@gmail.com")] def init(self): self.info['oldip'] = None self.scripts = {} self.event_list = ["archive_extract_failed", "archive_extracted" , "package_extract_failed", "package_extracted" , "all_archives_extracted", "all_archives_processed"] self.event_map = {'allDownloadsFinished' : "all_downloads_finished" , 'allDownloadsProcessed': "all_downloads_processed", 'packageDeleted' : "package_deleted" } folders = ["pyload_start", "pyload_restart", "pyload_stop", "before_reconnect", "after_reconnect", "download_preparing", "download_failed", "download_finished", "archive_extract_failed", "archive_extracted", "package_finished", "package_deleted", "package_extract_failed", "package_extracted", "all_downloads_processed", "all_downloads_finished", #@TODO: Invert `all_downloads_processed`, `all_downloads_finished` order in 0.4.10 "all_archives_extracted", "all_archives_processed"] for folder in folders: self.scripts[folder] = [] for dir in (pypath, ''): self.init_plugin_type(folder, os.path.join(dir, 'scripts', folder)) for script_type, names in self.scripts.items(): if names: self.log_info(_("Installed scripts for: ") + script_type, ", ".join(map(os.path.basename, names))) self.pyload_start() def init_plugin_type(self, name, dir): if not os.path.isdir(dir): try: os.makedirs(dir) except OSError, e: self.log_debug(e) return for filename in os.listdir(dir): file = fs_join(dir, filename) if not os.path.isfile(file): continue if filename[0] in ("#", "_") or filename.endswith("~") or filename.endswith(".swp"): continue if not os.access(file, os.X_OK): self.log_warning(_("Script not executable: %s/%s" % (name, filename)) self.scripts[name].append(file) @Expose def call(self, script, args=[], lock=False): try: args = [script] + map(encode, 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") % os.path.abspath(script), e or _("Unknown error")) def pyload_start(self): lock = self.get_config('lock') for script in self.scripts['pyload_start']: self.call(script, lock=lock) def exit(self): lock = self.get_config('lock') for script in self.scripts['pyload_restart' if self.pyload.do_restart else 'pyload_stop']: self.call(script, lock=True) def before_reconnect(self, ip): lock = self.get_config('lock') for script in self.scripts['before_reconnect']: args = [ip] self.call(script, args, lock) self.info['oldip'] = ip def after_reconnect(self, ip): lock = self.get_config('lock') for script in self.scripts['after_reconnect']: args = [ip, self.info['oldip']] #@TODO: Use built-in oldip in 0.4.10 self.call(script, args, lock) def download_preparing(self, pyfile): lock = self.get_config('lock') for script in self.scripts['download_preparing']: args = [pyfile.id, pyfile.name, None, pyfile.pluginname, pyfile.url] self.call(script, args, lock) def download_failed(self, pyfile): lock = self.get_config('lock') if self.pyload.config.get("general", "folder_per_package"): download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pyfile.package().folder) else: download_folder = self.pyload.config.get("general", "download_folder") for script in self.scripts['download_failed']: file = fs_join(download_folder, pyfile.name) args = [script, pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url] self.call(script, args, lock) def download_finished(self, pyfile): lock = self.get_config('lock') if self.pyload.config.get("general", "folder_per_package"): download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pyfile.package().folder) else: download_folder = self.pyload.config.get("general", "download_folder") for script in self.scripts['download_finished']: file = fs_join(download_folder, pyfile.name) args = [pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url] self.call(script, args, lock) def archive_extract_failed(self, pyfile, archive): lock = self.get_config('lock') for script in self.scripts['archive_extract_failed']: args = [pyfile.id, pyfile.name, archive.filename, archive.out, archive.files] self.call(script, args, lock) def archive_extracted(self, pyfile, archive): lock = self.get_config('lock') for script in self.scripts['archive_extracted']: args = [script, pyfile.id, pyfile.name, archive.filename, archive.out, archive.files] self.call(script, args, lock) def package_finished(self, pypack): lock = self.get_config('lock') if self.pyload.config.get("general", "folder_per_package"): download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder) else: download_folder = self.pyload.config.get("general", "download_folder") for script in self.scripts['package_finished']: args = [pypack.id, pypack.name, download_folder, pypack.password] self.call(script, args, lock) def package_deleted(self, pid): lock = self.get_config('lock') pack = self.pyload.api.getPackageInfo(pid) if self.pyload.config.get("general", "folder_per_package"): download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pack.folder) else: download_folder = self.pyload.config.get("general", "download_folder") for script in self.scripts['package_deleted']: args = [pack.id, pack.name, download_folder, pack.password] self.call(script, args, lock) def package_extract_failed(self, pypack): lock = self.get_config('lock') if self.pyload.config.get("general", "folder_per_package"): download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder) else: download_folder = self.pyload.config.get("general", "download_folder") for script in self.scripts['package_extract_failed']: args = [pypack.id, pypack.name, download_folder, pypack.password] self.call(script, args, lock) def package_extracted(self, pypack): lock = self.get_config('lock') if self.pyload.config.get("general", "folder_per_package"): download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder) else: download_folder = self.pyload.config.get("general", "download_folder") for script in self.scripts['package_extracted']: args = [pypack.id, pypack.name, download_folder] self.call(script, args, lock) def all_downloads_finished(self): lock = self.get_config('lock') for script in self.scripts['all_downloads_finished']: self.call(script, lock=lock) def all_downloads_processed(self): lock = self.get_config('lock') for script in self.scripts['all_downloads_processed']: self.call(script, lock=lock) def all_archives_extracted(self): lock = self.get_config('lock') for script in self.scripts['all_archives_extracted']: self.call(script, lock=lock) def all_archives_processed(self): lock = self.get_config('lock') for script in self.scripts['all_archives_processed']: self.call(script, lock=lock)