summaryrefslogtreecommitdiffstats
path: root/module/plugins/hooks/ExternalScripts.py
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/hooks/ExternalScripts.py')
-rw-r--r--module/plugins/hooks/ExternalScripts.py197
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")