diff options
Diffstat (limited to 'module/plugins/hooks')
-rw-r--r-- | module/plugins/hooks/Checksum.py | 14 | ||||
-rw-r--r-- | module/plugins/hooks/ExternalScripts.py | 9 | ||||
-rw-r--r-- | module/plugins/hooks/ExtractArchive.py | 52 | ||||
-rw-r--r-- | module/plugins/hooks/HotFolder.py | 3 | ||||
-rw-r--r-- | module/plugins/hooks/IRCInterface.py | 4 | ||||
-rw-r--r-- | module/plugins/hooks/SkipRev.py | 14 | ||||
-rw-r--r-- | module/plugins/hooks/TransmissionRPC.py | 84 | ||||
-rw-r--r-- | module/plugins/hooks/UpdateManager.py | 4 | ||||
-rw-r--r-- | module/plugins/hooks/XFileSharingPro.py | 12 |
9 files changed, 135 insertions, 61 deletions
diff --git a/module/plugins/hooks/Checksum.py b/module/plugins/hooks/Checksum.py index 6ecbfcda2..2a650768e 100644 --- a/module/plugins/hooks/Checksum.py +++ b/module/plugins/hooks/Checksum.py @@ -38,7 +38,7 @@ def compute_checksum(local_file, algorithm): class Checksum(Addon): __name__ = "Checksum" __type__ = "hook" - __version__ = "0.19" + __version__ = "0.22" __status__ = "testing" __config__ = [("check_checksum", "bool" , "Check checksum? (If False only size will be verified)", True ), @@ -114,7 +114,7 @@ class Checksum(Addon): api_size = int(data['size']) file_size = os.path.getsize(local_file) - if api_size is not file_size: + if api_size != file_size: self.log_warning(_("File %s has incorrect size: %d B (%d expected)") % (pyfile.name, file_size, api_size)) self.check_failed(pyfile, local_file, "Incorrect file size") @@ -131,15 +131,15 @@ class Checksum(Addon): for key in self.algorithms: if key in data: - checksum = computeChecksum(local_file, key.replace("-", "").lower()) + checksum = compute_checksum(local_file, key.replace("-", "").lower()) if checksum: - if checksum is data[key].lower(): + if checksum == data[key].lower(): self.log_info(_('File integrity of "%s" verified by %s checksum (%s)') % (pyfile.name, key.upper(), checksum)) break else: self.log_warning(_("%s checksum for file %s does not match (%s != %s)") % - (key.upper(), pyfile.name, checksum, data[key])) + (key.upper(), pyfile.name, checksum, data[key].lower())) self.check_failed(pyfile, local_file, "Checksums do not match") else: self.log_warning(_("Unsupported hashing algorithm"), key.upper()) @@ -160,7 +160,7 @@ class Checksum(Addon): return elif check_action == "nothing": return - pyfile.plugin.fail(reason=msg) + pyfile.plugin.fail(msg=msg) def package_finished(self, pypack): @@ -186,7 +186,7 @@ class Checksum(Addon): local_file = fs_encode(fs_join(download_folder, data['NAME'])) algorithm = self.methods.get(file_type, file_type) - checksum = computeChecksum(local_file, algorithm) + checksum = compute_checksum(local_file, algorithm) if checksum is data['HASH']: self.log_info(_('File integrity of "%s" verified by %s checksum (%s)') % (data['NAME'], algorithm, checksum)) diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py index b7495136a..4ec526d35 100644 --- a/module/plugins/hooks/ExternalScripts.py +++ b/module/plugins/hooks/ExternalScripts.py @@ -3,6 +3,7 @@ import os import subprocess +from module.plugins.internal.Plugin import encode from module.plugins.internal.Addon import Addon, Expose from module.utils import fs_encode, save_join as fs_join @@ -10,7 +11,7 @@ from module.utils import fs_encode, save_join as fs_join class ExternalScripts(Addon): __name__ = "ExternalScripts" __type__ = "hook" - __version__ = "0.46" + __version__ = "0.47" __status__ = "testing" __config__ = [("activated", "bool", "Activated" , True ), @@ -66,7 +67,8 @@ class ExternalScripts(Addon): self.log_debug(e) return - for file in os.listdir(path): + for filename in os.listdir(path): + file = fs_join(path, filename) if not os.path.isfile(file): continue @@ -77,13 +79,14 @@ class ExternalScripts(Addon): self.log_warning(_("Script not executable: [%s] %s") % (name, file)) self.scripts[name].append(file) + self.log_info(_("Registered script: [%s] %s") % (name, file)) @Expose def call(self, script, args=[], lock=False): try: script = os.path.abspath(script) - args = [script] + map(encode, args) + args = [script] + map(lambda arg: encode(arg) if isinstance(arg, basestring) else encode(str(arg)), args) self.log_info(_("EXECUTE [%s] %s") % (os.path.dirname(script), args)) p = subprocess.Popen(args, bufsize=-1) #@NOTE: output goes to pyload diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index eab196160..469f73141 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -51,7 +51,7 @@ except ImportError: pass from module.plugins.internal.Addon import Addon, Expose, threaded -from module.plugins.internal.Plugin import replace_patterns +from module.plugins.internal.Plugin import exists, replace_patterns from module.plugins.internal.Extractor import ArchiveError, CRCError, PasswordError from module.utils import fs_encode, save_join as fs_join, uniqify @@ -107,7 +107,7 @@ class ArchiveQueue(object): class ExtractArchive(Addon): __name__ = "ExtractArchive" __type__ = "hook" - __version__ = "1.49" + __version__ = "1.51" __status__ = "testing" __config__ = [("activated" , "bool" , "Activated" , True ), @@ -115,7 +115,6 @@ class ExtractArchive(Addon): ("overwrite" , "bool" , "Overwrite files" , False ), ("keepbroken" , "bool" , "Try to extract broken archives" , False ), ("repair" , "bool" , "Repair broken archives (RAR required)" , False ), - ("test" , "bool" , "Test archive before extracting" , False ), ("usepasswordfile", "bool" , "Use password file" , True ), ("passwordfile" , "file" , "Password file" , "passwords.txt" ), ("delete" , "bool" , "Delete archive after extraction" , True ), @@ -288,7 +287,7 @@ class ExtractArchive(Addon): if subfolder: out = fs_join(out, pypack.folder) - if not os.path.exists(out): + if not exists(out): os.makedirs(out) matched = False @@ -313,7 +312,7 @@ class ExtractArchive(Addon): for fname, fid, fout in targets: name = os.path.basename(fname) - if not os.path.exists(fname): + if not exists(fname): self.log_debug(name, "File not found") continue @@ -348,7 +347,7 @@ class ExtractArchive(Addon): #: Remove processed file and related multiparts from list files_ids = [(fname, fid, fout) for fname, fid, fout in files_ids \ - if fname not in archive.get_delete_files()] + if fname not in archive.items()] self.log_debug("Extracted files: %s" % new_files) for file in new_files: @@ -356,7 +355,7 @@ class ExtractArchive(Addon): for filename in new_files: file = fs_encode(fs_join(os.path.dirname(archive.filename), filename)) - if not os.path.exists(file): + if not exists(file): self.log_debug("New file %s does not exists" % filename) continue @@ -403,18 +402,10 @@ class ExtractArchive(Addon): passwords = uniqify([password] + self.get_passwords(False)) if self.get_config('usepasswordfile') else [password] for pw in passwords: try: - if self.get_config('test') or self.repair: - pyfile.setCustomStatus(_("archive testing")) - if pw: - self.log_debug("Testing with password: %s" % pw) - pyfile.setProgress(0) - archive.verify(pw) - pyfile.setProgress(100) - else: - archive.check(pw) - - self.add_password(pw) - break + pyfile.setCustomStatus(_("archive testing")) + pyfile.setProgress(0) + archive.verify(pw) + pyfile.setProgress(100) except PasswordError: if not encrypted: @@ -425,9 +416,11 @@ class ExtractArchive(Addon): self.log_debug(name, e) self.log_info(name, _("CRC Error")) - if self.repair: - self.log_warning(name, _("Repairing...")) + if not self.repair: + raise CRCError("Archive damaged") + else: + self.log_warning(name, _("Repairing...")) pyfile.setCustomStatus(_("archive repairing")) pyfile.setProgress(0) repaired = archive.repair() @@ -436,15 +429,18 @@ class ExtractArchive(Addon): if not repaired and not self.get_config('keepbroken'): raise CRCError("Archive damaged") - self.add_password(pw) - break - - raise CRCError("Archive damaged") + else: + self.add_password(pw) + break except ArchiveError, e: raise ArchiveError(e) - pyfile.setCustomStatus(_("extracting")) + else: + self.add_password(pw) + break + + pyfile.setCustomStatus(_("archive extracting")) pyfile.setProgress(0) if not encrypted or not self.get_config('usepasswordfile'): @@ -467,7 +463,7 @@ class ExtractArchive(Addon): pyfile.setProgress(100) pyfile.setStatus("processing") - delfiles = archive.get_delete_files() + delfiles = archive.items() self.log_debug("Would delete: " + ", ".join(delfiles)) if self.get_config('delete'): @@ -476,7 +472,7 @@ class ExtractArchive(Addon): deltotrash = self.get_config('deltotrash') for f in delfiles: file = fs_encode(f) - if not os.path.exists(file): + if not exists(file): continue if not deltotrash: diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py index 84db4db17..5a65146b9 100644 --- a/module/plugins/hooks/HotFolder.py +++ b/module/plugins/hooks/HotFolder.py @@ -14,7 +14,7 @@ from module.utils import fs_encode, save_join as fs_join class HotFolder(Addon): __name__ = "HotFolder" __type__ = "hook" - __version__ = "0.16" + __version__ = "0.17" __status__ = "testing" __config__ = [("folder" , "str" , "Folder to observe" , "container"), @@ -29,6 +29,7 @@ class HotFolder(Addon): def init(self): self.interval = 30 + self.init_periodical() def periodical(self): diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py index 08b1bad0c..5d8928a57 100644 --- a/module/plugins/hooks/IRCInterface.py +++ b/module/plugins/hooks/IRCInterface.py @@ -18,7 +18,7 @@ from module.utils import formatSize class IRCInterface(Thread, Addon): __name__ = "IRCInterface" __type__ = "hook" - __version__ = "0.15" + __version__ = "0.16" __status__ = "testing" __config__ = [("host" , "str" , "IRC-Server Address" , "Enter your server here!"), @@ -40,7 +40,7 @@ class IRCInterface(Thread, Addon): def __init__(self, core, manager): Thread.__init__(self) Addon.__init__(self, core, manager) - self.set_daemon(True) + self.setDaemon(True) def activate(self): diff --git a/module/plugins/hooks/SkipRev.py b/module/plugins/hooks/SkipRev.py index a1ddc3094..9f54218d6 100644 --- a/module/plugins/hooks/SkipRev.py +++ b/module/plugins/hooks/SkipRev.py @@ -13,7 +13,7 @@ from module.plugins.internal.Addon import Addon class SkipRev(Addon): __name__ = "SkipRev" __type__ = "hook" - __version__ = "0.33" + __version__ = "0.34" __status__ = "testing" __config__ = [("mode" , "Auto;Manual", "Choose recovery archives to skip" , "Auto"), @@ -24,13 +24,6 @@ class SkipRev(Addon): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - @staticmethod - def _init(self): - self.pyfile.plugin._init() - if self.pyfile.hasStatus("skipped"): - self.skip(self.pyfile.statusname or self.pyfile.pluginname) - - def _name(self, pyfile): return pyfile.pluginclass.get_info(pyfile.url)['name'] @@ -68,11 +61,6 @@ class SkipRev(Addon): pyfile.setCustomStatus("SkipRev", "skipped") - if not hasattr(pyfile.plugin, "_init"): - #: Work-around: inject status checker inside the preprocessing routine of the plugin - pyfile.plugin._init = pyfile.plugin.init - pyfile.plugin.init = MethodType(self._init, pyfile.plugin) - def download_failed(self, pyfile): #: Check if pyfile is still "failed", maybe might has been restarted in meantime diff --git a/module/plugins/hooks/TransmissionRPC.py b/module/plugins/hooks/TransmissionRPC.py new file mode 100644 index 000000000..715f82edb --- /dev/null +++ b/module/plugins/hooks/TransmissionRPC.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +import random +import re + +import pycurl + +from module.common.json_layer import json_loads, json_dumps +from module.network.HTTPRequest import BadHeader +from module.network.RequestFactory import getRequest as get_request +from module.plugins.internal.Addon import Addon + + +class TransmissionRPC(Addon): + __name__ = "TransmissionRPC" + __type__ = "hook" + __version__ = "0.12" + __status__ = "testing" + + __pattern__ = r"https?://.+\.torrent|magnet:\?.+" + __config__ = [("rpc_url", "str", "Transmission RPC URL", "http://127.0.0.1:9091/transmission/rpc")] + + __description__ = """Send torrent and magnet URLs to Transmission Bittorent daemon via RPC""" + __license__ = "GPLv3" + __authors__ = [("GammaC0de", None)] + + + def init(self): + self.event_map = {'linksAdded': "links_added"} + + + def links_added(self, links, pid): + pattern = re.compile(self.__pattern__) + urls = [link for link in links if pattern.match(link)] + + for url in urls: + self.log_debug("Sending link: %s" % url) + self.send_to_transmission(url) + links.remove(url) + + + def send_to_transmission(self, url): + transmission_rpc_url = self.get_config('rpc_url') + client_request_id = self.__name__ + "".join(random.choice('0123456789ABCDEF') for _i in xrange(4)) + req = get_request() + + try: + response = self.load(transmission_rpc_url, + post=json_dumps({'arguments': {'filename': url}, + 'method' : 'torrent-add', + 'tag' : client_request_id}), + req=req) + + except BadHeader, e: + if e.code == 409: + headers = dict(re.findall(r"(?P<name>.+?): (?P<value>.+?)\r?\n", req.header)) + session_id = headers['X-Transmission-Session-Id'] + req.c.setopt(pycurl.HTTPHEADER, ["X-Transmission-Session-Id: %s" % session_id]) + try: + response = self.load(transmission_rpc_url, + post=json_dumps({'arguments': {'filename': url}, + 'method' : 'torrent-add', + 'tag' : client_request_id}), + req=req) + + except Exception, e: + self.log_error(e) + return + + else: + self.log_error(e) + return + + except Exception, e: + self.log_error(e) + return + + try: + res = json_loads(response) + if "result" in res: + self.log_debug("Result: %s" % res['result']) + + except Exception, e: + self.log_error(e) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 117da0633..fb9e28b5d 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -17,7 +17,7 @@ from module.utils import fs_encode, save_join as fs_join class UpdateManager(Addon): __name__ = "UpdateManager" __type__ = "hook" - __version__ = "0.55" + __version__ = "0.56" __status__ = "testing" __config__ = [("activated" , "bool", "Activated" , True ), @@ -268,7 +268,7 @@ class UpdateManager(Addon): raise Exception(_("Version mismatch")) except Exception, e: - self.log_error(_("Error updating plugin: %s") % filename, e) + self.log_error(_("Error updating plugin: [%s] %s") % (type, name), e) if self.pyload.debug: traceback.print_exc() diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py index 7567a31a3..9b9c7f0ad 100644 --- a/module/plugins/hooks/XFileSharingPro.py +++ b/module/plugins/hooks/XFileSharingPro.py @@ -29,18 +29,20 @@ class XFileSharingPro(Hook): r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:user|folder)s?/\w+')} HOSTER_BUILTIN = [#WORKING HOSTERS: - "ani-stream.com", "backin.net", "cloudsix.me", "eyesfile.ca", "file4safe.com", - "fileband.com", "filedwon.com", "fileparadox.in", "filevice.com", - "hostingbulk.com", "junkyvideo.com", "linestorage.com", "ravishare.com", + "ani-stream.com", "backin.net", "cloudsix.me", "eyesfile.ca", + "file4safe.com", "fileband.com", "filedwon.com", "fileparadox.in", + "filevice.com", "hostingbulk.com", "junkyvideo.com", "ravishare.com", "ryushare.com", "salefiles.com", "sendmyway.com", "sharebeast.com", - "sharesix.com", "thefile.me", "verzend.be", "worldbytez.com", "xvidstage.com", + "sharesix.com", "thefile.me", "verzend.be", "worldbytez.com", + "xvidstage.com", #: NOT TESTED: "101shared.com", "4upfiles.com", "filemaze.ws", "filenuke.com", "linkzhost.com", "mightyupload.com", "rockdizfile.com", "sharerepo.com", "shareswift.com", "uploadbaz.com", "uploadc.com", "vidbull.com", "zalaa.com", "zomgupload.com", #: NOT WORKING: - "amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", "laoupload.com", "rd-fs.com"] + "amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", + "laoupload.com", "rd-fs.com"] CRYPTER_BUILTIN = ["junocloud.me", "rapidfileshare.net"] |