diff options
Diffstat (limited to 'module/plugins/hooks')
43 files changed, 0 insertions, 4133 deletions
diff --git a/module/plugins/hooks/AlldebridCom.py b/module/plugins/hooks/AlldebridCom.py deleted file mode 100644 index 2d3c8aad7..000000000 --- a/module/plugins/hooks/AlldebridCom.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class AlldebridCom(MultiHoster): - __name__ = "AlldebridCom" - __type__ = "hook" - __version__ = "0.13" - - __config__ = [("https", "bool", "Enable HTTPS", False), - ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to stanard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Alldebrid.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Andy Voigt", "spamsales@online.de")] - - - def getHoster(self): - https = "https" if self.getConfig("https") else "http" - page = getURL(https + "://www.alldebrid.com/api.php", get={'action': "get_host"}).replace("\"", "").strip() - - return [x.strip() for x in page.split(",") if x.strip()] diff --git a/module/plugins/hooks/BypassCaptcha.py b/module/plugins/hooks/BypassCaptcha.py deleted file mode 100644 index 7e1ea6424..000000000 --- a/module/plugins/hooks/BypassCaptcha.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- - -from pycurl import FORM_FILE, LOW_SPEED_TIME -from thread import start_new_thread - -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook - - -class BypassCaptchaException(Exception): - - def __init__(self, err): - self.err = err - - - def getCode(self): - return self.err - - - def __str__(self): - return "<BypassCaptchaException %s>" % self.err - - - def __repr__(self): - return "<BypassCaptchaException %s>" % self.err - - -class BypassCaptcha(Hook): - __name__ = "BypassCaptcha" - __type__ = "hook" - __version__ = "0.04" - - __config__ = [("force", "bool", "Force BC even if client is connected", False), - ("passkey", "password", "Passkey", "")] - - __description__ = """Send captchas to BypassCaptcha.com""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org"), - ("Godofdream", "soilfcition@gmail.com"), - ("zoidberg", "zoidberg@mujmail.cz")] - - - PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32" - - SUBMIT_URL = "http://bypasscaptcha.com/upload.php" - RESPOND_URL = "http://bypasscaptcha.com/check_value.php" - GETCREDITS_URL = "http://bypasscaptcha.com/ex_left.php" - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - - def getCredits(self): - res = getURL(self.GETCREDITS_URL, post={"key": self.getConfig("passkey")}) - - data = dict([x.split(' ', 1) for x in res.splitlines()]) - return int(data['Left']) - - - def submit(self, captcha, captchaType="file", match=None): - req = getRequest() - - #raise timeout threshold - req.c.setopt(LOW_SPEED_TIME, 80) - - try: - res = req.load(self.SUBMIT_URL, - post={'vendor_key': self.PYLOAD_KEY, - 'key': self.getConfig("passkey"), - 'gen_task_id': "1", - 'file': (FORM_FILE, captcha)}, - multipart=True) - finally: - req.close() - - data = dict([x.split(' ', 1) for x in res.splitlines()]) - if not data or "Value" not in data: - raise BypassCaptchaException(res) - - result = data['Value'] - ticket = data['TaskId'] - self.logDebug("Result %s : %s" % (ticket, result)) - - return ticket, result - - - def respond(self, ticket, success): - try: - res = getURL(self.RESPOND_URL, post={"task_id": ticket, "key": self.getConfig("passkey"), - "cv": 1 if success else 0}) - except BadHeader, e: - self.logError(_("Could not send response"), e) - - - def newCaptchaTask(self, task): - if "service" in task.data: - return False - - if not task.isTextual(): - return False - - if not self.getConfig("passkey"): - return False - - if self.core.isClientConnected() and not self.getConfig("force"): - return False - - if self.getCredits() > 0: - task.handler.append(self) - task.data['service'] = self.__name__ - task.setWaiting(100) - start_new_thread(self.processCaptcha, (task,)) - - else: - self.logInfo(_("Your %s account has not enough credits") % self.__name__) - - - def captchaCorrect(self, task): - if task.data['service'] == self.__name__ and "ticket" in task.data: - self.respond(task.data['ticket'], True) - - - def captchaInvalid(self, task): - if task.data['service'] == self.__name__ and "ticket" in task.data: - self.respond(task.data['ticket'], False) - - - def processCaptcha(self, task): - c = task.captchaFile - try: - ticket, result = self.submit(c) - except BypassCaptchaException, e: - task.error = e.getCode() - return - - task.data['ticket'] = ticket - task.setResult(result) diff --git a/module/plugins/hooks/Captcha9kw.py b/module/plugins/hooks/Captcha9kw.py deleted file mode 100755 index ead8aec9a..000000000 --- a/module/plugins/hooks/Captcha9kw.py +++ /dev/null @@ -1,256 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import re - -from base64 import b64encode -from thread import start_new_thread -from time import sleep - -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getURL - -from module.plugins.Hook import Hook - - -class Captcha9kw(Hook): - __name__ = "Captcha9kw" - __type__ = "hook" - __version__ = "0.25" - - __config__ = [("activated" , "bool" , "Activated" , True ), - ("ssl" , "bool" , "Use HTTPS" , True ), - ("force" , "bool" , "Force captcha resolving even if client is connected" , True ), - ("confirm" , "bool" , "Confirm Captcha (cost +6 credits)" , False ), - ("captchaperhour", "int" , "Captcha per hour" , "9999" ), - ("captchapermin" , "int" , "Captcha per minute" , "9999" ), - ("prio" , "int" , "Priority (max 10)(cost +0 -> +10 credits)" , "0" ), - ("queue" , "int" , "Max. Queue (max 999)" , "50" ), - ("hoster_options", "string" , "Hoster options (format: pluginname:prio=1:selfsolfe=1:confirm=1:timeout=900|...)", "ShareonlineBiz:prio=0:timeout=999 | UploadedTo:prio=0:timeout=999"), - ("selfsolve" , "bool" , "Selfsolve (manually solve your captcha in your 9kw client if active)" , "0" ), - ("passkey" , "password", "API key" , "" ), - ("timeout" , "int" , "Timeout in seconds (min 60, max 3999)" , "900" )] - - __description__ = """Send captchas to 9kw.eu""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org"), - ("Walter Purcaro", "vuolter@gmail.com")] - - - API_URL = "http://www.9kw.eu/index.cgi" - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - if self.getConfig("ssl"): - self.API_URL = self.API_URL.replace("http://", "https://") - - - def getCredits(self): - res = getURL(self.API_URL, - get={'apikey': self.getConfig("passkey"), - 'pyload': "1", - 'source': "pyload", - 'action': "usercaptchaguthaben"}) - - if res.isdigit(): - self.logInfo(_("%s credits left") % res) - credits = self.info['credits'] = int(res) - return credits - else: - self.logError(res) - return 0 - - - def _processCaptcha(self, task): - try: - with open(task.captchaFile, 'rb') as f: - data = f.read() - - except IOError, e: - self.logError(e) - return - - data = b64encode(data) - mouse = 1 if task.isPositional() else 0 - pluginname = re.search(r'_([^_]*)_\d+.\w+', task.captchaFile).group(1) - - option = {'min' : 2, - 'max' : 50, - 'phrase' : 0, - 'numeric' : 0, - 'case_sensitive': 0, - 'math' : 0, - 'prio' : min(max(self.getConfig("prio"), 0), 10), - 'confirm' : self.getConfig("confirm"), - 'timeout' : min(max(self.getConfig("timeout"), 300), 3999), - 'selfsolve' : self.getConfig("selfsolve"), - 'cph' : self.getConfig("captchaperhour"), - 'cpm' : self.getConfig("captchapermin")} - - for opt in str(self.getConfig("hoster_options").split('|')): - - details = map(str.strip, opt.split(':')) - - if not details or details[0].lower() != pluginname.lower(): - continue - - for d in details: - hosteroption = d.split("=") - - if len(hosteroption) < 2 or not hosteroption[1].isdigit(): - continue - - o = hosteroption[0].lower() - if o in option: - option[o] = hosteroption[1] - - break - - post_data = {'apikey' : self.getConfig("passkey"), - 'prio' : option['prio'], - 'confirm' : option['confirm'], - 'maxtimeout' : option['timeout'], - 'selfsolve' : option['selfsolve'], - 'captchaperhour': option['cph'], - 'captchapermin' : option['cpm'], - 'case-sensitive': option['case_sensitive'], - 'min_len' : option['min'], - 'max_len' : option['max'], - 'phrase' : option['phrase'], - 'numeric' : option['numeric'], - 'math' : option['math'], - 'oldsource' : pluginname, - 'pyload' : "1", - 'source' : "pyload", - 'base64' : "1", - 'mouse' : mouse, - 'file-upload-01': data, - 'action' : "usercaptchaupload"} - - for _i in xrange(5): - try: - res = getURL(self.API_URL, post=post_data) - except BadHeader, e: - sleep(3) - else: - if res and res.isdigit(): - break - else: - self.logError(_("Bad upload: %s") % res) - return - - self.logDebug(_("NewCaptchaID ticket: %s") % res, task.captchaFile) - - task.data["ticket"] = res - - for _i in xrange(int(self.getConfig("timeout") / 5)): - result = getURL(self.API_URL, - get={'apikey': self.getConfig("passkey"), - 'id' : res, - 'pyload': "1", - 'info' : "1", - 'source': "pyload", - 'action': "usercaptchacorrectdata"}) - - if not result or result == "NO DATA": - sleep(5) - else: - break - else: - self.logDebug("Could not send request: %s" % res) - result = None - - self.logInfo(_("Captcha result for ticket %s: %s") % (res, result)) - - task.setResult(result) - - - def newCaptchaTask(self, task): - if not task.isTextual() and not task.isPositional(): - return - - if not self.getConfig("passkey"): - return - - if self.core.isClientConnected() and not self.getConfig("force"): - return - - credits = self.getCredits() - - if not credits: - self.logError(_("Your captcha 9kw.eu account has not enough credits")) - return - - queue = min(self.getConfig("queue"), 999) - timeout = min(max(self.getConfig("timeout"), 300), 3999) - pluginname = re.search(r'_([^_]*)_\d+.\w+', task.captchaFile).group(1) - - for _i in xrange(5): - servercheck = getURL("http://www.9kw.eu/grafik/servercheck.txt") - if queue < re.search(r'queue=(\d+)', servercheck).group(1): - break - - sleep(10) - else: - self.fail(_("Too many captchas in queue")) - - for opt in str(self.getConfig("hoster_options").split('|')): - details = map(str.strip, opt.split(':')) - - if not details or details[0].lower() != pluginname.lower(): - continue - - for d in details: - hosteroption = d.split("=") - - if (len(hosteroption) > 1 - and hosteroption[0].lower() == 'timeout' - and hosteroption[1].isdigit()): - timeout = int(hosteroption[1]) - - break - - task.handler.append(self) - - task.setWaiting(timeout) - - self._processCaptcha(task) - - - def _captchaResponse(self, task, correct): - type = "correct" if correct else "refund" - - if 'ticket' not in task.data: - self.logDebug("No CaptchaID for %s request (task: %s)" % (type, task)) - return - - passkey = self.getConfig("passkey") - - for _i in xrange(3): - res = getURL(self.API_URL, - get={'action' : "usercaptchacorrectback", - 'apikey' : passkey, - 'api_key': passkey, - 'correct': "1" if correct else "2", - 'pyload' : "1", - 'source' : "pyload", - 'id' : task.data["ticket"]}) - - self.logDebug("Request %s: %s" % (type, res)) - - if res == "OK": - break - - sleep(5) - else: - self.logDebug("Could not send %s request: %s" % (type, res)) - - - def captchaCorrect(self, task): - self._captchaResponse(task, True) - - - def captchaInvalid(self, task): - self._captchaResponse(task, False) diff --git a/module/plugins/hooks/CaptchaBrotherhood.py b/module/plugins/hooks/CaptchaBrotherhood.py deleted file mode 100644 index 2ebeb1734..000000000 --- a/module/plugins/hooks/CaptchaBrotherhood.py +++ /dev/null @@ -1,171 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import StringIO -import pycurl - -try: - from PIL import Image -except ImportError: - import Image - -from thread import start_new_thread -from time import sleep -from urllib import urlencode - -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook - - -class CaptchaBrotherhoodException(Exception): - - def __init__(self, err): - self.err = err - - - def getCode(self): - return self.err - - - def __str__(self): - return "<CaptchaBrotherhoodException %s>" % self.err - - - def __repr__(self): - return "<CaptchaBrotherhoodException %s>" % self.err - - -class CaptchaBrotherhood(Hook): - __name__ = "CaptchaBrotherhood" - __type__ = "hook" - __version__ = "0.05" - - __config__ = [("username", "str", "Username", ""), - ("force", "bool", "Force CT even if client is connected", False), - ("passkey", "password", "Password", "")] - - __description__ = """Send captchas to CaptchaBrotherhood.com""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org"), - ("zoidberg", "zoidberg@mujmail.cz")] - - - API_URL = "http://www.captchabrotherhood.com/" - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - - def getCredits(self): - res = getURL(self.API_URL + "askCredits.aspx", - get={"username": self.getConfig("username"), "password": self.getConfig("passkey")}) - if not res.startswith("OK"): - raise CaptchaBrotherhoodException(res) - else: - credits = int(res[3:]) - self.logInfo(_("%d credits left") % credits) - self.info['credits'] = credits - return credits - - - def submit(self, captcha, captchaType="file", match=None): - try: - img = Image.open(captcha) - output = StringIO.StringIO() - self.logDebug("CAPTCHA IMAGE", img, img.format, img.mode) - if img.format in ("GIF", "JPEG"): - img.save(output, img.format) - else: - if img.mode != "RGB": - img = img.convert("RGB") - img.save(output, "JPEG") - data = output.getvalue() - output.close() - except Exception, e: - raise CaptchaBrotherhoodException("Reading or converting captcha image failed: %s" % e) - - req = getRequest() - - url = "%ssendNewCaptcha.aspx?%s" % (self.API_URL, - urlencode({"username": self.getConfig("username"), - "password": self.getConfig("passkey"), - "captchaSource": "pyLoad", - "timeout": "80"})) - - req.c.setopt(pycurl.URL, url) - req.c.setopt(pycurl.POST, 1) - req.c.setopt(pycurl.POSTFIELDS, data) - req.c.setopt(pycurl.HTTPHEADER, ["Content-Type: text/html"]) - - try: - req.c.perform() - res = req.getResponse() - except Exception, e: - raise CaptchaBrotherhoodException("Submit captcha image failed") - - req.close() - - if not res.startswith("OK"): - raise CaptchaBrotherhoodException(res[1]) - - ticket = res[3:] - - for _i in xrange(15): - sleep(5) - res = self.get_api("askCaptchaResult", ticket) - if res.startswith("OK-answered"): - return ticket, res[12:] - - raise CaptchaBrotherhoodException("No solution received in time") - - - def get_api(self, api, ticket): - res = getURL("%s%s.aspx" % (self.API_URL, api), - get={"username": self.getConfig("username"), - "password": self.getConfig("passkey"), - "captchaID": ticket}) - if not res.startswith("OK"): - raise CaptchaBrotherhoodException("Unknown response: %s" % res) - - return res - - - def newCaptchaTask(self, task): - if "service" in task.data: - return False - - if not task.isTextual(): - return False - - if not self.getConfig("username") or not self.getConfig("passkey"): - return False - - if self.core.isClientConnected() and not self.getConfig("force"): - return False - - if self.getCredits() > 10: - task.handler.append(self) - task.data['service'] = self.__name__ - task.setWaiting(100) - start_new_thread(self.processCaptcha, (task,)) - else: - self.logInfo(_("Your CaptchaBrotherhood Account has not enough credits")) - - - def captchaInvalid(self, task): - if task.data['service'] == self.__name__ and "ticket" in task.data: - res = self.get_api("complainCaptcha", task.data['ticket']) - - - def processCaptcha(self, task): - c = task.captchaFile - try: - ticket, result = self.submit(c) - except CaptchaBrotherhoodException, e: - task.error = e.getCode() - return - - task.data['ticket'] = ticket - task.setResult(result) diff --git a/module/plugins/hooks/Checksum.py b/module/plugins/hooks/Checksum.py deleted file mode 100644 index eeda2d849..000000000 --- a/module/plugins/hooks/Checksum.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import hashlib -import re -import zlib - -from os import remove -from os.path import getsize, isfile, splitext - -from module.plugins.Hook import Hook -from module.utils import save_join, fs_encode - - -def computeChecksum(local_file, algorithm): - if algorithm in getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")): - h = getattr(hashlib, algorithm)() - - with open(local_file, 'rb') as f: - for chunk in iter(lambda: f.read(128 * h.block_size), ''): - h.update(chunk) - - return h.hexdigest() - - elif algorithm in ("adler32", "crc32"): - hf = getattr(zlib, algorithm) - last = 0 - - with open(local_file, 'rb') as f: - for chunk in iter(lambda: f.read(8192), ''): - last = hf(chunk, last) - - return "%x" % last - - else: - return None - - -class Checksum(Hook): - __name__ = "Checksum" - __type__ = "hook" - __version__ = "0.14" - - __config__ = [("check_checksum", "bool", "Check checksum? (If False only size will be verified)", True), - ("check_action", "fail;retry;nothing", "What to do if check fails?", "retry"), - ("max_tries", "int", "Number of retries", 2), - ("retry_action", "fail;nothing", "What to do if all retries fail?", "fail"), - ("wait_time", "int", "Time to wait before each retry (seconds)", 1)] - - __description__ = """Verify downloaded file size and checksum""" - __license__ = "GPLv3" - __authors__ = [("zoidberg", "zoidberg@mujmail.cz"), - ("Walter Purcaro", "vuolter@gmail.com"), - ("stickell", "l.stickell@yahoo.it")] - - - methods = {'sfv': 'crc32', 'crc': 'crc32', 'hash': 'md5'} - regexps = {'sfv': r'^(?P<name>[^;].+)\s+(?P<hash>[0-9A-Fa-f]{8})$', - 'md5': r'^(?P<name>[0-9A-Fa-f]{32}) (?P<file>.+)$', - 'crc': r'filename=(?P<name>.+)\nsize=(?P<size>\d+)\ncrc32=(?P<hash>[0-9A-Fa-f]{8})$', - 'default': r'^(?P<hash>[0-9A-Fa-f]+)\s+\*?(?P<name>.+)$'} - - - def coreReady(self): - if not self.getConfig("check_checksum"): - self.logInfo(_("Checksum validation is disabled in plugin configuration")) - - - def setup(self): - self.algorithms = sorted( - getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse=True) - self.algorithms.extend(["crc32", "adler32"]) - self.formats = self.algorithms + ["sfv", "crc", "hash"] - - - def downloadFinished(self, pyfile): - """ - Compute checksum for the downloaded file and compare it with the hash provided by the hoster. - pyfile.plugin.check_data should be a dictionary which can contain: - a) if known, the exact filesize in bytes (e.g. "size": 123456789) - b) hexadecimal hash string with algorithm name as key (e.g. "md5": "d76505d0869f9f928a17d42d66326307") - """ - if hasattr(pyfile.plugin, "check_data") and isinstance(pyfile.plugin.check_data, dict): - data = pyfile.plugin.check_data.copy() - - elif hasattr(pyfile.plugin, "api_data") and isinstance(pyfile.plugin.api_data, dict): - data = pyfile.plugin.api_data.copy() - - # elif hasattr(pyfile.plugin, "info") and isinstance(pyfile.plugin.info, dict): - # data = pyfile.plugin.info.copy() - - else: - return - - self.logDebug(data) - - if not pyfile.plugin.lastDownload: - self.checkFailed(pyfile, None, "No file downloaded") - - local_file = fs_encode(pyfile.plugin.lastDownload) - #download_folder = self.config['general']['download_folder'] - #local_file = fs_encode(save_join(download_folder, pyfile.package().folder, pyfile.name)) - - if not isfile(local_file): - self.checkFailed(pyfile, None, "File does not exist") - - # validate file size - if "size" in data: - api_size = int(data['size']) - file_size = getsize(local_file) - if api_size != file_size: - self.logWarning(_("File %s has incorrect size: %d B (%d expected)") % (pyfile.name, file_size, api_size)) - self.checkFailed(pyfile, local_file, "Incorrect file size") - del data['size'] - - # validate checksum - if data and self.getConfig("check_checksum"): - if "checksum" in data: - data['md5'] = data['checksum'] - - for key in self.algorithms: - if key in data: - checksum = computeChecksum(local_file, key.replace("-", "").lower()) - if checksum: - if checksum == data[key].lower(): - self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') % - (pyfile.name, key.upper(), checksum)) - break - else: - self.logWarning(_("%s checksum for file %s does not match (%s != %s)") % - (key.upper(), pyfile.name, checksum, data[key])) - self.checkFailed(pyfile, local_file, "Checksums do not match") - else: - self.logWarning(_("Unsupported hashing algorithm"), key.upper()) - else: - self.logWarning(_("Unable to validate checksum for file: ") + pyfile.name) - - - def checkFailed(self, pyfile, local_file, msg): - check_action = self.getConfig("check_action") - if check_action == "retry": - max_tries = self.getConfig("max_tries") - retry_action = self.getConfig("retry_action") - if pyfile.plugin.retries < max_tries: - if local_file: - remove(local_file) - pyfile.plugin.retry(max_tries, self.getConfig("wait_time"), msg) - elif retry_action == "nothing": - return - elif check_action == "nothing": - return - pyfile.plugin.fail(reason=msg) - - - def packageFinished(self, pypack): - download_folder = save_join(self.config['general']['download_folder'], pypack.folder, "") - - for link in pypack.getChildren().itervalues(): - file_type = splitext(link['name'])[1][1:].lower() - - if file_type not in self.formats: - continue - - hash_file = fs_encode(save_join(download_folder, link['name'])) - if not isfile(hash_file): - self.logWarning(_("File not found"), link['name']) - continue - - with open(hash_file) as f: - text = f.read() - - for m in re.finditer(self.regexps.get(file_type, self.regexps['default']), text): - data = m.groupdict() - self.logDebug(link['name'], data) - - local_file = fs_encode(save_join(download_folder, data['name'])) - algorithm = self.methods.get(file_type, file_type) - checksum = computeChecksum(local_file, algorithm) - if checksum == data['hash']: - self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') % - (data['name'], algorithm, checksum)) - else: - self.logWarning(_("%s checksum for file %s does not match (%s != %s)") % - (algorithm, data['name'], checksum, data['hash'])) diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py deleted file mode 100644 index c9c0f60c0..000000000 --- a/module/plugins/hooks/ClickAndLoad.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- - -import socket -import thread - -from module.plugins.Hook import Hook - - -def proxy(self, *settings): - thread.start_new_thread(server, (self,) + settings) - lock = thread.allocate_lock() - lock.acquire() - lock.acquire() - - -def server(self, *settings): - try: - dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - dock_socket.bind((settings[0], settings[2])) - dock_socket.listen(5) - while True: - client_socket = dock_socket.accept()[0] - server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_socket.connect(("127.0.0.1", settings[1])) - thread.start_new_thread(forward, (client_socket, server_socket)) - thread.start_new_thread(forward, (server_socket, client_socket)) - except socket.error, e: - if hasattr(e, "errno"): - errno = e.errno - else: - errno = e.args[0] - - if errno == 98: - self.logWarning(_("Click'N'Load: Port 9666 already in use")) - return - thread.start_new_thread(server, (self,) + settings) - except: - thread.start_new_thread(server, (self,) + settings) - - -def forward(source, destination): - string = ' ' - while string: - string = source.recv(1024) - if string: - destination.sendall(string) - else: - #source.shutdown(socket.SHUT_RD) - destination.shutdown(socket.SHUT_WR) - - -class ClickAndLoad(Hook): - __name__ = "ClickAndLoad" - __type__ = "hook" - __version__ = "0.22" - - __config__ = [("activated", "bool", "Activated", True), - ("extern", "bool", "Allow external link adding", False)] - - __description__ = """Click'N'Load hook plugin""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.de"), - ("mkaay", "mkaay@mkaay.de")] - - - def coreReady(self): - self.port = int(self.config['webinterface']['port']) - if self.config['webinterface']['activated']: - try: - if self.getConfig("extern"): - ip = "0.0.0.0" - else: - ip = "127.0.0.1" - - thread.start_new_thread(proxy, (self, ip, self.port, 9666)) - except: - self.logError(_("ClickAndLoad port already in use")) diff --git a/module/plugins/hooks/DeathByCaptcha.py b/module/plugins/hooks/DeathByCaptcha.py deleted file mode 100644 index df09769ce..000000000 --- a/module/plugins/hooks/DeathByCaptcha.py +++ /dev/null @@ -1,218 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import re - -from base64 import b64encode -from pycurl import FORM_FILE, HTTPHEADER -from thread import start_new_thread -from time import sleep - -from module.common.json_layer import json_loads -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getRequest -from module.plugins.Hook import Hook - - -class DeathByCaptchaException(Exception): - DBC_ERRORS = {'not-logged-in': 'Access denied, check your credentials', - 'invalid-credentials': 'Access denied, check your credentials', - 'banned': 'Access denied, account is suspended', - 'insufficient-funds': 'Insufficient account balance to decrypt CAPTCHA', - 'invalid-captcha': 'CAPTCHA is not a valid image', - 'service-overload': 'CAPTCHA was rejected due to service overload, try again later', - 'invalid-request': 'Invalid request', - 'timed-out': 'No CAPTCHA solution received in time'} - - - def __init__(self, err): - self.err = err - - - def getCode(self): - return self.err - - - def getDesc(self): - if self.err in self.DBC_ERRORS.keys(): - return self.DBC_ERRORS[self.err] - else: - return self.err - - - def __str__(self): - return "<DeathByCaptchaException %s>" % self.err - - - def __repr__(self): - return "<DeathByCaptchaException %s>" % self.err - - -class DeathByCaptcha(Hook): - __name__ = "DeathByCaptcha" - __type__ = "hook" - __version__ = "0.03" - - __config__ = [("username", "str", "Username", ""), - ("passkey", "password", "Password", ""), - ("force", "bool", "Force DBC even if client is connected", False)] - - __description__ = """Send captchas to DeathByCaptcha.com""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org"), - ("zoidberg", "zoidberg@mujmail.cz")] - - - API_URL = "http://api.dbcapi.me/api/" - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - - def call_api(self, api="captcha", post=False, multipart=False): - req = getRequest() - req.c.setopt(HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.core.version]) - - if post: - if not isinstance(post, dict): - post = {} - post.update({"username": self.getConfig("username"), - "password": self.getConfig("passkey")}) - - res = None - try: - json = req.load("%s%s" % (self.API_URL, api), - post=post, - multipart=multipart) - self.logDebug(json) - res = json_loads(json) - - if "error" in res: - raise DeathByCaptchaException(res['error']) - elif "status" not in res: - raise DeathByCaptchaException(str(res)) - - except BadHeader, e: - if 403 == e.code: - raise DeathByCaptchaException('not-logged-in') - elif 413 == e.code: - raise DeathByCaptchaException('invalid-captcha') - elif 503 == e.code: - raise DeathByCaptchaException('service-overload') - elif e.code in (400, 405): - raise DeathByCaptchaException('invalid-request') - else: - raise - - finally: - req.close() - - return res - - - def getCredits(self): - res = self.call_api("user", True) - - if 'is_banned' in res and res['is_banned']: - raise DeathByCaptchaException('banned') - elif 'balance' in res and 'rate' in res: - self.info.update(res) - else: - raise DeathByCaptchaException(res) - - - def getStatus(self): - res = self.call_api("status", False) - - if 'is_service_overloaded' in res and res['is_service_overloaded']: - raise DeathByCaptchaException('service-overload') - - - def submit(self, captcha, captchaType="file", match=None): - #workaround multipart-post bug in HTTPRequest.py - if re.match("^\w*$", self.getConfig("passkey")): - multipart = True - data = (FORM_FILE, captcha) - else: - multipart = False - with open(captcha, 'rb') as f: - data = f.read() - data = "base64:" + b64encode(data) - - res = self.call_api("captcha", {"captchafile": data}, multipart) - - if "captcha" not in res: - raise DeathByCaptchaException(res) - ticket = res['captcha'] - - for _i in xrange(24): - sleep(5) - res = self.call_api("captcha/%d" % ticket, False) - if res['text'] and res['is_correct']: - break - else: - raise DeathByCaptchaException('timed-out') - - result = res['text'] - self.logDebug("Result %s : %s" % (ticket, result)) - - return ticket, result - - - def newCaptchaTask(self, task): - if "service" in task.data: - return False - - if not task.isTextual(): - return False - - if not self.getConfig("username") or not self.getConfig("passkey"): - return False - - if self.core.isClientConnected() and not self.getConfig("force"): - return False - - try: - self.getStatus() - self.getCredits() - except DeathByCaptchaException, e: - self.logError(e.getDesc()) - return False - - balance, rate = self.info['balance'], self.info['rate'] - self.logInfo(_("Account balance"), - _("US$%.3f (%d captchas left at %.2f cents each)") % (balance / 100, - balance // rate, rate)) - - if balance > rate: - task.handler.append(self) - task.data['service'] = self.__name__ - task.setWaiting(180) - start_new_thread(self.processCaptcha, (task,)) - - - def captchaInvalid(self, task): - if task.data['service'] == self.__name__ and "ticket" in task.data: - try: - res = self.call_api("captcha/%d/report" % task.data['ticket'], True) - - except DeathByCaptchaException, e: - self.logError(e.getDesc()) - - except Exception, e: - self.logError(e) - - - def processCaptcha(self, task): - c = task.captchaFile - try: - ticket, result = self.submit(c) - except DeathByCaptchaException, e: - task.error = e.getCode() - self.logError(e.getDesc()) - return - - task.data['ticket'] = ticket - task.setResult(result) diff --git a/module/plugins/hooks/DebridItaliaCom.py b/module/plugins/hooks/DebridItaliaCom.py deleted file mode 100644 index b7f0ef1c7..000000000 --- a/module/plugins/hooks/DebridItaliaCom.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class DebridItaliaCom(MultiHoster): - __name__ = "DebridItaliaCom" - __type__ = "hook" - __version__ = "0.08" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to standard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Debriditalia.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("stickell", "l.stickell@yahoo.it"), - ("Walter Purcaro", "vuolter@gmail.com")] - - - def getHoster(self): - html = getURL("http://www.debriditalia.com/status.php") - return re.findall(r'title="(.+?)"> \1</td><td><img src="/images/(?:attivo|testing)', html) diff --git a/module/plugins/hooks/DeleteFinished.py b/module/plugins/hooks/DeleteFinished.py deleted file mode 100644 index 5d2b78d50..000000000 --- a/module/plugins/hooks/DeleteFinished.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.database import style -from module.plugins.Hook import Hook - - -class DeleteFinished(Hook): - __name__ = "DeleteFinished" - __type__ = "hook" - __version__ = "1.11" - - __config__ = [('activated', 'bool', 'Activated', 'False'), - ('interval', 'int', 'Delete every (hours)', '72'), - ('deloffline', 'bool', 'Delete packages with offline links', 'False')] - - __description__ = """Automatically delete all finished packages from queue""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - # event_list = ["pluginConfigChanged"] - - - ## overwritten methods ## - def periodical(self): - if not self.info['sleep']: - deloffline = self.getConfig('deloffline') - mode = '0,1,4' if deloffline else '0,4' - msg = _('delete all finished packages in queue list (%s packages with offline links)') - self.logInfo(msg % (_('including') if deloffline else _('excluding'))) - self.deleteFinished(mode) - self.info['sleep'] = True - self.addEvent('packageFinished', self.wakeup) - - - def pluginConfigChanged(self, plugin, name, value): - if name == "interval" and value != self.interval: - self.interval = value * 3600 - self.initPeriodical() - - - def unload(self): - self.removeEvent('packageFinished', self.wakeup) - - - def coreReady(self): - self.info = {'sleep': True} - interval = self.getConfig('interval') - self.pluginConfigChanged(self.__name__, 'interval', interval) - self.addEvent('packageFinished', self.wakeup) - - - ## own methods ## - @style.queue - def deleteFinished(self, mode): - self.c.execute('DELETE FROM packages WHERE NOT EXISTS(SELECT 1 FROM links WHERE package=packages.id AND status NOT IN (%s))' % mode) - self.c.execute('DELETE FROM links WHERE NOT EXISTS(SELECT 1 FROM packages WHERE id=links.package)') - - - def wakeup(self, pypack): - self.removeEvent('packageFinished', self.wakeup) - self.info['sleep'] = False - - - ## event managing ## - def addEvent(self, event, func): - """Adds an event listener for event name""" - if event in self.m.events: - if func in self.m.events[event]: - self.logDebug("Function already registered", func) - else: - self.m.events[event].append(func) - else: - self.m.events[event] = [func] - - - def setup(self): - self.m = self.manager - self.removeEvent = self.m.removeEvent diff --git a/module/plugins/hooks/DownloadScheduler.py b/module/plugins/hooks/DownloadScheduler.py deleted file mode 100644 index 14884426f..000000000 --- a/module/plugins/hooks/DownloadScheduler.py +++ /dev/null @@ -1,78 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from time import localtime - -from module.plugins.Hook import Hook - - -class DownloadScheduler(Hook): - __name__ = "DownloadScheduler" - __type__ = "hook" - __version__ = "0.21" - - __config__ = [("timetable", "str", "List time periods as hh:mm full or number(kB/s)", - "0:00 full, 7:00 250, 10:00 0, 17:00 150"), - ("abort", "bool", "Abort active downloads when start period with speed 0", False)] - - __description__ = """Download Scheduler""" - __license__ = "GPLv3" - __authors__ = [("zoidberg", "zoidberg@mujmail.cz"), - ("stickell", "l.stickell@yahoo.it")] - - - def setup(self): - self.cb = None # callback to scheduler job; will be by removed hookmanager when hook unloaded - - - def coreReady(self): - self.updateSchedule() - - - def updateSchedule(self, schedule=None): - if schedule is None: - schedule = self.getConfig("timetable") - - schedule = re.findall("(\d{1,2}):(\d{2})[\s]*(-?\d+)", - schedule.lower().replace("full", "-1").replace("none", "0")) - if not schedule: - self.logError(_("Invalid schedule")) - return - - t0 = localtime() - now = (t0.tm_hour, t0.tm_min, t0.tm_sec, "X") - schedule = sorted([(int(x[0]), int(x[1]), 0, int(x[2])) for x in schedule] + [now]) - - self.logDebug("Schedule", schedule) - - for i, v in enumerate(schedule): - if v[3] == "X": - last, next = schedule[i - 1], schedule[(i + 1) % len(schedule)] - self.logDebug("Now/Last/Next", now, last, next) - - self.setDownloadSpeed(last[3]) - - next_time = (((24 + next[0] - now[0]) * 60 + next[1] - now[1]) * 60 + next[2] - now[2]) % 86400 - self.core.scheduler.removeJob(self.cb) - self.cb = self.core.scheduler.addJob(next_time, self.updateSchedule, threaded=False) - - - def setDownloadSpeed(self, speed): - if speed == 0: - abort = self.getConfig("abort") - self.logInfo(_("Stopping download server. (Running downloads will %sbe aborted.)") % '' if abort else _('not ')) - self.core.api.pauseServer() - if abort: - self.core.api.stopAllDownloads() - else: - self.core.api.unpauseServer() - - if speed > 0: - self.logInfo(_("Setting download speed to %d kB/s") % speed) - self.core.api.setConfigValue("download", "limit_speed", 1) - self.core.api.setConfigValue("download", "max_speed", speed) - else: - self.logInfo(_("Setting download speed to FULL")) - self.core.api.setConfigValue("download", "limit_speed", 0) - self.core.api.setConfigValue("download", "max_speed", -1) diff --git a/module/plugins/hooks/EasybytezCom.py b/module/plugins/hooks/EasybytezCom.py deleted file mode 100644 index 3faa4fa1a..000000000 --- a/module/plugins/hooks/EasybytezCom.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.internal.MultiHoster import MultiHoster - - -class EasybytezCom(MultiHoster): - __name__ = "EasybytezCom" - __type__ = "hook" - __version__ = "0.03" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "")] - - __description__ = """EasyBytez.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] - - - def getHoster(self): - self.account = self.core.accountManager.getAccountPlugin(self.__name__) - user = self.account.selectAccount()[0] - - try: - req = self.account.getAccountRequest(user) - page = req.load("http://www.easybytez.com") - - hosters = re.search(r'</textarea>\s*Supported sites:(.*)', page).group(1).split(',') - - except Exception, e: - self.logWarning(_("Unable to load supported hoster list, using last known")) - self.logDebug(e) - - hosters = ["bitshare.com", "crocko.com", "ddlstorage.com", "depositfiles.com", "extabit.com", "hotfile.com", - "mediafire.com", "netload.in", "rapidgator.net", "rapidshare.com", "uploading.com", "uload.to", - "uploaded.to"] - finally: - return hosters diff --git a/module/plugins/hooks/ExpertDecoders.py b/module/plugins/hooks/ExpertDecoders.py deleted file mode 100644 index 1b9459eb6..000000000 --- a/module/plugins/hooks/ExpertDecoders.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -from base64 import b64encode -from pycurl import LOW_SPEED_TIME -from thread import start_new_thread -from uuid import uuid4 - -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook - - -class ExpertDecoders(Hook): - __name__ = "ExpertDecoders" - __type__ = "hook" - __version__ = "0.01" - - __config__ = [("force", "bool", "Force CT even if client is connected", False), - ("passkey", "password", "Access key", "")] - - __description__ = """Send captchas to expertdecoders.com""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org"), - ("zoidberg", "zoidberg@mujmail.cz")] - - - API_URL = "http://www.fasttypers.org/imagepost.ashx" - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - - def getCredits(self): - res = getURL(self.API_URL, post={"key": self.getConfig("passkey"), "action": "balance"}) - - if res.isdigit(): - self.logInfo(_("%s credits left") % res) - self.info['credits'] = credits = int(res) - return credits - else: - self.logError(res) - return 0 - - - def processCaptcha(self, task): - task.data['ticket'] = ticket = uuid4() - result = None - - with open(task.captchaFile, 'rb') as f: - data = f.read() - data = b64encode(data) - - req = getRequest() - #raise timeout threshold - req.c.setopt(LOW_SPEED_TIME, 80) - - try: - result = req.load(self.API_URL, post={"action": "upload", "key": self.getConfig("passkey"), - "file": data, "gen_task_id": ticket}) - finally: - req.close() - - self.logDebug("Result %s : %s" % (ticket, result)) - task.setResult(result) - - - def newCaptchaTask(self, task): - if not task.isTextual(): - return False - - if not self.getConfig("passkey"): - return False - - if self.core.isClientConnected() and not self.getConfig("force"): - return False - - if self.getCredits() > 0: - task.handler.append(self) - task.setWaiting(100) - start_new_thread(self.processCaptcha, (task,)) - - else: - self.logInfo(_("Your ExpertDecoders Account has not enough credits")) - - - def captchaInvalid(self, task): - if "ticket" in task.data: - - try: - res = getURL(self.API_URL, - post={'action': "refund", 'key': self.getConfig("passkey"), 'gen_task_id': task.data['ticket']}) - self.logInfo(_("Request refund", res) - - except BadHeader, e: - self.logError(_("Could not send refund request"), e) diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py deleted file mode 100644 index 5db2037fa..000000000 --- a/module/plugins/hooks/ExternalScripts.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- - -import subprocess - -from itertools import chain -from os import listdir, access, X_OK, makedirs -from os.path import join, exists, basename, abspath - -from module.plugins.Hook import Hook -from module.utils import save_join - - -class ExternalScripts(Hook): - __name__ = "ExternalScripts" - __type__ = "hook" - __version__ = "0.24" - - __config__ = [("activated", "bool", "Activated", True)] - - __description__ = """Run external scripts""" - __license__ = "GPLv3" - __authors__ = [("mkaay", "mkaay@mkaay.de"), - ("RaNaN", "ranan@pyload.org"), - ("spoob", "spoob@pyload.org"), - ("Walter Purcaro", "vuolter@gmail.com")] - - - event_list = ["archive_extracted", "package_extracted", "all_archives_extracted", "all_archives_processed", - "allDownloadsFinished", "allDownloadsProcessed"] - - - def setup(self): - self.scripts = {} - - folders = ["download_preparing", "download_finished", "all_downloads_finished", "all_downloads_processed", - "before_reconnect", "after_reconnect", - "package_finished", "package_extracted", - "archive_extracted", "all_archives_extracted", "all_archives_processed", - # deprecated folders - "unrar_finished", "all_dls_finished", "all_dls_processed"] - - for folder in folders: - self.scripts[folder] = [] - - self.initPluginType(folder, join(pypath, 'scripts', folder)) - self.initPluginType(folder, join('scripts', folder)) - - for script_type, names in self.scripts.iteritems(): - if names: - self.logInfo(_("Installed scripts for"), script_type, ", ".join([basename(x) for x in names])) - - - def initPluginType(self, folder, path): - if not exists(path): - try: - makedirs(path) - except: - self.logDebug("Script folder %s not created" % folder) - return - - for f in listdir(path): - if f.startswith("#") or f.startswith(".") or f.startswith("_") or f.endswith("~") or f.endswith(".swp"): - continue - - if not access(join(path, f), X_OK): - self.logWarning(_("Script not executable:") + " %s/%s" % (folder, f)) - - self.scripts[folder].append(join(path, f)) - - - def callScript(self, script, *args): - try: - cmd = [script] + [str(x) if not isinstance(x, basestring) else x for x in args] - self.logDebug("Executing", abspath(script), " ".join(cmd)) - #output goes to pyload - subprocess.Popen(cmd, bufsize=-1) - except Exception, e: - self.logError(_("Error in %(script)s: %(error)s") % {"script": basename(script), "error": e}) - - - def downloadPreparing(self, pyfile): - for script in self.scripts['download_preparing']: - self.callScript(script, pyfile.pluginname, pyfile.url, pyfile.id) - - - def downloadFinished(self, pyfile): - download_folder = self.config['general']['download_folder'] - for script in self.scripts['download_finished']: - filename = save_join(download_folder, pyfile.package().folder, pyfile.name) - self.callScript(script, pyfile.pluginname, pyfile.url, pyfile.name, filename, pyfile.id) - - - def packageFinished(self, pypack): - download_folder = self.config['general']['download_folder'] - for script in self.scripts['package_finished']: - folder = save_join(download_folder, pypack.folder) - self.callScript(script, pypack.name, folder, pypack.password, pypack.id) - - - def beforeReconnecting(self, ip): - for script in self.scripts['before_reconnect']: - self.callScript(script, ip) - - - def afterReconnecting(self, ip): - for script in self.scripts['after_reconnect']: - self.callScript(script, ip) - - - def archive_extracted(self, pyfile, folder, filename, files): - for script in self.scripts['archive_extracted']: - self.callScript(script, folder, filename, files) - for script in self.scripts['unrar_finished']: #: deprecated - self.callScript(script, folder, filename) - - - def package_extracted(self, pypack): - download_folder = self.config['general']['download_folder'] - for script in self.scripts['package_extracted']: - folder = save_join(download_folder, pypack.folder) - self.callScript(script, pypack.name, folder, pypack.password, pypack.id) - - - def all_archives_extracted(self): - for script in self.scripts['all_archives_extracted']: - self.callScript(script) - - - def all_archives_processed(self): - for script in self.scripts['all_archives_processed']: - self.callScript(script) - - - def allDownloadsFinished(self): - for script in chain(self.scripts['all_downloads_finished'], self.scripts['all_dls_finished']): - self.callScript(script) - - - def allDownloadsProcessed(self): - for script in chain(self.scripts['all_downloads_processed'], self.scripts['all_dls_processed']): - self.callScript(script) diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py deleted file mode 100644 index 07db13aa1..000000000 --- a/module/plugins/hooks/ExtractArchive.py +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import os -import sys - -from copy import copy -from os import remove, chmod, makedirs -from os.path import exists, basename, isfile, isdir -from traceback import print_exc - -# monkey patch bug in python 2.6 and lower -# http://bugs.python.org/issue6122 , http://bugs.python.org/issue1236 , http://bugs.python.org/issue1731717 -if sys.version_info < (2, 7) and os.name != "nt": - import errno - from subprocess import Popen - - - def _eintr_retry_call(func, *args): - while True: - try: - return func(*args) - except OSError, e: - if e.errno == errno.EINTR: - continue - raise - - - # unsued timeout option for older python version - def wait(self, timeout=0): - """Wait for child process to terminate. Returns returncode - attribute.""" - if self.returncode is None: - try: - pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) - except OSError, e: - if e.errno != errno.ECHILD: - raise - # This happens if SIGCLD is set to be ignored or waiting - # for child processes has otherwise been disabled for our - # process. This child is dead, we can't get the status. - sts = 0 - self._handle_exitstatus(sts) - return self.returncode - - Popen.wait = wait - -if os.name != "nt": - from grp import getgrnam - from os import chown - from pwd import getpwnam - -from module.plugins.Hook import Hook, threaded, Expose -from module.plugins.internal.AbstractExtractor import ArchiveError, CRCError, WrongPassword -from module.utils import save_join, fs_encode - - -class ExtractArchive(Hook): - __name__ = "ExtractArchive" - __type__ = "hook" - __version__ = "0.18" - - __config__ = [("activated", "bool", "Activated", True), - ("fullpath", "bool", "Extract full path", True), - ("overwrite", "bool", "Overwrite files", True), - ("passwordfile", "file", "password file", "archive_password.txt"), - ("deletearchive", "bool", "Delete archives when done", False), - ("subfolder", "bool", "Create subfolder for each package", False), - ("destination", "folder", "Extract files to", ""), - ("excludefiles", "str", "Exclude files from unpacking (seperated by ;)", ""), - ("recursive", "bool", "Extract archives in archvies", True), - ("queue", "bool", "Wait for all downloads to be finished", True), - ("renice", "int", "CPU Priority", 0)] - - __description__ = """Extract different kind of archives""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "ranan@pyload.org"), - ("AndroKev", None), - ("Walter Purcaro", "vuolter@gmail.com")] - - - event_list = ["allDownloadsProcessed"] - - - def setup(self): - self.plugins = [] - self.passwords = [] - names = [] - - for p in ("UnRar", "UnZip"): - try: - module = self.core.pluginManager.loadModule("internal", p) - klass = getattr(module, p) - if klass.checkDeps(): - names.append(p) - self.plugins.append(klass) - - except OSError, e: - if e.errno == 2: - self.logInfo(_("No %s installed") % p) - else: - self.logWarning(_("Could not activate %s") % p, e) - if self.core.debug: - print_exc() - - except Exception, e: - self.logWarning(_("Could not activate %s") % p, e) - if self.core.debug: - print_exc() - - if names: - self.logInfo(_("Activated") + " " + " ".join(names)) - else: - self.logInfo(_("No Extract plugins activated")) - - # queue with package ids - self.queue = [] - - - @Expose - def extractPackage(self, id): - """ Extract package with given id""" - self.manager.startThread(self.extract, [id]) - - - def packageFinished(self, pypack): - pid = pypack.id - if self.getConfig("queue"): - self.logInfo(_("Package %s queued for later extracting") % pypack.name) - self.queue.append(pid) - else: - self.manager.startThread(self.extract, [pid]) - - - @threaded - def allDownloadsProcessed(self, thread): - local = copy(self.queue) - del self.queue[:] - if self.extract(local, thread): #: check only if all gone fine, no failed reporting for now - self.manager.dispatchEvent("all_archives_extracted") - self.manager.dispatchEvent("all_archives_processed") - - - def extract(self, ids, thread=None): - processed = [] - extracted = [] - failed = [] - - destination = self.getConfig("destination") - subfolder = self.getConfig("subfolder") - fullpath = self.getConfig("fullpath") - overwrite = self.getConfig("overwrite") - excludefiles = self.getConfig("excludefiles") - renice = self.getConfig("renice") - recursive = self.getConfig("recursive") - - # reload from txt file - self.reloadPasswords() - - # dl folder - dl = self.config['general']['download_folder'] - - #iterate packages -> plugins -> targets - for pid in ids: - p = self.core.files.getPackage(pid) - self.logInfo(_("Check package %s") % p.name) - if not p: - continue - - # determine output folder - out = save_join(dl, p.folder, destination, "") #: force trailing slash - - if subfolder: - out = save_join(out, fs_encode(p.folder)) - - if not exists(out): - makedirs(out) - - files_ids = [(save_join(dl, p.folder, x['name']), x['id']) for x in p.getChildren().itervalues()] - matched = False - success = True - - # check as long there are unseen files - while files_ids: - new_files_ids = [] - - for plugin in self.plugins: - targets = plugin.getTargets(files_ids) - if targets: - self.logDebug("Targets for %s: %s" % (plugin.__name__, targets)) - matched = True - for target, fid in targets: - if target in processed: - self.logDebug(basename(target), "skipped") - continue - - processed.append(target) # prevent extracting same file twice - - self.logInfo(basename(target), _("Extract to %s") % out) - try: - klass = plugin(self, target, out, fullpath, overwrite, excludefiles, renice) - klass.init() - password = p.password.strip().splitlines() - new_files = self._extract(klass, fid, password, thread) - except Exception, e: - self.logError(basename(target), e) - success = False - continue - - self.logDebug("Extracted", new_files) - self.setPermissions(new_files) - - for file in new_files: - if not exists(file): - self.logDebug("New file %s does not exists" % file) - continue - if recursive and isfile(file): - new_files_ids.append((file, fid)) # append as new target - - files_ids = new_files_ids # also check extracted files - - if matched: - if success: - extracted.append(pid) - self.manager.dispatchEvent("package_extracted", p) - else: - failed.append(pid) - self.manager.dispatchEvent("package_extract_failed", p) - else: - self.logInfo(_("No files found to extract")) - - return True if not failed else False - - - def _extract(self, plugin, fid, passwords, thread): - pyfile = self.core.files.getFile(fid) - deletearchive = self.getConfig("deletearchive") - - pyfile.setCustomStatus(_("extracting")) - thread.addActive(pyfile) # keep this file until everything is done - - try: - progress = lambda x: pyfile.setProgress(x) - success = False - - if not plugin.checkArchive(): - plugin.extract(progress) - success = True - else: - self.logInfo(basename(plugin.file), _("Password protected")) - self.logDebug("Passwords", passwords) - - pwlist = copy(self.getPasswords()) - # remove already supplied pws from list (only local) - for pw in passwords: - if pw in pwlist: - pwlist.remove(pw) - - for pw in passwords + pwlist: - try: - self.logDebug("Try password", pw) - if plugin.checkPassword(pw): - plugin.extract(progress, pw) - self.addPassword(pw) - success = True - break - except WrongPassword: - self.logDebug("Password was wrong") - - if not success: - raise Exception(_("Wrong password")) - - if self.core.debug: - self.logDebug("Would delete", ", ".join(plugin.getDeleteFiles())) - - if deletearchive: - files = plugin.getDeleteFiles() - self.logInfo(_("Deleting %s files") % len(files)) - for f in files: - if exists(f): - remove(f) - else: - self.logDebug("%s does not exists" % f) - - self.logInfo(basename(plugin.file), _("Extracting finished")) - - extracted_files = plugin.getExtractedFiles() - self.manager.dispatchEvent("archive_extracted", pyfile, plugin.out, plugin.file, extracted_files) - - return extracted_files - - except ArchiveError, e: - self.logError(basename(plugin.file), _("Archive Error"), e) - except CRCError: - self.logError(basename(plugin.file), _("CRC Mismatch")) - except Exception, e: - if self.core.debug: - print_exc() - self.logError(basename(plugin.file), _("Unknown Error"), e) - - self.manager.dispatchEvent("archive_extract_failed", pyfile) - raise Exception(_("Extract failed")) - - - @Expose - def getPasswords(self): - """ List of saved passwords """ - return self.passwords - - - def reloadPasswords(self): - passwordfile = self.getConfig("passwordfile") - - try: - passwords = [] - with open(passwordfile, "a+") as f: - for pw in f.read().splitlines(): - passwords.append(pw) - - except IOError, e: - self.logError(e) - - else: - self.passwords = passwords - - - @Expose - def addPassword(self, pw): - """ Adds a password to saved list""" - passwordfile = self.getConfig("passwordfile") - - if pw in self.passwords: - self.passwords.remove(pw) - - self.passwords.insert(0, pw) - - try: - with open(passwordfile, "wb") as f: - for pw in self.passwords: - f.write(pw + "\n") - except IOError, e: - self.logError(e) - - - def setPermissions(self, files): - for f in files: - if not exists(f): - continue - try: - if self.config['permission']['change_file']: - if isfile(f): - chmod(f, int(self.config['permission']['file'], 8)) - elif isdir(f): - chmod(f, int(self.config['permission']['folder'], 8)) - - if self.config['permission']['change_dl'] and os.name != "nt": - uid = getpwnam(self.config['permission']['user'])[2] - gid = getgrnam(self.config['permission']['group'])[2] - chown(f, uid, gid) - except Exception, e: - self.logWarning(_("Setting User and Group failed"), e) diff --git a/module/plugins/hooks/FastixRu.py b/module/plugins/hooks/FastixRu.py deleted file mode 100644 index cec6c6f1f..000000000 --- a/module/plugins/hooks/FastixRu.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class FastixRu(MultiHoster): - __name__ = "FastixRu" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("unloadFailing", "bool", "Revert to standard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Fastix.ru hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Massimo Rosamilia", "max@spiritix.eu")] - - - def getHoster(self): - page = getURL("http://fastix.ru/api_v2", - get={'apikey': "5182964c3f8f9a7f0b00000a_kelmFB4n1IrnCDYuIFn2y", - 'sub' : "allowed_sources"}) - host_list = json_loads(page) - host_list = host_list['allow'] - return host_list diff --git a/module/plugins/hooks/FreeWayMe.py b/module/plugins/hooks/FreeWayMe.py deleted file mode 100644 index 5abec29ba..000000000 --- a/module/plugins/hooks/FreeWayMe.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class FreeWayMe(MultiHoster): - __name__ = "FreeWayMe" - __type__ = "hook" - __version__ = "0.11" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to stanard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """FreeWay.me hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Nicolas Giese", "james@free-way.me")] - - - def getHoster(self): - hostis = getURL("https://www.free-way.me/ajax/jd.php", get={'id': 3}).replace("\"", "").strip() - self.logDebug("Hosters", hostis) - return [x.strip() for x in hostis.split(",") if x.strip()] diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py deleted file mode 100644 index b0b59e2ba..000000000 --- a/module/plugins/hooks/HotFolder.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import time - -from os import listdir, makedirs -from os.path import exists, isfile, join -from shutil import move - -from module.plugins.Hook import Hook -from module.utils import fs_encode, save_join - - -class HotFolder(Hook): - __name__ = "HotFolder" - __type__ = "hook" - __version__ = "0.12" - - __config__ = [("folder", "str", "Folder to observe", "container"), - ("watch_file", "bool", "Observe link file", False), - ("keep", "bool", "Keep added containers", True), - ("file", "str", "Link file", "links.txt")] - - __description__ = """Observe folder and file for changes and add container and links""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.de")] - - - def setup(self): - self.interval = 10 - - - def periodical(self): - folder = fs_encode(self.getConfig("folder")) - - try: - if not exists(join(folder, "finished")): - makedirs(join(folder, "finished")) - - if self.getConfig("watch_file"): - with open(fs_encode(self.getConfig("file")), "a+") as f: - content = f.read().strip() - - if content: - name = "%s_%s.txt" % (self.getConfig("file"), time.strftime("%H-%M-%S_%d%b%Y")) - - with open(save_join(folder, "finished", name), "wb") as f: - f.write(content) - - self.core.api.addPackage(f.name, [f.name], 1) - - for f in listdir(folder): - path = join(folder, f) - - if not isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."): - continue - - newpath = join(folder, "finished", f if self.getConfig("keep") else "tmp_" + f) - move(path, newpath) - - self.logInfo(_("Added %s from HotFolder") % f) - self.core.api.addPackage(f, [newpath], 1) - - except IOError, e: - self.logError(e) diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py deleted file mode 100644 index 98edc2f7f..000000000 --- a/module/plugins/hooks/IRCInterface.py +++ /dev/null @@ -1,431 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import socket -import ssl -import time - -from pycurl import FORM_FILE -from select import select -from threading import Thread -from time import sleep -from traceback import print_exc - -from module.Api import PackageDoesNotExists, FileDoesNotExists -from module.network.RequestFactory import getURL -from module.plugins.Hook import Hook -from module.utils import formatSize - - -class IRCInterface(Thread, Hook): - __name__ = "IRCInterface" - __type__ = "hook" - __version__ = "0.12" - - __config__ = [("host", "str", "IRC-Server Address", "Enter your server here!"), - ("port", "int", "IRC-Server Port", 6667), - ("ident", "str", "Clients ident", "pyload-irc"), - ("realname", "str", "Realname", "pyload-irc"), - ("ssl", "bool", "Use SSL", False), - ("nick", "str", "Nickname the Client will take", "pyLoad-IRC"), - ("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here!"), - ("info_file", "bool", "Inform about every file finished", False), - ("info_pack", "bool", "Inform about every package finished", True), - ("captcha", "bool", "Send captcha requests", True)] - - __description__ = """Connect to irc and let owner perform different tasks""" - __license__ = "GPLv3" - __authors__ = [("Jeix", "Jeix@hasnomail.com")] - - - def __init__(self, core, manager): - Thread.__init__(self) - Hook.__init__(self, core, manager) - self.setDaemon(True) - - - def coreReady(self): - self.abort = False - self.more = [] - self.new_package = {} - - self.start() - - - def packageFinished(self, pypack): - try: - if self.getConfig("info_pack"): - self.response(_("Package finished: %s") % pypack.name) - except: - pass - - - def downloadFinished(self, pyfile): - try: - if self.getConfig("info_file"): - self.response( - _("Download finished: %(name)s @ %(plugin)s ") % {"name": pyfile.name, "plugin": pyfile.pluginname}) - except: - pass - - - def newCaptchaTask(self, task): - if self.getConfig("captcha") and task.isTextual(): - task.handler.append(self) - task.setWaiting(60) - - page = getURL("http://www.freeimagehosting.net/upload.php", - post={"attached": (FORM_FILE, task.captchaFile)}, multipart=True) - - url = re.search(r"\[img\]([^\[]+)\[/img\]\[/url\]", page).group(1) - self.response(_("New Captcha Request: %s") % url) - self.response(_("Answer with 'c %s text on the captcha'") % task.id) - - - def run(self): - # connect to IRC etc. - self.sock = socket.socket() - host = self.getConfig("host") - self.sock.connect((host, self.getConfig("port"))) - - if self.getConfig("ssl"): - self.sock = ssl.wrap_socket(self.sock, cert_reqs=ssl.CERT_NONE) #@TODO: support certificate - - nick = self.getConfig("nick") - self.sock.send("NICK %s\r\n" % nick) - self.sock.send("USER %s %s bla :%s\r\n" % (nick, host, nick)) - for t in self.getConfig("owner").split(): - if t.strip().startswith("#"): - self.sock.send("JOIN %s\r\n" % t.strip()) - self.logInfo(_("Connected to"), host) - self.logInfo(_("Switching to listening mode!")) - try: - self.main_loop() - - except IRCError, ex: - self.sock.send("QUIT :byebye\r\n") - print_exc() - self.sock.close() - - - def main_loop(self): - readbuffer = "" - while True: - sleep(1) - fdset = select([self.sock], [], [], 0) - if self.sock not in fdset[0]: - continue - - if self.abort: - raise IRCError("quit") - - readbuffer += self.sock.recv(1024) - temp = readbuffer.split("\n") - readbuffer = temp.pop() - - for line in temp: - line = line.rstrip() - first = line.split() - - if first[0] == "PING": - self.sock.send("PONG %s\r\n" % first[1]) - - if first[0] == "ERROR": - raise IRCError(line) - - msg = line.split(None, 3) - if len(msg) < 4: - continue - - msg = { - "origin": msg[0][1:], - "action": msg[1], - "target": msg[2], - "text": msg[3][1:] - } - - self.handle_events(msg) - - - def handle_events(self, msg): - if not msg['origin'].split("!", 1)[0] in self.getConfig("owner").split(): - return - - if msg['target'].split("!", 1)[0] != self.getConfig("nick"): - return - - if msg['action'] != "PRIVMSG": - return - - # HANDLE CTCP ANTI FLOOD/BOT PROTECTION - if msg['text'] == "\x01VERSION\x01": - self.logDebug("Sending CTCP VERSION") - self.sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface")) - return - elif msg['text'] == "\x01TIME\x01": - self.logDebug("Sending CTCP TIME") - self.sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time())) - return - elif msg['text'] == "\x01LAG\x01": - self.logDebug("Received CTCP LAG") #: don't know how to answer - return - - trigger = "pass" - args = None - - try: - temp = msg['text'].split() - trigger = temp[0] - if len(temp) > 1: - args = temp[1:] - except: - pass - - handler = getattr(self, "event_%s" % trigger, self.event_pass) - try: - res = handler(args) - for line in res: - self.response(line, msg['origin']) - except Exception, e: - self.logError(e) - - - def response(self, msg, origin=""): - if origin == "": - for t in self.getConfig("owner").split(): - self.sock.send("PRIVMSG %s :%s\r\n" % (t.strip(), msg)) - else: - self.sock.send("PRIVMSG %s :%s\r\n" % (origin.split("!", 1)[0], msg)) - - - #### Events - - def event_pass(self, args): - return [] - - - def event_status(self, args): - downloads = self.core.api.statusDownloads() - if not downloads: - return ["INFO: There are no active downloads currently."] - - temp_progress = "" - lines = ["ID - Name - Status - Speed - ETA - Progress"] - for data in downloads: - - if data.status == 5: - temp_progress = data.format_wait - else: - temp_progress = "%d%% (%s)" % (data.percent, data.format_size) - - lines.append("#%d - %s - %s - %s - %s - %s" % - ( - data.fid, - data.name, - data.statusmsg, - "%s/s" % formatSize(data.speed), - "%s" % data.format_eta, - temp_progress - )) - return lines - - - def event_queue(self, args): - ps = self.core.api.getQueueData() - - if not ps: - return ["INFO: There are no packages in queue."] - - lines = [] - for pack in ps: - lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.links))) - - return lines - - - def event_collector(self, args): - ps = self.core.api.getCollectorData() - if not ps: - return ["INFO: No packages in collector!"] - - lines = [] - for pack in ps: - lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.links))) - - return lines - - - def event_info(self, args): - if not args: - return ["ERROR: Use info like this: info <id>"] - - info = None - try: - info = self.core.api.getFileData(int(args[0])) - - except FileDoesNotExists: - return ["ERROR: Link doesn't exists."] - - return ['LINK #%s: %s (%s) [%s][%s]' % (info.fid, info.name, info.format_size, info.statusmsg, info.plugin)] - - - def event_packinfo(self, args): - if not args: - return ["ERROR: Use packinfo like this: packinfo <id>"] - - lines = [] - pack = None - try: - pack = self.core.api.getPackageData(int(args[0])) - - except PackageDoesNotExists: - return ["ERROR: Package doesn't exists."] - - id = args[0] - - self.more = [] - - lines.append('PACKAGE #%s: "%s" with %d links' % (id, pack.name, len(pack.links))) - for pyfile in pack.links: - self.more.append('LINK #%s: %s (%s) [%s][%s]' % (pyfile.fid, pyfile.name, pyfile.format_size, - pyfile.statusmsg, pyfile.plugin)) - - if len(self.more) < 6: - lines.extend(self.more) - self.more = [] - else: - lines.extend(self.more[:6]) - self.more = self.more[6:] - lines.append("%d more links do display." % len(self.more)) - - return lines - - - def event_more(self, args): - if not self.more: - return ["No more information to display."] - - lines = self.more[:6] - self.more = self.more[6:] - lines.append("%d more links do display." % len(self.more)) - - return lines - - - def event_start(self, args): - self.core.api.unpauseServer() - return ["INFO: Starting downloads."] - - - def event_stop(self, args): - self.core.api.pauseServer() - return ["INFO: No new downloads will be started."] - - - def event_add(self, args): - if len(args) < 2: - return ['ERROR: Add links like this: "add <packagename|id> links". ', - "This will add the link <link> to to the package <package> / the package with id <id>!"] - - pack = args[0].strip() - links = [x.strip() for x in args[1:]] - - count_added = 0 - count_failed = 0 - try: - id = int(pack) - pack = self.core.api.getPackageData(id) - if not pack: - return ["ERROR: Package doesn't exists."] - - #TODO add links - - return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack['name'], id)] - - except: - # create new package - id = self.core.api.addPackage(pack, links, 1) - return ["INFO: Created new Package %s [#%d] with %d links." % (pack, id, len(links))] - - - def event_del(self, args): - if len(args) < 2: - return ["ERROR: Use del command like this: del -p|-l <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] - - if args[0] == "-p": - ret = self.core.api.deletePackages(map(int, args[1:])) - return ["INFO: Deleted %d packages!" % len(args[1:])] - - elif args[0] == "-l": - ret = self.core.api.delLinks(map(int, args[1:])) - return ["INFO: Deleted %d links!" % len(args[1:])] - - else: - return ["ERROR: Use del command like this: del <-p|-l> <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] - - - def event_push(self, args): - if not args: - return ["ERROR: Push package to queue like this: push <package id>"] - - id = int(args[0]) - try: - info = self.core.api.getPackageInfo(id) - except PackageDoesNotExists: - return ["ERROR: Package #%d does not exist." % id] - - self.core.api.pushToQueue(id) - return ["INFO: Pushed package #%d to queue." % id] - - - def event_pull(self, args): - if not args: - return ["ERROR: Pull package from queue like this: pull <package id>."] - - id = int(args[0]) - if not self.core.api.getPackageData(id): - return ["ERROR: Package #%d does not exist." % id] - - self.core.api.pullFromQueue(id) - return ["INFO: Pulled package #%d from queue to collector." % id] - - - def event_c(self, args): - """ captcha answer """ - if not args: - return ["ERROR: Captcha ID missing."] - - task = self.core.captchaManager.getTaskByID(args[0]) - if not task: - return ["ERROR: Captcha Task with ID %s does not exists." % args[0]] - - task.setResult(" ".join(args[1:])) - return ["INFO: Result %s saved." % " ".join(args[1:])] - - - def event_help(self, args): - lines = ["The following commands are available:", - "add <package|packid> <links> [...] Adds link to package. (creates new package if it does not exist)", - "queue Shows all packages in the queue", - "collector Shows all packages in collector", - "del -p|-l <id> [...] Deletes all packages|links with the ids specified", - "info <id> Shows info of the link with id <id>", - "packinfo <id> Shows info of the package with id <id>", - "more Shows more info when the result was truncated", - "start Starts all downloads", - "stop Stops the download (but not abort active downloads)", - "push <id> Push package to queue", - "pull <id> Pull package from queue", - "status Show general download status", - "help Shows this help message"] - return lines - - -class IRCError(Exception): - - def __init__(self, value): - self.value = value - - - def __str__(self): - return repr(self.value) diff --git a/module/plugins/hooks/ImageTyperz.py b/module/plugins/hooks/ImageTyperz.py deleted file mode 100644 index b00c5118f..000000000 --- a/module/plugins/hooks/ImageTyperz.py +++ /dev/null @@ -1,157 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import re - -from base64 import b64encode -from pycurl import FORM_FILE, LOW_SPEED_TIME -from thread import start_new_thread - -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook - - -class ImageTyperzException(Exception): - - def __init__(self, err): - self.err = err - - - def getCode(self): - return self.err - - - def __str__(self): - return "<ImageTyperzException %s>" % self.err - - - def __repr__(self): - return "<ImageTyperzException %s>" % self.err - - -class ImageTyperz(Hook): - __name__ = "ImageTyperz" - __type__ = "hook" - __version__ = "0.04" - - __config__ = [("username", "str", "Username", ""), - ("passkey", "password", "Password", ""), - ("force", "bool", "Force IT even if client is connected", False)] - - __description__ = """Send captchas to ImageTyperz.com""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org"), - ("zoidberg", "zoidberg@mujmail.cz")] - - - SUBMIT_URL = "http://captchatypers.com/Forms/UploadFileAndGetTextNEW.ashx" - RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx" - GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx" - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - - def getCredits(self): - res = getURL(self.GETCREDITS_URL, - post={'action': "REQUESTBALANCE", - 'username': self.getConfig("username"), - 'password': self.getConfig("passkey")}) - - if res.startswith('ERROR'): - raise ImageTyperzException(res) - - try: - balance = float(res) - except: - raise ImageTyperzException("Invalid response") - - self.logInfo(_("Account balance: $%s left") % res) - return balance - - - def submit(self, captcha, captchaType="file", match=None): - req = getRequest() - #raise timeout threshold - req.c.setopt(LOW_SPEED_TIME, 80) - - try: - #workaround multipart-post bug in HTTPRequest.py - if re.match("^\w*$", self.getConfig("passkey")): - multipart = True - data = (FORM_FILE, captcha) - else: - multipart = False - with open(captcha, 'rb') as f: - data = f.read() - data = b64encode(data) - - res = req.load(self.SUBMIT_URL, - post={'action': "UPLOADCAPTCHA", - 'username': self.getConfig("username"), - 'password': self.getConfig("passkey"), "file": data}, - multipart=multipart) - finally: - req.close() - - if res.startswith("ERROR"): - raise ImageTyperzException(res) - else: - data = res.split('|') - if len(data) == 2: - ticket, result = data - else: - raise ImageTyperzException("Unknown response: %s" % res) - - return ticket, result - - - def newCaptchaTask(self, task): - if "service" in task.data: - return False - - if not task.isTextual(): - return False - - if not self.getConfig("username") or not self.getConfig("passkey"): - return False - - if self.core.isClientConnected() and not self.getConfig("force"): - return False - - if self.getCredits() > 0: - task.handler.append(self) - task.data['service'] = self.__name__ - task.setWaiting(100) - start_new_thread(self.processCaptcha, (task,)) - - else: - self.logInfo(_("Your %s account has not enough credits") % self.__name__) - - - def captchaInvalid(self, task): - if task.data['service'] == self.__name__ and "ticket" in task.data: - res = getURL(self.RESPOND_URL, - post={'action': "SETBADIMAGE", - 'username': self.getConfig("username"), - 'password': self.getConfig("passkey"), - 'imageid': task.data['ticket']}) - - if res == "SUCCESS": - self.logInfo(_("Bad captcha solution received, requested refund")) - else: - self.logError(_("Bad captcha solution received, refund request failed"), res) - - - def processCaptcha(self, task): - c = task.captchaFile - try: - ticket, result = self.submit(c) - except ImageTyperzException, e: - task.error = e.getCode() - return - - task.data['ticket'] = ticket - task.setResult(result) diff --git a/module/plugins/hooks/LinkdecrypterCom.py b/module/plugins/hooks/LinkdecrypterCom.py deleted file mode 100644 index 0c5f6e754..000000000 --- a/module/plugins/hooks/LinkdecrypterCom.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.network.RequestFactory import getURL -from module.plugins.Hook import Hook -from module.utils import remove_chars - - -class LinkdecrypterCom(Hook): - __name__ = "LinkdecrypterCom" - __type__ = "hook" - __version__ = "0.20" - - __description__ = """Linkdecrypter.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] - - - def coreReady(self): - try: - self.loadPatterns() - except Exception, e: - self.logError(e) - - - def loadPatterns(self): - html = getURL("http://linkdecrypter.com/") - - m = re.search(r'<title>', html) - if m is None: - self.logError(_("Linkdecrypter site is down")) - return - - m = re.search(r'<b>Supported\(\d+\)</b>: <i>([^+<]*)', html) - if m is None: - self.logError(_("Crypter list not found")) - return - - builtin = [name.lower() for name in self.core.pluginManager.crypterPlugins.keys()] - builtin.append("downloadserienjunkiesorg") - - crypter_pattern = re.compile("(\w[\w.-]+)") - online = [] - for crypter in m.group(1).split(', '): - m = re.match(crypter_pattern, crypter) - if m and remove_chars(m.group(1), "-.") not in builtin: - online.append(m.group(1).replace(".", "\\.")) - - if not online: - self.logError(_("Crypter list is empty")) - return - - regexp = r'https?://([^.]+\.)*?(%s)/.*' % '|'.join(online) - - dict = self.core.pluginManager.crypterPlugins[self.__name__] - dict['pattern'] = regexp - dict['re'] = re.compile(regexp) - - self.logDebug("Loaded pattern: %s" % regexp) diff --git a/module/plugins/hooks/LinksnappyCom.py b/module/plugins/hooks/LinksnappyCom.py deleted file mode 100644 index 82edc30fd..000000000 --- a/module/plugins/hooks/LinksnappyCom.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class LinksnappyCom(MultiHoster): - __name__ = "LinksnappyCom" - __type__ = "hook" - __version__ = "0.01" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to standard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Linksnappy.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("stickell", "l.stickell@yahoo.it")] - - - def getHoster(self): - json_data = getURL("http://gen.linksnappy.com/lseAPI.php", get={'act': "FILEHOSTS"}) - json_data = json_loads(json_data) - - return json_data['return'].keys() diff --git a/module/plugins/hooks/MegaDebridEu.py b/module/plugins/hooks/MegaDebridEu.py deleted file mode 100644 index 4f627b7e9..000000000 --- a/module/plugins/hooks/MegaDebridEu.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class MegaDebridEu(MultiHoster): - __name__ = "MegaDebridEu" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("unloadFailing", "bool", "Revert to standard download if download fails", False)] - - __description__ = """mega-debrid.eu hook plugin""" - __license__ = "GPLv3" - __authors__ = [("D.Ducatel", "dducatel@je-geek.fr")] - - - def getHoster(self): - reponse = getURL("http://www.mega-debrid.eu/api.php", get={'action': "getHosters"}) - json_data = json_loads(reponse) - - if json_data['response_code'] == "ok": - host_list = [element[0] for element in json_data['hosters']] - else: - self.logError(_("Unable to retrieve hoster list")) - host_list = list() - - return host_list diff --git a/module/plugins/hooks/MergeFiles.py b/module/plugins/hooks/MergeFiles.py deleted file mode 100644 index e6f8bb26f..000000000 --- a/module/plugins/hooks/MergeFiles.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import re - -from traceback import print_exc - -from module.plugins.Hook import Hook, threaded -from module.utils import save_join, fs_encode - - -class MergeFiles(Hook): - __name__ = "MergeFiles" - __type__ = "hook" - __version__ = "0.12" - - __config__ = [("activated", "bool", "Activated", True)] - - __description__ = """Merges parts splitted with hjsplit""" - __license__ = "GPLv3" - __authors__ = [("and9000", "me@has-no-mail.com")] - - - BUFFER_SIZE = 4096 - - - def setup(self): - # nothing to do - pass - - - @threaded - def packageFinished(self, pack): - files = {} - fid_dict = {} - for fid, data in pack.getChildren().iteritems(): - if re.search("\.\d{3}$", data['name']): - if data['name'][:-4] not in files: - files[data['name'][:-4]] = [] - files[data['name'][:-4]].append(data['name']) - files[data['name'][:-4]].sort() - fid_dict[data['name']] = fid - - download_folder = self.config['general']['download_folder'] - - if self.config['general']['folder_per_package']: - download_folder = save_join(download_folder, pack.folder) - - for name, file_list in files.iteritems(): - self.logInfo(_("Starting merging of"), name) - final_file = open(save_join(download_folder, name), "wb") - - for splitted_file in file_list: - self.logDebug("Merging part", splitted_file) - pyfile = self.core.files.getFile(fid_dict[splitted_file]) - pyfile.setStatus("processing") - try: - s_file = open(os.path.join(download_folder, splitted_file), "rb") - size_written = 0 - s_file_size = int(os.path.getsize(os.path.join(download_folder, splitted_file))) - while True: - f_buffer = s_file.read(self.BUFFER_SIZE) - if f_buffer: - final_file.write(f_buffer) - size_written += self.BUFFER_SIZE - pyfile.setProgress((size_written * 100) / s_file_size) - else: - break - s_file.close() - self.logDebug("Finished merging part", splitted_file) - except Exception, e: - print_exc() - finally: - pyfile.setProgress(100) - pyfile.setStatus("finished") - pyfile.release() - - final_file.close() - self.logInfo(_("Finished merging of"), name) diff --git a/module/plugins/hooks/MultiHome.py b/module/plugins/hooks/MultiHome.py deleted file mode 100644 index 228e6027d..000000000 --- a/module/plugins/hooks/MultiHome.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- - -from time import time - -from module.plugins.Hook import Hook - - -class MultiHome(Hook): - __name__ = "MultiHome" - __type__ = "hook" - __version__ = "0.11" - - __config__ = [("interfaces", "str", "Interfaces", "None")] - - __description__ = """Ip address changer""" - __license__ = "GPLv3" - __authors__ = [("mkaay", "mkaay@mkaay.de")] - - - def setup(self): - self.register = {} - self.interfaces = [] - self.parseInterfaces(self.getConfig("interfaces").split(";")) - if not self.interfaces: - self.parseInterfaces([self.config['download']['interface']]) - self.setConfig("interfaces", self.toConfig()) - - - def toConfig(self): - return ";".join([i.adress for i in self.interfaces]) - - - def parseInterfaces(self, interfaces): - for interface in interfaces: - if not interface or str(interface).lower() == "none": - continue - self.interfaces.append(Interface(interface)) - - - def coreReady(self): - requestFactory = self.core.requestFactory - oldGetRequest = requestFactory.getRequest - - - def getRequest(pluginName, account=None): - iface = self.bestInterface(pluginName, account) - if iface: - iface.useFor(pluginName, account) - requestFactory.iface = lambda: iface.adress - self.logDebug("Using address", iface.adress) - return oldGetRequest(pluginName, account) - - requestFactory.getRequest = getRequest - - - def bestInterface(self, pluginName, account): - best = None - for interface in self.interfaces: - if not best or interface.lastPluginAccess(pluginName, account) < best.lastPluginAccess(pluginName, account): - best = interface - return best - - -class Interface(object): - - def __init__(self, adress): - self.adress = adress - self.history = {} - - - def lastPluginAccess(self, pluginName, account): - if (pluginName, account) in self.history: - return self.history[(pluginName, account)] - return 0 - - - def useFor(self, pluginName, account): - self.history[(pluginName, account)] = time() - - - def __repr__(self): - return "<Interface - %s>" % self.adress diff --git a/module/plugins/hooks/MultishareCz.py b/module/plugins/hooks/MultishareCz.py deleted file mode 100644 index 0e651393d..000000000 --- a/module/plugins/hooks/MultishareCz.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class MultishareCz(MultiHoster): - __name__ = "MultishareCz" - __type__ = "hook" - __version__ = "0.04" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "uloz.to")] - - __description__ = """MultiShare.cz hook plugin""" - __license__ = "GPLv3" - __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] - - - HOSTER_PATTERN = r'<img class="logo-shareserveru"[^>]*?alt="([^"]+)"></td>\s*<td class="stav">[^>]*?alt="OK"' - - - def getHoster(self): - page = getURL("http://www.multishare.cz/monitoring/") - return re.findall(self.HOSTER_PATTERN, page) diff --git a/module/plugins/hooks/MyfastfileCom.py b/module/plugins/hooks/MyfastfileCom.py deleted file mode 100644 index 0cf2c6c22..000000000 --- a/module/plugins/hooks/MyfastfileCom.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class MyfastfileCom(MultiHoster): - __name__ = "MyfastfileCom" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to standard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Myfastfile.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("stickell", "l.stickell@yahoo.it")] - - - def getHoster(self): - json_data = getURL("http://myfastfile.com/api.php", get={'hosts': ""}, decode=True) - self.logDebug("JSON data", json_data) - json_data = json_loads(json_data) - - return json_data['hosts'] diff --git a/module/plugins/hooks/OverLoadMe.py b/module/plugins/hooks/OverLoadMe.py deleted file mode 100644 index baa9b0e0a..000000000 --- a/module/plugins/hooks/OverLoadMe.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class OverLoadMe(MultiHoster): - __name__ = "OverLoadMe" - __type__ = "hook" - __version__ = "0.01" - - __config__ = [("https", "bool", "Enable HTTPS", True), - ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to standard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 12)] - - __description__ = """Over-Load.me hook plugin""" - __license__ = "GPLv3" - __authors__ = [("marley", "marley@over-load.me")] - - - def getHoster(self): - https = "https" if self.getConfig("https") else "http" - page = getURL(https + "://api.over-load.me/hoster.php", - get={'auth': "0001-cb1f24dadb3aa487bda5afd3b76298935329be7700cd7-5329be77-00cf-1ca0135f"}).replace("\"", "").strip() - self.logDebug("Hosterlist", page) - - return [x.strip() for x in page.split(",") if x.strip()] diff --git a/module/plugins/hooks/PremiumTo.py b/module/plugins/hooks/PremiumTo.py deleted file mode 100644 index 7be46945f..000000000 --- a/module/plugins/hooks/PremiumTo.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class PremiumTo(MultiHoster): - __name__ = "PremiumTo" - __type__ = "hook" - __version__ = "0.04" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for downloads from supported hosters:", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "")] - - __description__ = """Premium.to hook plugin""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org"), - ("zoidberg", "zoidberg@mujmail.cz"), - ("stickell", "l.stickell@yahoo.it")] - - - def getHoster(self): - page = getURL("http://premium.to/api/hosters.php", - get={'username': self.account.username, 'password': self.account.password}) - return [x.strip() for x in page.replace("\"", "").split(";")] - - - def coreReady(self): - self.account = self.core.accountManager.getAccountPlugin("PremiumTo") - - user = self.account.selectAccount()[0] - - if not user: - self.logError(_("Please add your premium.to account first and restart pyLoad")) - return - - return MultiHoster.coreReady(self) diff --git a/module/plugins/hooks/PremiumizeMe.py b/module/plugins/hooks/PremiumizeMe.py deleted file mode 100644 index c18e8cf8e..000000000 --- a/module/plugins/hooks/PremiumizeMe.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class PremiumizeMe(MultiHoster): - __name__ = "PremiumizeMe" - __type__ = "hook" - __version__ = "0.12" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to stanard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Premiumize.me hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Florian Franzen", "FlorianFranzen@gmail.com")] - - - def getHoster(self): - # If no accounts are available there will be no hosters available - if not self.account or not self.account.canUse(): - return [] - - # Get account data - (user, data) = self.account.selectAccount() - - # Get supported hosters list from premiumize.me using the - # json API v1 (see https://secure.premiumize.me/?show=api) - answer = getURL("https://api.premiumize.me/pm-api/v1.php" - get={'method': "hosterlist", 'params[login]': user, 'params[pass]': data['password']}) - data = json_loads(answer) - - # If account is not valid thera are no hosters available - if data['status'] != 200: - return [] - - # Extract hosters from json file - return data['result']['hosterlist'] - - - def coreReady(self): - # Get account plugin and check if there is a valid account available - self.account = self.core.accountManager.getAccountPlugin("PremiumizeMe") - if not self.account.canUse(): - self.account = None - self.logError(_("Please add a valid premiumize.me account first and restart pyLoad")) - return - - # Run the overwriten core ready which actually enables the multihoster hook - return MultiHoster.coreReady(self) diff --git a/module/plugins/hooks/RPNetBiz.py b/module/plugins/hooks/RPNetBiz.py deleted file mode 100644 index e38aa8ea0..000000000 --- a/module/plugins/hooks/RPNetBiz.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class RPNetBiz(MultiHoster): - __name__ = "RPNetBiz" - __type__ = "hook" - __version__ = "0.1" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to stanard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """RPNet.biz hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Dman", "dmanugm@gmail.com")] - - - def getHoster(self): - # No hosts supported if no account - if not self.account or not self.account.canUse(): - return [] - - # Get account data - (user, data) = self.account.selectAccount() - - res = getURL("https://premium.rpnet.biz/client_api.php", - get={'username': user, 'password': data['password'], 'action': "showHosterList"}) - hoster_list = json_loads(res) - - # If account is not valid thera are no hosters available - if 'error' in hoster_list: - return [] - - # Extract hosters from json file - return hoster_list['hosters'] - - - def coreReady(self): - # Get account plugin and check if there is a valid account available - self.account = self.core.accountManager.getAccountPlugin("RPNetBiz") - if not self.account.canUse(): - self.account = None - self.logError(_("Please enter your %s account or deactivate this plugin") % "rpnet") - return - - # Run the overwriten core ready which actually enables the multihoster hook - return MultiHoster.coreReady(self) diff --git a/module/plugins/hooks/RealdebridCom.py b/module/plugins/hooks/RealdebridCom.py deleted file mode 100644 index 50cc81f0c..000000000 --- a/module/plugins/hooks/RealdebridCom.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class RealdebridCom(MultiHoster): - __name__ = "RealdebridCom" - __type__ = "hook" - __version__ = "0.43" - - __config__ = [("https", "bool", "Enable HTTPS", False), - ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to stanard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Real-Debrid.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Devirex Hazzard", "naibaf_11@yahoo.de")] - - - def getHoster(self): - https = "https" if self.getConfig("https") else "http" - page = getURL(https + "://real-debrid.com/api/hosters.php").replace("\"", "").strip() - - return [x.strip() for x in page.split(",") if x.strip()] diff --git a/module/plugins/hooks/RehostTo.py b/module/plugins/hooks/RehostTo.py deleted file mode 100644 index 1bf7d2555..000000000 --- a/module/plugins/hooks/RehostTo.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class RehostTo(MultiHoster): - __name__ = "RehostTo" - __type__ = "hook" - __version__ = "0.43" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to stanard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24)] - - __description__ = """Rehost.to hook plugin""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org")] - - - def getHoster(self): - page = getURL("http://rehost.to/api.php", - get={'cmd': "get_supported_och_dl", 'long_ses': self.long_ses}) - return [x.strip() for x in page.replace("\"", "").split(",")] - - - def coreReady(self): - self.account = self.core.accountManager.getAccountPlugin("RehostTo") - - user = self.account.selectAccount()[0] - - if not user: - self.logError(_("Please add your rehost.to account first and restart pyLoad")) - return - - data = self.account.getAccountInfo(user) - self.ses = data['ses'] - self.long_ses = data['long_ses'] - - return MultiHoster.coreReady(self) diff --git a/module/plugins/hooks/RestartFailed.py b/module/plugins/hooks/RestartFailed.py deleted file mode 100644 index 07fb80967..000000000 --- a/module/plugins/hooks/RestartFailed.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.Hook import Hook - - -class RestartFailed(Hook): - __name__ = "RestartFailed" - __type__ = "hook" - __version__ = "1.57" - - __config__ = [("interval", "int", "Check interval in minutes", 90)] - - __description__ = """Periodically restart all failed downloads in queue""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - # event_list = ["pluginConfigChanged"] - - MIN_INTERVAL = 15 * 60 #: 15m minimum check interval (value is in seconds) - - - def pluginConfigChanged(self, plugin, name, value): - if name == "interval": - interval = value * 60 - if self.MIN_INTERVAL <= interval != self.interval: - self.core.scheduler.removeJob(self.cb) - self.interval = interval - self.initPeriodical() - else: - self.logDebug("Invalid interval value, kept current") - - - def periodical(self): - self.logDebug(_("Restart failed downloads")) - self.core.api.restartFailed() - - - def setup(self): - self.interval = self.MIN_INTERVAL - - - def coreReady(self): - self.pluginConfigChanged(self.__name__, "interval", self.getConfig("interval")) diff --git a/module/plugins/hooks/SimplyPremiumCom.py b/module/plugins/hooks/SimplyPremiumCom.py deleted file mode 100644 index cc7e9183c..000000000 --- a/module/plugins/hooks/SimplyPremiumCom.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class SimplyPremiumCom(MultiHoster): - __name__ = "SimplyPremiumCom" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("activated", "bool", "Activated", "False"), - ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to standard download if download fails", "False"), - ("interval", "int", "Reload interval in hours (0 to disable)", "24")] - - __description__ = """Simply-Premium.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("EvolutionClip", "evolutionclip@live.de")] - - - def getHoster(self): - json_data = getURL("http://www.simply-premium.com/api/hosts.php", get={'format': "json", 'online': 1}) - json_data = json_loads(json_data) - - host_list = [element['regex'] for element in json_data['result']] - - return host_list diff --git a/module/plugins/hooks/SimplydebridCom.py b/module/plugins/hooks/SimplydebridCom.py deleted file mode 100644 index 173206e75..000000000 --- a/module/plugins/hooks/SimplydebridCom.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class SimplydebridCom(MultiHoster): - __name__ = "SimplydebridCom" - __type__ = "hook" - __version__ = "0.01" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "")] - - __description__ = """Simply-Debrid.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] - - - def getHoster(self): - page = getURL("http://simply-debrid.com/api.php", get={'list': 1}) - return [x.strip() for x in page.rstrip(';').replace("\"", "").split(";")] diff --git a/module/plugins/hooks/UnSkipOnFail.py b/module/plugins/hooks/UnSkipOnFail.py deleted file mode 100644 index f97d12431..000000000 --- a/module/plugins/hooks/UnSkipOnFail.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- - -from os.path import basename - -from module.PyFile import PyFile -from module.plugins.Hook import Hook -from module.utils import fs_encode - - -class UnSkipOnFail(Hook): - __name__ = "UnSkipOnFail" - __type__ = "hook" - __version__ = "0.01" - - __config__ = [("activated", "bool", "Activated", True)] - - __description__ = """When a download fails, restart skipped duplicates""" - __license__ = "GPLv3" - __authors__ = [("hagg", None)] - - - def downloadFailed(self, pyfile): - pyfile_name = basename(pyfile.name) - pid = pyfile.package().id - msg = _('look for skipped duplicates for %s (pid:%s)') - self.logInfo(msg % (pyfile_name, pid)) - dups = self.findDuplicates(pyfile) - for link in dups: - # check if link is "skipped"(=4) - if link.status == 4: - lpid = link.packageID - self.logInfo(_('restart "%s" (pid:%s)') % (pyfile_name, lpid)) - self.setLinkStatus(link, "queued") - - - def findDuplicates(self, pyfile): - """ Search all packages for duplicate links to "pyfile". - Duplicates are links that would overwrite "pyfile". - To test on duplicity the package-folder and link-name - of twolinks are compared (basename(link.name)). - So this method returns a list of all links with equal - package-folders and filenames as "pyfile", but except - the data for "pyfile" iotselöf. - It does MOT check the link's status. - """ - dups = [] - pyfile_name = fs_encode(basename(pyfile.name)) - # get packages (w/o files, as most file data is useless here) - queue = self.core.api.getQueue() - for package in queue: - # check if package-folder equals pyfile's package folder - if fs_encode(package.folder) == fs_encode(pyfile.package().folder): - # now get packaged data w/ files/links - pdata = self.core.api.getPackageData(package.pid) - if pdata.links: - for link in pdata.links: - link_name = fs_encode(basename(link.name)) - # check if link name collides with pdata's name - if link_name == pyfile_name: - # at last check if it is not pyfile itself - if link.fid != pyfile.id: - dups.append(link) - return dups - - - def setLinkStatus(self, link, new_status): - """ Change status of "link" to "new_status". - "link" has to be a valid FileData object, - "new_status" has to be a valid status name - (i.e. "queued" for this Plugin) - It creates a temporary PyFile object using - "link" data, changes its status, and tells - the core.files-manager to save its data. - """ - pyfile = PyFile(self.core.files, - link.fid, - link.url, - link.name, - link.size, - link.status, - link.error, - link.plugin, - link.packageID, - link.order) - pyfile.setStatus(new_status) - self.core.files.save() - pyfile.release() diff --git a/module/plugins/hooks/UnrestrictLi.py b/module/plugins/hooks/UnrestrictLi.py deleted file mode 100644 index d87265ef4..000000000 --- a/module/plugins/hooks/UnrestrictLi.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class UnrestrictLi(MultiHoster): - __name__ = "UnrestrictLi" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", ""), - ("unloadFailing", "bool", "Revert to standard download if download fails", False), - ("interval", "int", "Reload interval in hours (0 to disable)", 24), - ("history", "bool", "Delete History", False)] - - __description__ = """Unrestrict.li hook plugin""" - __license__ = "GPLv3" - __authors__ = [("stickell", "l.stickell@yahoo.it")] - - - def getHoster(self): - json_data = getURL("http://unrestrict.li/api/jdownloader/hosts.php", get={'format': "json"}) - json_data = json_loads(json_data) - - host_list = [element['host'] for element in json_data['result']] - - return host_list diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py deleted file mode 100644 index c72699228..000000000 --- a/module/plugins/hooks/UpdateManager.py +++ /dev/null @@ -1,310 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import re -import sys - -from operator import itemgetter -from os import path, remove, stat - -from module.network.RequestFactory import getURL -from module.plugins.Hook import Expose, Hook, threaded -from module.utils import save_join - - -class UpdateManager(Hook): - __name__ = "UpdateManager" - __type__ = "hook" - __version__ = "0.42" - - __config__ = [("activated" , "bool" , "Activated" , True ), - ("mode" , "pyLoad + plugins;plugins only", "Check updates for" , "pyLoad + plugins"), - ("interval" , "int" , "Check interval in hours" , 8 ), - ("autorestart" , "bool" , "Automatically restart pyLoad when required" , True ), - ("reloadplugins", "bool" , "Monitor plugins for code changes in debug mode", True ), - ("nodebugupdate", "bool" , "Don't check for updates in debug mode" , True )] - - __description__ = """ Check for updates """ - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - # event_list = ["pluginConfigChanged"] - - SERVER_URL = "http://updatemanager.pyload.org" - VERSION = re.compile(r'__version__.*=.*("|\')([\d.]+)') - MIN_INTERVAL = 3 * 60 * 60 #: 3h minimum check interval (value is in seconds) - - - def pluginConfigChanged(self, plugin, name, value): - if name == "interval": - interval = value * 60 * 60 - if self.MIN_INTERVAL <= interval != self.interval: - self.core.scheduler.removeJob(self.cb) - self.interval = interval - self.initPeriodical() - else: - self.logDebug("Invalid interval value, kept current") - - elif name == "reloadplugins": - if self.cb2: - self.core.scheduler.removeJob(self.cb2) - if value is True and self.core.debug: - self.periodical2() - - - def coreReady(self): - self.pluginConfigChanged(self.__name__, "interval", self.getConfig("interval")) - x = lambda: self.pluginConfigChanged(self.__name__, "reloadplugins", self.getConfig("reloadplugins")) - self.core.scheduler.addJob(10, x, threaded=False) - - - def unload(self): - self.pluginConfigChanged(self.__name__, "reloadplugins", False) - - - def setup(self): - self.cb2 = None - self.interval = self.MIN_INTERVAL - self.updating = False - self.info = {'pyload': False, 'version': None, 'plugins': False} - self.mtimes = {} #: store modification time for each plugin - - - def periodical2(self): - if not self.updating: - self.autoreloadPlugins() - - self.cb2 = self.core.scheduler.addJob(4, self.periodical2, threaded=False) - - - @Expose - def autoreloadPlugins(self): - """ reload and reindex all modified plugins """ - modules = filter( - lambda m: m and (m.__name__.startswith("module.plugins.") or - m.__name__.startswith("userplugins.")) and - m.__name__.count(".") >= 2, sys.modules.itervalues() - ) - - reloads = [] - - for m in modules: - root, type, name = m.__name__.rsplit(".", 2) - id = (type, name) - if type in self.core.pluginManager.plugins: - f = m.__file__.replace(".pyc", ".py") - if not path.isfile(f): - continue - - mtime = stat(f).st_mtime - - if id not in self.mtimes: - self.mtimes[id] = mtime - elif self.mtimes[id] < mtime: - reloads.append(id) - self.mtimes[id] = mtime - - return True if self.core.pluginManager.reloadPlugins(reloads) else False - - - def periodical(self): - if not self.info['pyload'] and not (self.getConfig("nodebugupdate") and self.core.debug): - self.updateThread() - - - def server_request(self): - try: - return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines() - except: - self.logWarning(_("Unable to contact server to get updates")) - - - @threaded - def updateThread(self): - self.updating = True - - status = self.update(onlyplugin=self.getConfig("mode") == "plugins only") - - if status is 2 and self.getConfig("autorestart"): - self.core.api.restart() - else: - self.updating = False - - - @Expose - def updatePlugins(self): - """ simple wrapper for calling plugin update quickly """ - return self.update(onlyplugin=True) - - - @Expose - def update(self, onlyplugin=False): - """ check for updates """ - data = self.server_request() - - if not data: - exitcode = 0 - - elif data[0] == "None": - self.logInfo(_("No new pyLoad version available")) - updates = data[1:] - exitcode = self._updatePlugins(updates) - - elif onlyplugin: - exitcode = 0 - - else: - newversion = data[0] - self.logInfo(_("*** New pyLoad Version %s available ***") % newversion) - self.logInfo(_("*** Get it here: https://github.com/pyload/pyload/releases ***")) - exitcode = 3 - self.info['pyload'] = True - self.info['version'] = newversion - - return exitcode #: 0 = No plugins updated; 1 = Plugins updated; 2 = Plugins updated, but restart required; 3 = No plugins updated, new pyLoad version available - - - def _updatePlugins(self, updates): - """ check for plugin updates """ - - if self.info['plugins']: - return False #: plugins were already updated - - exitcode = 0 - updated = [] - - url = updates[0] - schema = updates[1].split('|') - - if "BLACKLIST" in updates: - blacklist = updates[updates.index('BLACKLIST') + 1:] - updates = updates[2:updates.index('BLACKLIST')] - else: - blacklist = None - updates = updates[2:] - - upgradable = [dict(zip(schema, x.split('|'))) for x in updates] - blacklisted = [(x.split('|')[0], x.split('|')[1].rsplit('.', 1)[0]) for x in blacklist] if blacklist else [] - - if blacklist: - # Protect UpdateManager from self-removing - try: - blacklisted.remove(("hook", "UpdateManager")) - except: - pass - - for t, n in blacklisted: - for idx, plugin in enumerate(upgradable): - if n == plugin['name'] and t == plugin['type']: - upgradable.pop(idx) - break - - for t, n in self.removePlugins(sorted(blacklisted)): - self.logInfo(_("Removed blacklisted plugin [%(type)s] %(name)s") % { - 'type': t, - 'name': n, - }) - - for plugin in sorted(upgradable, key=itemgetter("type", "name")): - filename = plugin['name'] - prefix = plugin['type'] - version = plugin['version'] - - if filename.endswith(".pyc"): - name = filename[:filename.find("_")] - else: - name = filename.replace(".py", "") - - #@TODO: obsolete after 0.4.10 - if prefix.endswith("s"): - type = prefix[:-1] - else: - type = prefix - - plugins = getattr(self.core.pluginManager, "%sPlugins" % type) - - oldver = float(plugins[name]['v']) if name in plugins else None - newver = float(version) - - if not oldver: - msg = "New plugin: [%(type)s] %(name)s (v%(newver).2f)" - elif newver > oldver: - msg = "New version of plugin: [%(type)s] %(name)s (v%(oldver).2f -> v%(newver).2f)" - else: - continue - - self.logInfo(_(msg) % {'type' : type, - 'name' : name, - 'oldver': oldver, - 'newver': newver}) - try: - content = getURL(url % plugin) - m = self.VERSION.search(content) - - if m and m.group(2) == version: - with open(save_join("userplugins", prefix, filename), "wb") as f: - f.write(content) - - updated.append((prefix, name)) - else: - raise Exception, _("Version mismatch") - - except Exception, e: - self.logError(_("Error updating plugin: %s") % filename, str(e)) - - if updated: - reloaded = self.core.pluginManager.reloadPlugins(updated) - if reloaded: - self.logInfo(_("Plugins updated and reloaded")) - exitcode = 1 - else: - self.logInfo(_("*** Plugins have been updated, but need a pyLoad restart to be reloaded ***")) - self.info['plugins'] = True - exitcode = 2 - else: - self.logInfo(_("No plugin updates available")) - - return exitcode #: 0 = No plugins updated; 1 = Plugins updated; 2 = Plugins updated, but restart required - - - @Expose - def removePlugins(self, type_plugins): - """ delete plugins from disk """ - - if not type_plugins: - return - - self.logDebug("Requested deletion of plugins: %s" % type_plugins) - - removed = [] - - for type, name in type_plugins: - err = False - file = name + ".py" - - for root in ("userplugins", path.join(pypath, "module", "plugins")): - - filename = save_join(root, type, file) - try: - remove(filename) - except Exception, e: - self.logDebug("Error removing: %s" % path.basename(filename), str(e)) - err = True - - filename += "c" - if path.isfile(filename): - try: - if type == "hook": - self.manager.deactivateHook(name) - remove(filename) - except Exception, e: - self.logDebug("Error removing: %s" % path.basename(filename), str(e)) - err = True - - if not err: - id = (type, name) - removed.append(id) - - return removed #: return a list of the plugins successfully removed diff --git a/module/plugins/hooks/WindowsPhoneToastNotify.py b/module/plugins/hooks/WindowsPhoneToastNotify.py deleted file mode 100644 index 053ea47d0..000000000 --- a/module/plugins/hooks/WindowsPhoneToastNotify.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- - -import httplib -import time - -from module.plugins.Hook import Hook - - -class WindowsPhoneToastNotify(Hook): - __name__ = "WindowsPhoneToastNotify" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("force", "bool", "Force even if client is connected", False), - ("pushId", "str", "pushId", ""), - ("pushUrl", "str", "pushUrl", ""), - ("pushTimeout", "int", "Timeout between notifications in seconds", 0)] - - __description__ = """Send push notifications to Windows Phone""" - __license__ = "GPLv3" - __authors__ = [("Andy Voigt", "phone-support@hotmail.de")] - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - - def getXmlData(self): - myxml = ("<?xml version='1.0' encoding='utf-8'?> <wp:Notification xmlns:wp='WPNotification'> " - "<wp:Toast> <wp:Text1>Pyload Mobile</wp:Text1> <wp:Text2>Captcha waiting!</wp:Text2> " - "</wp:Toast> </wp:Notification>") - return myxml - - - def doRequest(self): - URL = self.getConfig("pushUrl") - request = self.getXmlData() - webservice = httplib.HTTP(URL) - webservice.putrequest("POST", self.getConfig("pushId")) - webservice.putheader("Host", URL) - webservice.putheader("Content-type", "text/xml") - webservice.putheader("X-NotificationClass", "2") - webservice.putheader("X-WindowsPhone-Target", "toast") - webservice.putheader("Content-length", "%d" % len(request)) - webservice.endheaders() - webservice.send(request) - webservice.close() - self.setStorage("LAST_NOTIFY", time.time()) - - - def newCaptchaTask(self, task): - if not self.getConfig("pushId") or not self.getConfig("pushUrl"): - return False - - if self.core.isClientConnected() and not self.getConfig("force"): - return False - - if (time.time() - float(self.getStorage("LAST_NOTIFY", 0))) < self.getConf("pushTimeout"): - return False - - self.doRequest() diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py deleted file mode 100644 index fe955beb9..000000000 --- a/module/plugins/hooks/XFileSharingPro.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.Hook import Hook - - -class XFileSharingPro(Hook): - __name__ = "XFileSharingPro" - __type__ = "hook" - __version__ = "0.25" - - __config__ = [("activated", "bool", "Activated", True), - ("use_hoster_list", "bool", "Load listed hosters only", True), - ("use_crypter_list", "bool", "Load listed crypters only", False), - ("use_builtin_list", "bool", "Load built-in plugin list", True), - ("hoster_list", "str", "Hoster list (comma separated)", ""), - ("crypter_list", "str", "Crypter list (comma separated)", "")] - - __description__ = """Load XFileSharingPro based hosters and crypter which don't need a own plugin to run""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - # event_list = ["pluginConfigChanged"] - regexp = {'hoster' : (r'https?://(?:www\.)?([\w.^_]+(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', - r'https?://(?:[^/]+\.)?(%s)/(?:embed-)?\w+'), - 'crypter': (r'https?://(?:www\.)?([\w.^_]+(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:user|folder)s?/\w+', - r'https?://(?:[^/]+\.)?(%s)/(?:user|folder)s?/\w+')} - - HOSTER_LIST = [#WORKING HOSTERS: - "eyesfile.ca", "file4safe.com", "fileband.com", "filedwon.com", "filevice.com", "hostingbulk.com", - "linestorage.com", "ravishare.com", "sharesix.com", "thefile.me", "verzend.be", "xvidstage.com", - #NOT TESTED: - "101shared.com", "4upfiles.com", "filemaze.ws", "filenuke.com", "linkzhost.com", "mightyupload.com", - "rockdizfile.com", "sharebeast.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"] - CRYPTER_LIST = [] - - - # def pluginConfigChanged(self.__name__, plugin, name, value): - # self.loadPattern() - - - def coreReady(self): - self.loadPattern() - - - def loadPattern(self): - use_builtin_list = self.getConfig('use_builtin_list') - - for type, plugin in (("hoster", "XFileSharingPro"), - ("crypter", "XFileSharingProFolder")): - every_plugin = not self.getConfig("use_%s_list" % type) - - if every_plugin: - self.logInfo(_("Handling any %s I can!") % type) - pattern = self.regexp[type][0] - else: - s = self.getConfig('%s_list' % type).replace('\\', '').replace('|', ',').replace(';', ',').lower() - plugin_list = set([x.strip() for x in s.split(',')]) - - if use_builtin_list: - plugin_list |= set([x.lower() for x in getattr(self, "%s_LIST" % type.upper())]) - - plugin_list -= set(('', u'')) - - if not plugin_list: - self.logInfo(_("No %s to handle") % type) - self._unload(type, plugin) - return - - match_list = '|'.join(sorted(plugin_list)) - - len_match_list = len(plugin_list) - self.logInfo(_("Handling %d %s%s: %s") % (len_match_list, type, "" if len_match_list is 1 else "s", match_list.replace('|', ', '))) - - pattern = self.regexp[type][1] % match_list.replace('.', '\.') - - dict = self.core.pluginManager.plugins[type][plugin] - dict['pattern'] = pattern - dict['re'] = re.compile(pattern) - - self.logDebug("Loaded %s pattern: %s" % (type, pattern)) - - - def _unload(self, type, plugin): - dict = self.core.pluginManager.plugins[type][plugin] - dict['pattern'] = r'^unmatchable$' - dict['re'] = re.compile(dict['pattern']) - - - def unload(self): - for type, plugin in (("hoster", "XFileSharingPro"), - ("crypter", "XFileSharingProFolder")): - self._unload(type, plugin) diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py deleted file mode 100644 index bbeab4341..000000000 --- a/module/plugins/hooks/XMPPInterface.py +++ /dev/null @@ -1,252 +0,0 @@ -# -*- coding: utf-8 -*- - -from pyxmpp import streamtls -from pyxmpp.all import JID, Message -from pyxmpp.interface import implements -from pyxmpp.interfaces import * -from pyxmpp.jabber.client import JabberClient - -from module.plugins.hooks.IRCInterface import IRCInterface - - -class XMPPInterface(IRCInterface, JabberClient): - __name__ = "XMPPInterface" - __type__ = "hook" - __version__ = "0.11" - - __config__ = [("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"), - ("pw", "str", "Password", ""), - ("tls", "bool", "Use TLS", False), - ("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"), - ("info_file", "bool", "Inform about every file finished", False), - ("info_pack", "bool", "Inform about every package finished", True), - ("captcha", "bool", "Send captcha requests", True)] - - __description__ = """Connect to jabber and let owner perform different tasks""" - __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org")] - - - implements(IMessageHandlersProvider) - - - def __init__(self, core, manager): - IRCInterface.__init__(self, core, manager) - - self.jid = JID(self.getConfig("jid")) - password = self.getConfig("pw") - - # if bare JID is provided add a resource -- it is required - if not self.jid.resource: - self.jid = JID(self.jid.node, self.jid.domain, "pyLoad") - - if self.getConfig("tls"): - tls_settings = streamtls.TLSSettings(require=True, verify_peer=False) - auth = ("sasl:PLAIN", "sasl:DIGEST-MD5") - else: - tls_settings = None - auth = ("sasl:DIGEST-MD5", "digest") - - # setup client with provided connection information - # and identity data - JabberClient.__init__(self, self.jid, password, - disco_name="pyLoad XMPP Client", disco_type="bot", - tls_settings=tls_settings, auth_methods=auth) - - self.interface_providers = [ - VersionHandler(self), - self, - ] - - - def coreReady(self): - self.new_package = {} - - self.start() - - - def packageFinished(self, pypack): - try: - if self.getConfig("info_pack"): - self.announce(_("Package finished: %s") % pypack.name) - except: - pass - - - def downloadFinished(self, pyfile): - try: - if self.getConfig("info_file"): - self.announce( - _("Download finished: %(name)s @ %(plugin)s") % {"name": pyfile.name, "plugin": pyfile.pluginname}) - except: - pass - - - def run(self): - # connect to IRC etc. - self.connect() - try: - self.loop() - except Exception, ex: - self.logError(ex) - - - def stream_state_changed(self, state, arg): - """This one is called when the state of stream connecting the component - to a server changes. This will usually be used to let the user - know what is going on.""" - self.logDebug("*** State changed: %s %r ***" % (state, arg)) - - - def disconnected(self): - self.logDebug("Client was disconnected") - - - def stream_closed(self, stream): - self.logDebug("Stream was closed", stream) - - - def stream_error(self, err): - self.logDebug("Stream Error", err) - - - def get_message_handlers(self): - """Return list of (message_type, message_handler) tuples. - - The handlers returned will be called when matching message is received - in a client session.""" - return [("normal", self.message)] - - - def message(self, stanza): - """Message handler for the component.""" - subject = stanza.get_subject() - body = stanza.get_body() - t = stanza.get_type() - self.logDebug("Message from %s received." % unicode(stanza.get_from())) - self.logDebug("Body: %s Subject: %s Type: %s" % (body, subject, t)) - - if t == "headline": - # 'headline' messages should never be replied to - return True - if subject: - subject = u"Re: " + subject - - to_jid = stanza.get_from() - from_jid = stanza.get_to() - - #j = JID() - to_name = to_jid.as_utf8() - from_name = from_jid.as_utf8() - - names = self.getConfig("owners").split(";") - - if to_name in names or to_jid.node + "@" + to_jid.domain in names: - messages = [] - - trigger = "pass" - args = None - - try: - temp = body.split() - trigger = temp[0] - if len(temp) > 1: - args = temp[1:] - except: - pass - - handler = getattr(self, "event_%s" % trigger, self.event_pass) - try: - res = handler(args) - for line in res: - m = Message( - to_jid=to_jid, - from_jid=from_jid, - stanza_type=stanza.get_type(), - subject=subject, - body=line) - - messages.append(m) - except Exception, e: - self.logError(e) - - return messages - - else: - return True - - - def response(self, msg, origin=""): - return self.announce(msg) - - - def announce(self, message): - """ send message to all owners""" - for user in self.getConfig("owners").split(";"): - self.logDebug("Send message to", user) - - to_jid = JID(user) - - m = Message(from_jid=self.jid, - to_jid=to_jid, - stanza_type="chat", - body=message) - - stream = self.get_stream() - if not stream: - self.connect() - stream = self.get_stream() - - stream.send(m) - - - def beforeReconnecting(self, ip): - self.disconnect() - - - def afterReconnecting(self, ip): - self.connect() - - -class VersionHandler(object): - """Provides handler for a version query. - - This class will answer version query and announce 'jabber:iq:version' namespace - in the client's disco#info results.""" - - implements(IIqHandlersProvider, IFeaturesProvider) - - - def __init__(self, client): - """Just remember who created this.""" - self.client = client - - - def get_features(self): - """Return namespace which should the client include in its reply to a - disco#info query.""" - return ["jabber:iq:version"] - - - def get_iq_get_handlers(self): - """Return list of tuples (element_name, namespace, handler) describing - handlers of <iq type='get'/> stanzas""" - return [("query", "jabber:iq:version", self.get_version)] - - - def get_iq_set_handlers(self): - """Return empty list, as this class provides no <iq type='set'/> stanza handler.""" - return [] - - - def get_version(self, iq): - """Handler for jabber:iq:version queries. - - jabber:iq:version queries are not supported directly by PyXMPP, so the - XML node is accessed directly through the libxml2 API. This should be - used very carefully!""" - iq = iq.make_result_response() - q = iq.new_query("jabber:iq:version") - q.newTextChild(q.ns(), "name", "Echo component") - q.newTextChild(q.ns(), "version", "1.0") - return iq diff --git a/module/plugins/hooks/ZeveraCom.py b/module/plugins/hooks/ZeveraCom.py deleted file mode 100644 index 6fafb9666..000000000 --- a/module/plugins/hooks/ZeveraCom.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class ZeveraCom(MultiHoster): - __name__ = "ZeveraCom" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "")] - - __description__ = """Real-Debrid.com hook plugin""" - __license__ = "GPLv3" - __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] - - - def getHoster(self): - page = getURL("http://www.zevera.com/jDownloader.ashx", get={'cmd': "gethosters"}) - return [x.strip() for x in page.replace("\"", "").split(",")] diff --git a/module/plugins/hooks/__init__.py b/module/plugins/hooks/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/module/plugins/hooks/__init__.py +++ /dev/null |