diff options
author | Walter Purcaro <vuolter@gmail.com> | 2014-09-07 23:40:50 +0200 |
---|---|---|
committer | Walter Purcaro <vuolter@gmail.com> | 2014-09-14 10:58:42 +0200 |
commit | 887ad58e4c6c20b992311bbdf931bcd18e73d384 (patch) | |
tree | f31beb241bacca0bfea4c1acc4e9ace813755cef /module/plugins/hooks | |
parent | [AccountManager] Fixed #733 (diff) | |
parent | [File4safe] distributing LINK_PATTERN (diff) | |
download | pyload-887ad58e4c6c20b992311bbdf931bcd18e73d384.tar.xz |
Merge branch 'stable' into 0.4.10
Conflicts:
module/plugins/Account.py
module/plugins/AccountManager.py
module/plugins/Hook.py
module/plugins/OCR.py
module/plugins/Plugin.py
module/plugins/PluginManager.py
module/plugins/ReCaptcha.py
module/plugins/accounts/Ftp.py
module/plugins/accounts/Http.py
module/plugins/internal/MultiHoster.py
module/plugins/ocr/GigasizeCom.py
module/plugins/ocr/LinksaveIn.py
module/plugins/ocr/NetloadIn.py
module/plugins/ocr/ShareonlineBiz.py
Diffstat (limited to 'module/plugins/hooks')
46 files changed, 527 insertions, 1097 deletions
diff --git a/module/plugins/hooks/AlldebridCom.py b/module/plugins/hooks/AlldebridCom.py index 0f8d3bfbb..906875a69 100644 --- a/module/plugins/hooks/AlldebridCom.py +++ b/module/plugins/hooks/AlldebridCom.py @@ -1,15 +1,13 @@ # -*- coding: utf-8 -*- -# should be working - from module.network.RequestFactory import getURL from module.plugins.internal.MultiHoster import MultiHoster class AlldebridCom(MultiHoster): __name__ = "AlldebridCom" - __version__ = "0.13" __type__ = "hook" + __version__ = "0.13" __config__ = [("activated", "bool", "Activated", False), ("https", "bool", "Enable HTTPS", False), @@ -22,6 +20,7 @@ class AlldebridCom(MultiHoster): __author_name__ = "Andy Voigt" __author_mail__ = "spamsales@online.de" + def getHoster(self): https = "https" if self.getConfig("https") else "http" page = getURL(https + "://www.alldebrid.com/api.php?action=get_host").replace("\"", "").strip() diff --git a/module/plugins/hooks/BypassCaptcha.py b/module/plugins/hooks/BypassCaptcha.py index 70e60f56c..d62de24a7 100644 --- a/module/plugins/hooks/BypassCaptcha.py +++ b/module/plugins/hooks/BypassCaptcha.py @@ -1,34 +1,15 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: RaNaN, Godofdream, zoidberg -""" - -from thread import start_new_thread from pycurl import FORM_FILE, LOW_SPEED_TIME +from thread import start_new_thread -from module.network.RequestFactory import getURL, getRequest from module.network.HTTPRequest import BadHeader - +from module.network.RequestFactory import getURL, getRequest from module.plugins.Hook import Hook -PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32" - class BypassCaptchaException(Exception): + def __init__(self, err): self.err = err @@ -44,18 +25,24 @@ class BypassCaptchaException(Exception): class BypassCaptcha(Hook): __name__ = "BypassCaptcha" + __type__ = "hook" __version__ = "0.04" - __description__ = """Send captchas to BypassCaptcha.com""" + __config__ = [("activated", "bool", "Activated", False), ("force", "bool", "Force BC even if client is connected", False), ("passkey", "password", "Passkey", "")] + + __description__ = """Send captchas to BypassCaptcha.com""" __author_name__ = ("RaNaN", "Godofdream", "zoidberg") __author_mail__ = ("RaNaN@pyload.org", "soilfcition@gmail.com", "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 = {} @@ -73,7 +60,7 @@ class BypassCaptcha(Hook): try: response = req.load(self.SUBMIT_URL, - post={"vendor_key": PYLOAD_KEY, + post={"vendor_key": self.PYLOAD_KEY, "key": self.getConfig("passkey"), "gen_task_id": "1", "file": (FORM_FILE, captcha)}, @@ -122,11 +109,11 @@ class BypassCaptcha(Hook): def captchaCorrect(self, task): if task.data['service'] == self.__name__ and "ticket" in task.data: - self.respond(task.data["ticket"], True) + 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) + self.respond(task.data['ticket'], False) def processCaptcha(self, task): c = task.captchaFile @@ -136,5 +123,5 @@ class BypassCaptcha(Hook): task.error = e.getCode() return - task.data["ticket"] = ticket + task.data['ticket'] = ticket task.setResult(result) diff --git a/module/plugins/hooks/Captcha9kw.py b/module/plugins/hooks/Captcha9kw.py index c86f92972..1b7406edd 100755 --- a/module/plugins/hooks/Captcha9kw.py +++ b/module/plugins/hooks/Captcha9kw.py @@ -1,37 +1,22 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay, RaNaN, zoidberg -""" from __future__ import with_statement -from thread import start_new_thread -from base64 import b64encode import time -from module.network.RequestFactory import getURL -from module.network.HTTPRequest import BadHeader +from base64 import b64encode +from thread import start_new_thread +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.09" - __description__ = """Send captchas to 9kw.eu""" + __config__ = [("activated", "bool", "Activated", False), ("force", "bool", "Force CT even if client is connected", True), ("https", "bool", "Enable HTTPS", False), @@ -43,11 +28,14 @@ class Captcha9kw(Hook): False), ("timeout", "int", "Timeout (max. 300)", 300), ("passkey", "password", "API key", "")] + + __description__ = """Send captchas to 9kw.eu""" __author_name__ = "RaNaN" __author_mail__ = "RaNaN@pyload.org" API_URL = "://www.9kw.eu/index.cgi" + def setup(self): self.API_URL = "https" + self.API_URL if self.getConfig("https") else "http" + self.API_URL self.info = {} @@ -58,7 +46,7 @@ class Captcha9kw(Hook): if response.isdigit(): self.logInfo(_("%s credits left") % response) - self.info["credits"] = credits = int(response) + self.info['credits'] = credits = int(response) return credits else: self.logError(response) @@ -104,7 +92,7 @@ class Captcha9kw(Hook): time.sleep(3) result = response2 - task.data["ticket"] = response + task.data['ticket'] = response self.logInfo("result %s : %s" % (response, result)) task.setResult(result) else: @@ -140,7 +128,7 @@ class Captcha9kw(Hook): "correct": "1", "pyload": "1", "source": "pyload", - "id": task.data["ticket"]}) + "id": task.data['ticket']}) self.logInfo("Request correct: %s" % response) except BadHeader, e: @@ -159,7 +147,7 @@ class Captcha9kw(Hook): "correct": "2", "pyload": "1", "source": "pyload", - "id": task.data["ticket"]}) + "id": task.data['ticket']}) self.logInfo("Request refund: %s" % response) except BadHeader, e: diff --git a/module/plugins/hooks/CaptchaBrotherhood.py b/module/plugins/hooks/CaptchaBrotherhood.py index 23d71ff5f..e240cbbc0 100644 --- a/module/plugins/hooks/CaptchaBrotherhood.py +++ b/module/plugins/hooks/CaptchaBrotherhood.py @@ -1,36 +1,21 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay, RaNaN, zoidberg -""" from __future__ import with_statement -from thread import start_new_thread - -import pycurl import StringIO -from urllib import urlencode -from time import sleep +import pycurl + from PIL 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 @@ -46,17 +31,21 @@ class CaptchaBrotherhoodException(Exception): class CaptchaBrotherhood(Hook): __name__ = "CaptchaBrotherhood" + __type__ = "hook" __version__ = "0.05" - __description__ = """Send captchas to CaptchaBrotherhood.com""" + __config__ = [("activated", "bool", "Activated", False), ("username", "str", "Username", ""), ("force", "bool", "Force CT even if client is connected", False), ("passkey", "password", "Password", "")] + + __description__ = """Send captchas to CaptchaBrotherhood.com""" __author_name__ = ("RaNaN", "zoidberg") __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") API_URL = "http://www.captchabrotherhood.com/" + def setup(self): self.info = {} @@ -68,7 +57,7 @@ class CaptchaBrotherhood(Hook): else: credits = int(response[3:]) self.logInfo(_("%d credits left") % credits) - self.info["credits"] = credits + self.info['credits'] = credits return credits def submit(self, captcha, captchaType="file", match=None): @@ -164,5 +153,5 @@ class CaptchaBrotherhood(Hook): task.error = e.getCode() return - task.data["ticket"] = ticket + task.data['ticket'] = ticket task.setResult(result) diff --git a/module/plugins/hooks/CaptchaTrader.py b/module/plugins/hooks/CaptchaTrader.py deleted file mode 100644 index 051dc6c2b..000000000 --- a/module/plugins/hooks/CaptchaTrader.py +++ /dev/null @@ -1,157 +0,0 @@ -# -*- coding: utf-8 -*- - -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay, RaNaN -""" - -from thread import start_new_thread -from pycurl import FORM_FILE, LOW_SPEED_TIME - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader -from module.plugins.Hook import Hook - -PYLOAD_KEY = "9f65e7f381c3af2b076ea680ae96b0b7" - - -class CaptchaTraderException(Exception): - def __init__(self, err): - self.err = err - - def getCode(self): - return self.err - - def __str__(self): - return "<CaptchaTraderException %s>" % self.err - - def __repr__(self): - return "<CaptchaTraderException %s>" % self.err - - -class CaptchaTrader(Hook): - __name__ = "CaptchaTrader" - __version__ = "0.16" - __description__ = """Send captchas to captchatrader.com""" - __config__ = [("activated", "bool", "Activated", False), - ("username", "str", "Username", ""), - ("force", "bool", "Force CT even if client is connected", False), - ("passkey", "password", "Password", "")] - __author_name__ = "RaNaN" - __author_mail__ = "RaNaN@pyload.org" - - SUBMIT_URL = "http://api.captchatrader.com/submit" - RESPOND_URL = "http://api.captchatrader.com/respond" - GETCREDITS_URL = "http://api.captchatrader.com/get_credits/username:%(user)s/password:%(password)s/" - - def setup(self): - self.info = {} - - def getCredits(self): - json = getURL(CaptchaTrader.GETCREDITS_URL % {"user": self.getConfig("username"), - "password": self.getConfig("passkey")}) - response = json_loads(json) - if response[0] < 0: - raise CaptchaTraderException(response[1]) - else: - self.logInfo(_("%s credits left") % response[1]) - self.info["credits"] = response[1] - return response[1] - - def submit(self, captcha, captchaType="file", match=None): - if not PYLOAD_KEY: - raise CaptchaTraderException("No API Key Specified!") - - #if type(captcha) == str and captchaType == "file": - # raise CaptchaTraderException("Invalid Type") - assert captchaType in ("file", "url-jpg", "url-jpeg", "url-png", "url-bmp") - - req = getRequest() - - #raise timeout threshold - req.c.setopt(LOW_SPEED_TIME, 80) - - try: - json = req.load(CaptchaTrader.SUBMIT_URL, post={"api_key": PYLOAD_KEY, - "username": self.getConfig("username"), - "password": self.getConfig("passkey"), - "value": (FORM_FILE, captcha), - "type": captchaType}, multipart=True) - finally: - req.close() - - response = json_loads(json) - if response[0] < 0: - raise CaptchaTraderException(response[1]) - - ticket = response[0] - result = response[1] - self.logDebug("result %s : %s" % (ticket, result)) - - return ticket, result - - def respond(self, ticket, success): - try: - json = getURL(CaptchaTrader.RESPOND_URL, post={"is_correct": 1 if success else 0, - "username": self.getConfig("username"), - "password": self.getConfig("passkey"), - "ticket": ticket}) - - response = json_loads(json) - if response[0] < 0: - raise CaptchaTraderException(response[1]) - - except BadHeader, e: - self.logError(_("Could not send response."), str(e)) - - def newCaptchaTask(self, task): - 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.setWaiting(100) - start_new_thread(self.processCaptcha, (task,)) - - else: - self.logInfo(_("Your CaptchaTrader Account has not enough credits")) - - def captchaCorrect(self, task): - if "ticket" in task.data: - ticket = task.data["ticket"] - self.respond(ticket, True) - - def captchaInvalid(self, task): - if "ticket" in task.data: - ticket = task.data["ticket"] - self.respond(ticket, False) - - def processCaptcha(self, task): - c = task.captchaFile - try: - ticket, result = self.submit(c) - except CaptchaTraderException, 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 index af37d69e6..013172899 100644 --- a/module/plugins/hooks/Checksum.py +++ b/module/plugins/hooks/Checksum.py @@ -1,31 +1,16 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: zoidberg -""" - from __future__ import with_statement + import hashlib +import re import zlib + from os import remove from os.path import getsize, isfile, splitext -import re -from module.utils import save_join, fs_encode from module.plugins.Hook import Hook +from module.utils import save_join, fs_encode def computeChecksum(local_file, algorithm): @@ -54,15 +39,19 @@ def computeChecksum(local_file, algorithm): class Checksum(Hook): __name__ = "Checksum" - __version__ = "0.12" - __description__ = """Verify downloaded file size and checksum""" + __type__ = "hook" + __version__ = "0.13" + __config__ = [("activated", "bool", "Activated", False), + ("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)] - __author_name__ = ("zoidberg", "Walter Purcaro") - __author_mail__ = ("zoidberg@mujmail.cz", "vuolter@gmail.com") + + __description__ = """Verify downloaded file size and checksum""" + __author_name__ = ("zoidberg", "Walter Purcaro", "stickell") + __author_mail__ = ("zoidberg@mujmail.cz", "vuolter@gmail.com", "l.stickell@yahoo.it") methods = {'sfv': 'crc32', 'crc': 'crc32', 'hash': 'md5'} regexps = {'sfv': r'^(?P<name>[^;].+)\s+(?P<hash>[0-9A-Fa-f]{8})$', @@ -70,15 +59,16 @@ class Checksum(Hook): '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.config['general']['checksum']: - self.logInfo("Checksum validation is disabled in general configuration") + 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'] + self.formats = self.algorithms + ["sfv", "crc", "hash"] def downloadFinished(self, pyfile): """ @@ -116,7 +106,7 @@ class Checksum(Hook): del data['size'] # validate checksum - if data and self.config['general']['checksum']: + if data and self.getConfig("check_checksum"): if "checksum" in data: data['md5'] = data['checksum'] @@ -156,15 +146,15 @@ class Checksum(Hook): 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() + file_type = splitext(link['name'])[1][1:].lower() #self.logDebug(link, file_type) if file_type not in self.formats: continue - hash_file = fs_encode(save_join(download_folder, link["name"])) + hash_file = fs_encode(save_join(download_folder, link['name'])) if not isfile(hash_file): - self.logWarning("File not found: %s" % link["name"]) + self.logWarning("File not found: %s" % link['name']) continue with open(hash_file) as f: @@ -172,14 +162,14 @@ class Checksum(Hook): for m in re.finditer(self.regexps.get(file_type, self.regexps['default']), text): data = m.groupdict() - self.logDebug(link["name"], data) + self.logDebug(link['name'], data) - local_file = fs_encode(save_join(download_folder, data["name"])) + 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"]: + if checksum == data['hash']: self.logInfo('File integrity of "%s" verified by %s checksum (%s).' % - (data["name"], algorithm, checksum)) + (data['name'], algorithm, checksum)) else: self.logWarning("%s checksum for file %s does not match (%s != %s)" % - (algorithm, data["name"], checksum, data["hash"])) + (algorithm, data['name'], checksum, data['hash'])) diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py index 002fd4cd7..5c523caf7 100644 --- a/module/plugins/hooks/ClickAndLoad.py +++ b/module/plugins/hooks/ClickAndLoad.py @@ -1,23 +1,5 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: RaNaN - @interface-version: 0.2 -""" - import socket import thread @@ -26,13 +8,17 @@ from module.plugins.Hook import Hook class ClickAndLoad(Hook): __name__ = "ClickAndLoad" + __type__ = "hook" __version__ = "0.22" - __description__ = """Gives abillity to use jd's click and load. depends on webinterface""" + __config__ = [("activated", "bool", "Activated", True), ("extern", "bool", "Allow external link adding", False)] + + __description__ = """Gives abillity to use jd's click and load. depends on webinterface""" __author_name__ = ("RaNaN", "mkaay") __author_mail__ = ("RaNaN@pyload.de", "mkaay@mkaay.de") + def coreReady(self): self.port = int(self.config['webinterface']['port']) if self.config['webinterface']['activated']: diff --git a/module/plugins/hooks/DeathByCaptcha.py b/module/plugins/hooks/DeathByCaptcha.py index f7bc1b90f..530395d32 100644 --- a/module/plugins/hooks/DeathByCaptcha.py +++ b/module/plugins/hooks/DeathByCaptcha.py @@ -1,33 +1,18 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay, RaNaN, zoidberg -""" from __future__ import with_statement -from thread import start_new_thread +import re + +from base64 import b64encode from pycurl import FORM_FILE, HTTPHEADER +from thread import start_new_thread from time import sleep -from base64 import b64encode -import re -from module.network.RequestFactory import getRequest +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 -from module.common.json_layer import json_loads class DeathByCaptchaException(Exception): @@ -61,17 +46,21 @@ class DeathByCaptchaException(Exception): class DeathByCaptcha(Hook): __name__ = "DeathByCaptcha" + __type__ = "hook" __version__ = "0.03" - __description__ = """Send captchas to DeathByCaptcha.com""" + __config__ = [("activated", "bool", "Activated", False), ("username", "str", "Username", ""), ("passkey", "password", "Password", ""), ("force", "bool", "Force DBC even if client is connected", False)] + + __description__ = """Send captchas to DeathByCaptcha.com""" __author_name__ = ("RaNaN", "zoidberg") __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") API_URL = "http://api.dbcapi.me/api/" + def setup(self): self.info = {} @@ -132,7 +121,7 @@ class DeathByCaptcha(Hook): raise DeathByCaptchaException('service-overload') def submit(self, captcha, captchaType="file", match=None): - #workaround multipart-post bug in HTTPRequest.py + #workaround multipart-post bug in HTTPRequest.py if re.match("^[A-Za-z0-9]*$", self.getConfig("passkey")): multipart = True data = (FORM_FILE, captcha) @@ -181,7 +170,7 @@ class DeathByCaptcha(Hook): self.logError(e.getDesc()) return False - balance, rate = self.info["balance"], self.info["rate"] + 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)) @@ -194,7 +183,7 @@ class DeathByCaptcha(Hook): def captchaInvalid(self, task): if task.data['service'] == self.__name__ and "ticket" in task.data: try: - response = self.call_api("captcha/%d/report" % task.data["ticket"], True) + response = self.call_api("captcha/%d/report" % task.data['ticket'], True) except DeathByCaptchaException, e: self.logError(e.getDesc()) except Exception, e: @@ -209,5 +198,5 @@ class DeathByCaptcha(Hook): self.logError(e.getDesc()) return - task.data["ticket"] = ticket + task.data['ticket'] = ticket task.setResult(result) diff --git a/module/plugins/hooks/DebridItaliaCom.py b/module/plugins/hooks/DebridItaliaCom.py index fb6be674f..88efb6b2a 100644 --- a/module/plugins/hooks/DebridItaliaCom.py +++ b/module/plugins/hooks/DebridItaliaCom.py @@ -1,26 +1,13 @@ # -*- coding: utf-8 -*- -############################################################################ -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU Affero General Public License as # -# published by the Free Software Foundation, either version 3 of the # -# License, or (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU Affero General Public License for more details. # -# # -# You should have received a copy of the GNU Affero General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -############################################################################ from module.plugins.internal.MultiHoster import MultiHoster class DebridItaliaCom(MultiHoster): __name__ = "DebridItaliaCom" - __version__ = "0.07" __type__ = "hook" + __version__ = "0.07" + __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), ("hosterList", "str", "Hoster list (comma separated)", ""), @@ -31,6 +18,7 @@ class DebridItaliaCom(MultiHoster): __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" + def getHoster(self): return ["netload.in", "hotfile.com", "rapidshare.com", "multiupload.com", "uploading.com", "megashares.com", "crocko.com", "filepost.com", diff --git a/module/plugins/hooks/DeleteFinished.py b/module/plugins/hooks/DeleteFinished.py index 3bc98a7b3..bc926906f 100644 --- a/module/plugins/hooks/DeleteFinished.py +++ b/module/plugins/hooks/DeleteFinished.py @@ -1,37 +1,22 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: Walter Purcaro -""" - from module.database import style from module.plugins.Hook import Hook class DeleteFinished(Hook): - __name__ = 'DeleteFinished' - __version__ = '1.09' - __description__ = 'Automatically delete all finished packages from queue' - __config__ = [ - ('activated', 'bool', 'Activated', 'False'), - ('interval', 'int', 'Delete every (hours)', '72'), - ('deloffline', 'bool', 'Delete packages with offline links', 'False') - ] - __author_name__ = ('Walter Purcaro') - __author_mail__ = ('vuolter@gmail.com') + __name__ = "DeleteFinished" + __type__ = "hook" + __version__ = "1.09" + + __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""" + __author_name__ = "Walter Purcaro" + __author_mail__ = "vuolter@gmail.com" + ## overwritten methods ## def periodical(self): diff --git a/module/plugins/hooks/DownloadScheduler.py b/module/plugins/hooks/DownloadScheduler.py index 41a20e5d1..a3d70b3ab 100644 --- a/module/plugins/hooks/DownloadScheduler.py +++ b/module/plugins/hooks/DownloadScheduler.py @@ -1,22 +1,7 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: zoidberg - Original idea by new.cze -""" - import re + from time import localtime from module.plugins.Hook import Hook @@ -24,15 +9,19 @@ from module.plugins.Hook import Hook class DownloadScheduler(Hook): __name__ = "DownloadScheduler" + __type__ = "hook" __version__ = "0.21" - __description__ = """Download Scheduler""" + __config__ = [("activated", "bool", "Activated", False), ("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""" __author_name__ = ("zoidberg", "stickell") __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") + def setup(self): self.cb = None # callback to scheduler job; will be by removed hookmanager when hook unloaded diff --git a/module/plugins/hooks/EasybytezCom.py b/module/plugins/hooks/EasybytezCom.py index a3a2dcb92..da37297d9 100644 --- a/module/plugins/hooks/EasybytezCom.py +++ b/module/plugins/hooks/EasybytezCom.py @@ -7,15 +7,18 @@ from module.plugins.internal.MultiHoster import MultiHoster class EasybytezCom(MultiHoster): __name__ = "EasybytezCom" - __version__ = "0.03" __type__ = "hook" + __version__ = "0.03" + __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), ("hosterList", "str", "Hoster list (comma separated)", "")] + __description__ = """EasyBytez.com hook plugin""" __author_name__ = "zoidberg" __author_mail__ = "zoidberg@mujmail.cz" + def getHoster(self): self.account = self.core.accountManager.getAccountPlugin(self.__name__) user = self.account.selectAccount()[0] @@ -24,11 +27,11 @@ class EasybytezCom(MultiHoster): req = self.account.getAccountRequest(user) page = req.load("http://www.easybytez.com") - found = re.search(r'</textarea>\s*Supported sites:(.*)', page) - return found.group(1).split(',') + m = re.search(r'</textarea>\s*Supported sites:(.*)', page) + return m.group(1).split(',') except Exception, e: self.logDebug(e) self.logWarning("Unable to load supported hoster list, using last known") - return ['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'] + return ["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"] diff --git a/module/plugins/hooks/Ev0InFetcher.py b/module/plugins/hooks/Ev0InFetcher.py index 1e2b62062..c54c38bc6 100644 --- a/module/plugins/hooks/Ev0InFetcher.py +++ b/module/plugins/hooks/Ev0InFetcher.py @@ -1,31 +1,17 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay -""" from time import mktime, time from module.lib import feedparser + from module.plugins.Hook import Hook class Ev0InFetcher(Hook): __name__ = "Ev0InFetcher" + __type__ = "hook" __version__ = "0.21" - __description__ = """Checks rss feeds for Ev0.in""" + __config__ = [("activated", "bool", "Activated", False), ("interval", "int", "Check interval in minutes", 10), ("queue", "bool", "Move new shows directly to Queue", False), @@ -33,9 +19,12 @@ class Ev0InFetcher(Hook): ("quality", "xvid;x264;rmvb", "Video Format", "xvid"), ("hoster", "str", "Hoster to use (comma seperated)", "NetloadIn,RapidshareCom,MegauploadCom,HotfileCom")] + + __description__ = """Checks rss feeds for Ev0.in""" __author_name__ = "mkaay" __author_mail__ = "mkaay@mkaay.de" + def setup(self): self.interval = self.getConfig("interval") * 60 @@ -55,7 +44,9 @@ class Ev0InFetcher(Hook): continue return [] + def periodical(self): + def normalizefiletitle(filename): filename = filename.replace('.', ' ') filename = filename.replace('_', ' ') diff --git a/module/plugins/hooks/ExpertDecoders.py b/module/plugins/hooks/ExpertDecoders.py index 7be30f86e..c7ab80da0 100644 --- a/module/plugins/hooks/ExpertDecoders.py +++ b/module/plugins/hooks/ExpertDecoders.py @@ -1,46 +1,33 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay, RaNaN, zoidberg -""" from __future__ import with_statement -from thread import start_new_thread +from base64 import b64encode from pycurl import LOW_SPEED_TIME +from thread import start_new_thread from uuid import uuid4 -from base64 import b64encode -from module.network.RequestFactory import getURL, getRequest 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" - __description__ = """Send captchas to expertdecoders.com""" + __config__ = [("activated", "bool", "Activated", False), ("force", "bool", "Force CT even if client is connected", False), ("passkey", "password", "Access key", "")] + + __description__ = """Send captchas to expertdecoders.com""" __author_name__ = ("RaNaN", "zoidberg") __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") API_URL = "http://www.fasttypers.org/imagepost.ashx" + def setup(self): self.info = {} @@ -49,14 +36,14 @@ class ExpertDecoders(Hook): if response.isdigit(): self.logInfo(_("%s credits left") % response) - self.info["credits"] = credits = int(response) + self.info['credits'] = credits = int(response) return credits else: self.logError(response) return 0 def processCaptcha(self, task): - task.data["ticket"] = ticket = uuid4() + task.data['ticket'] = ticket = uuid4() result = None with open(task.captchaFile, 'rb') as f: @@ -100,7 +87,7 @@ class ExpertDecoders(Hook): try: response = getURL(self.API_URL, post={"action": "refund", "key": self.getConfig("passkey"), - "gen_task_id": task.data["ticket"]}) + "gen_task_id": task.data['ticket']}) self.logInfo("Request refund: %s" % response) except BadHeader, e: diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py index 3d84dcc3d..8d03d27d4 100644 --- a/module/plugins/hooks/ExternalScripts.py +++ b/module/plugins/hooks/ExternalScripts.py @@ -1,24 +1,7 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay - @interface-version: 0.1 -""" - import subprocess + from os import listdir, access, X_OK, makedirs from os.path import join, exists, basename, abspath @@ -28,20 +11,24 @@ from module.utils import save_join class ExternalScripts(Hook): __name__ = "ExternalScripts" + __type__ = "hook" __version__ = "0.23" - __description__ = """Run external scripts""" + __config__ = [("activated", "bool", "Activated", True)] + + __description__ = """Run external scripts""" __author_name__ = ("mkaay", "RaNaN", "spoob") __author_mail__ = ("mkaay@mkaay.de", "ranan@pyload.org", "spoob@pyload.org") event_list = ["unrarFinished", "allDownloadsFinished", "allDownloadsProcessed"] + def setup(self): self.scripts = {} - folders = ['download_preparing', 'download_finished', 'package_finished', - 'before_reconnect', 'after_reconnect', 'unrar_finished', - 'all_dls_finished', 'all_dls_processed'] + folders = ["download_preparing", "download_finished", "package_finished", + "before_reconnect", "after_reconnect", "unrar_finished", + "all_dls_finished", "all_dls_processed"] for folder in folders: self.scripts[folder] = [] @@ -105,13 +92,13 @@ class ExternalScripts(Hook): self.callScript(script, ip) def unrarFinished(self, folder, fname): - for script in self.scripts["unrar_finished"]: + for script in self.scripts['unrar_finished']: self.callScript(script, folder, fname) def allDownloadsFinished(self): - for script in self.scripts["all_dls_finished"]: + for script in self.scripts['all_dls_finished']: self.callScript(script) def allDownloadsProcessed(self): - for script in self.scripts["all_dls_processed"]: + for script in self.scripts['all_dls_processed']: self.callScript(script) diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index 12e53fe50..144829459 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -1,19 +1,18 @@ # -*- coding: utf-8 -*- -import sys import os +import sys + +from copy import copy from os import remove, chmod, makedirs -from os.path import exists, basename, isfile, isdir, join +from os.path import exists, basename, isfile, isdir from traceback import print_exc -from copy import copy # monkey patch bug in python 2.6 and lower -# see http://bugs.python.org/issue6122 -# http://bugs.python.org/issue1236 -# http://bugs.python.org/issue1731717 +# 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": - from subprocess import Popen import errno + from subprocess import Popen def _eintr_retry_call(func, *args): while True: @@ -44,13 +43,13 @@ if sys.version_info < (2, 7) and os.name != "nt": Popen.wait = wait if os.name != "nt": + from grp import getgrnam from os import chown from pwd import getpwnam - from grp import getgrnam -from module.utils import save_join, fs_encode 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): @@ -58,8 +57,9 @@ class ExtractArchive(Hook): Provides: unrarFinished (folder, filename) """ __name__ = "ExtractArchive" + __type__ = "hook" __version__ = "0.16" - __description__ = """Extract different kind of archives""" + __config__ = [("activated", "bool", "Activated", True), ("fullpath", "bool", "Extract full path", True), ("overwrite", "bool", "Overwrite files", True), @@ -71,11 +71,14 @@ class ExtractArchive(Hook): ("recursive", "bool", "Extract archives in archvies", True), ("queue", "bool", "Wait for all downloads to be finished", True), ("renice", "int", "CPU Priority", 0)] - __author_name__ = ("pyload Team", "AndroKev") - __author_mail__ = ("admin<at>pyload.org", "@pyloadforum") + + __description__ = """Extract different kind of archives""" + __author_name__ = ("pyLoad Team", "AndroKev") + __author_mail__ = ("admin@pyload.org", "@pyloadforum") event_list = ["allDownloadsProcessed"] + def setup(self): self.plugins = [] self.passwords = [] @@ -154,12 +157,12 @@ class ExtractArchive(Hook): #relative to package folder if destination is relative, otherwise absolute path overwrites them if self.getConfig("subfolder"): - out = join(out, fs_encode(p.folder)) + 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()] + files_ids = [(save_join(dl, p.folder, x['name']), x['id']) for x in p.getChildren().itervalues()] matched = False # check as long there are unseen files @@ -303,15 +306,15 @@ class ExtractArchive(Hook): if not exists(f): continue try: - if self.config["permission"]["change_file"]: + if self.config['permission']['change_file']: if isfile(f): - chmod(f, int(self.config["permission"]["file"], 8)) + chmod(f, int(self.config['permission']['file'], 8)) elif isdir(f): - chmod(f, int(self.config["permission"]["folder"], 8)) + 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] + 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 index 558da1b86..879dba277 100644 --- a/module/plugins/hooks/FastixRu.py +++ b/module/plugins/hooks/FastixRu.py @@ -1,24 +1,25 @@ # -*- coding: utf-8 -*- -# should be working - +from module.common.json_layer import json_loads from module.network.RequestFactory import getURL from module.plugins.internal.MultiHoster import MultiHoster -from module.common.json_layer import json_loads class FastixRu(MultiHoster): __name__ = "FastixRu" - __version__ = "0.02" __type__ = "hook" + __version__ = "0.02" + __config__ = [("activated", "bool", "Activated", False), ("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""" __author_name__ = "Massimo Rosamilia" __author_mail__ = "max@spiritix.eu" + def getHoster(self): page = getURL( "http://fastix.ru/api_v2/?apikey=5182964c3f8f9a7f0b00000a_kelmFB4n1IrnCDYuIFn2y&sub=allowed_sources") diff --git a/module/plugins/hooks/FreeWayMe.py b/module/plugins/hooks/FreeWayMe.py index 7d4bcc852..12d58ac8a 100644 --- a/module/plugins/hooks/FreeWayMe.py +++ b/module/plugins/hooks/FreeWayMe.py @@ -1,39 +1,25 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: Nicolas Giese -""" - from module.network.RequestFactory import getURL from module.plugins.internal.MultiHoster import MultiHoster class FreeWayMe(MultiHoster): __name__ = "FreeWayMe" - __version__ = "0.11" __type__ = "hook" - __description__ = """FreeWay.me hook plugin""" + __version__ = "0.11" + __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 stanard download if download fails", False), ("interval", "int", "Reload interval in hours (0 to disable)", 24)] + + __description__ = """FreeWay.me hook plugin""" __author_name__ = "Nicolas Giese" __author_mail__ = "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: %s" % hostis) diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py index a63b314d1..4c81292e3 100644 --- a/module/plugins/hooks/HotFolder.py +++ b/module/plugins/hooks/HotFolder.py @@ -1,51 +1,34 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: RaNaN - @interface-version: 0.2 -""" - -from os import makedirs -from os import listdir -from os.path import exists -from os.path import join -from os.path import isfile -from shutil import move import time +from os import listdir, makedirs +from os.path import exists, isfile, join +from shutil import move + from module.plugins.Hook import Hook class HotFolder(Hook): __name__ = "HotFolder" + __type__ = "hook" __version__ = "0.11" - __description__ = """Observe folder and file for changes and add container and links""" + __config__ = [("activated", "bool", "Activated", False), ("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""" __author_name__ = "RaNaN" __author_mail__ = "RaNaN@pyload.de" + def setup(self): self.interval = 10 def periodical(self): - if not exists(join(self.getConfig("folder"), "finished")): makedirs(join(self.getConfig("folder"), "finished")) diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py index 760c1a4df..7ebc0275f 100644 --- a/module/plugins/hooks/IRCInterface.py +++ b/module/plugins/hooks/IRCInterface.py @@ -1,43 +1,26 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: RaNaN - @author: jeix - @interface-version: 0.2 -""" +import re +import socket +import time +from pycurl import FORM_FILE from select import select -import socket from threading import Thread -import time from time import sleep from traceback import print_exc -import re -from pycurl import FORM_FILE -from module.plugins.Hook import Hook +from module.Api import PackageDoesNotExists, FileDoesNotExists from module.network.RequestFactory import getURL +from module.plugins.Hook import Hook from module.utils import formatSize -from module.Api import PackageDoesNotExists, FileDoesNotExists class IRCInterface(Thread, Hook): __name__ = "IRCInterface" + __type__ = "hook" __version__ = "0.11" - __description__ = """Connect to irc and let owner perform different tasks""" + __config__ = [("activated", "bool", "Activated", False), ("host", "str", "IRC-Server Address", "Enter your server here!"), ("port", "int", "IRC-Server Port", 6667), @@ -48,9 +31,12 @@ class IRCInterface(Thread, Hook): ("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""" __author_name__ = "Jeix" __author_mail__ = "Jeix@hasnomail.com" + def __init__(self, core, manager): Thread.__init__(self) Hook.__init__(self, core, manager) @@ -59,12 +45,9 @@ class IRCInterface(Thread, Hook): self.api = core.api # todo, only use api def coreReady(self): - self.new_package = {} - self.abort = False - - self.links_added = 0 self.more = [] + self.new_package = {} self.start() @@ -155,25 +138,25 @@ class IRCInterface(Thread, Hook): self.handle_events(msg) def handle_events(self, msg): - if not msg["origin"].split("!", 1)[0] in self.getConfig("owner").split(): + if not msg['origin'].split("!", 1)[0] in self.getConfig("owner").split(): return - if msg["target"].split("!", 1)[0] != self.getConfig("nick"): + if msg['target'].split("!", 1)[0] != self.getConfig("nick"): return - if msg["action"] != "PRIVMSG": + if msg['action'] != "PRIVMSG": return # HANDLE CTCP ANTI FLOOD/BOT PROTECTION - if msg["text"] == "\x01VERSION\x01": + 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": + 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": + elif msg['text'] == "\x01LAG\x01": self.logDebug("Received CTCP LAG.") # don't know how to answer return @@ -181,7 +164,7 @@ class IRCInterface(Thread, Hook): args = None try: - temp = msg["text"].split() + temp = msg['text'].split() trigger = temp[0] if len(temp) > 1: args = temp[1:] @@ -192,7 +175,7 @@ class IRCInterface(Thread, Hook): try: res = handler(args) for line in res: - self.response(line, msg["origin"]) + self.response(line, msg['origin']) except Exception, e: self.logError("pyLoad IRC: " + repr(e)) @@ -258,7 +241,7 @@ class IRCInterface(Thread, Hook): def event_info(self, args): if not args: - return ['ERROR: Use info like this: info <id>'] + return ["ERROR: Use info like this: info <id>"] info = None try: @@ -271,7 +254,7 @@ class IRCInterface(Thread, Hook): def event_packinfo(self, args): if not args: - return ['ERROR: Use packinfo like this: packinfo <id>'] + return ["ERROR: Use packinfo like this: packinfo <id>"] lines = [] pack = None @@ -311,19 +294,17 @@ class IRCInterface(Thread, Hook): return lines def event_start(self, args): - self.api.unpauseServer() return ["INFO: Starting downloads."] def event_stop(self, args): - self.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>!'] + "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:]] @@ -338,7 +319,7 @@ class IRCInterface(Thread, Hook): #TODO add links - return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack["name"], id)] + return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack['name'], id)] except: # create new package @@ -415,6 +396,7 @@ class IRCInterface(Thread, Hook): class IRCError(Exception): + def __init__(self, value): self.value = value diff --git a/module/plugins/hooks/ImageTyperz.py b/module/plugins/hooks/ImageTyperz.py index e2e9d93d5..d9d4e547e 100644 --- a/module/plugins/hooks/ImageTyperz.py +++ b/module/plugins/hooks/ImageTyperz.py @@ -1,32 +1,19 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay, RaNaN, zoidberg -""" from __future__ import with_statement -from thread import start_new_thread -from pycurl import FORM_FILE, LOW_SPEED_TIME + 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 @@ -42,12 +29,15 @@ class ImageTyperzException(Exception): class ImageTyperz(Hook): __name__ = "ImageTyperz" + __type__ = "hook" __version__ = "0.04" - __description__ = """Send captchas to ImageTyperz.com""" + __config__ = [("activated", "bool", "Activated", False), ("username", "str", "Username", ""), ("passkey", "password", "Password", ""), ("force", "bool", "Force IT even if client is connected", False)] + + __description__ = """Send captchas to ImageTyperz.com""" __author_name__ = ("RaNaN", "zoidberg") __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") @@ -55,6 +45,7 @@ class ImageTyperz(Hook): RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx" GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx" + def setup(self): self.info = {} @@ -79,7 +70,7 @@ class ImageTyperz(Hook): req.c.setopt(LOW_SPEED_TIME, 80) try: - #workaround multipart-post bug in HTTPRequest.py + #workaround multipart-post bug in HTTPRequest.py if re.match("^[A-Za-z0-9]*$", self.getConfig("passkey")): multipart = True data = (FORM_FILE, captcha) @@ -133,7 +124,7 @@ class ImageTyperz(Hook): if task.data['service'] == self.__name__ and "ticket" in task.data: response = getURL(self.RESPOND_URL, post={"action": "SETBADIMAGE", "username": self.getConfig("username"), "password": self.getConfig("passkey"), - "imageid": task.data["ticket"]}) + "imageid": task.data['ticket']}) if response == "SUCCESS": self.logInfo("Bad captcha solution received, requested refund") @@ -148,5 +139,5 @@ class ImageTyperz(Hook): task.error = e.getCode() return - task.data["ticket"] = ticket + task.data['ticket'] = ticket task.setResult(result) diff --git a/module/plugins/hooks/LinkdecrypterCom.py b/module/plugins/hooks/LinkdecrypterCom.py index dd9cd79f2..1aa8f7ca1 100644 --- a/module/plugins/hooks/LinkdecrypterCom.py +++ b/module/plugins/hooks/LinkdecrypterCom.py @@ -1,37 +1,24 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: zoidberg -""" - import re -from module.plugins.Hook import Hook 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.19" - __description__ = """Linkdecrypter.com hook plugin""" + __config__ = [("activated", "bool", "Activated", False)] + + __description__ = """Linkdecrypter.com hook plugin""" __author_name__ = "zoidberg" __author_mail__ = "zoidberg@mujmail.cz" + def coreReady(self): try: self.loadPatterns() @@ -41,12 +28,12 @@ class LinkdecrypterCom(Hook): def loadPatterns(self): page = getURL("http://linkdecrypter.com/") m = re.search(r'<b>Supported\(\d+\)</b>: <i>([^+<]*)', page) - if not m: + if m is None: self.logError(_("Crypter list not found")) return builtin = [name.lower() for name in self.core.pluginManager.crypterPlugins.keys()] - builtin.extend(["downloadserienjunkiesorg"]) + builtin.append("downloadserienjunkiesorg") crypter_pattern = re.compile("(\w[\w.-]+)") online = [] @@ -62,7 +49,7 @@ class LinkdecrypterCom(Hook): regexp = r"https?://([^.]+\.)*?(%s)/.*" % "|".join(online) dict = self.core.pluginManager.crypterPlugins[self.__name__] - dict["pattern"] = regexp - dict["re"] = re.compile(regexp) + dict['pattern'] = regexp + dict['re'] = re.compile(regexp) self.logDebug("REGEXP: " + regexp) diff --git a/module/plugins/hooks/LinksnappyCom.py b/module/plugins/hooks/LinksnappyCom.py index 110731228..20da68632 100644 --- a/module/plugins/hooks/LinksnappyCom.py +++ b/module/plugins/hooks/LinksnappyCom.py @@ -1,14 +1,15 @@ # -*- coding: utf-8 -*- -from module.plugins.internal.MultiHoster import MultiHoster -from module.network.RequestFactory import getURL 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" - __version__ = "0.01" __type__ = "hook" + __version__ = "0.01" + __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), ("hosterList", "str", "Hoster list (comma separated)", ""), @@ -19,6 +20,7 @@ class LinksnappyCom(MultiHoster): __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" + def getHoster(self): json_data = getURL('http://gen.linksnappy.com/lseAPI.php?act=FILEHOSTS') json_data = json_loads(json_data) diff --git a/module/plugins/hooks/MegaDebridEu.py b/module/plugins/hooks/MegaDebridEu.py index 0c3bb99f6..605b04f21 100644 --- a/module/plugins/hooks/MegaDebridEu.py +++ b/module/plugins/hooks/MegaDebridEu.py @@ -1,39 +1,28 @@ # -*- coding: utf-8 -*- -############################################################################ -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU Affero General Public License as # -# published by the Free Software Foundation, either version 3 of the # -# License, or (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU Affero General Public License for more details. # -# # -# You should have received a copy of the GNU Affero General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -############################################################################ -from module.plugins.internal.MultiHoster import MultiHoster -from module.network.RequestFactory import getURL 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" - __version__ = "0.02" __type__ = "hook" + __version__ = "0.02" + __config__ = [("activated", "bool", "Activated", False), ("unloadFailing", "bool", "Revert to standard download if download fails", False)] + __description__ = """mega-debrid.eu hook plugin""" __author_name__ = "D.Ducatel" __author_mail__ = "dducatel@je-geek.fr" + def getHoster(self): reponse = getURL('http://www.mega-debrid.eu/api.php?action=getHosters') json_data = json_loads(reponse) - if json_data["response_code"] == "ok": + if json_data['response_code'] == "ok": host_list = [element[0] for element in json_data['hosters']] else: self.logError("Unable to retrieve hoster list") diff --git a/module/plugins/hooks/MergeFiles.py b/module/plugins/hooks/MergeFiles.py index 99b0aafc6..a859092fb 100644 --- a/module/plugins/hooks/MergeFiles.py +++ b/module/plugins/hooks/MergeFiles.py @@ -1,56 +1,42 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: and9000 -""" - import os import re import traceback -from os.path import join +from module.plugins.Hook import Hook, threaded from module.utils import save_join, fs_encode -from module.plugins.Hook import Hook - -BUFFER_SIZE = 4096 class MergeFiles(Hook): __name__ = "MergeFiles" + __type__ = "hook" __version__ = "0.12" - __description__ = """Merges parts splitted with hjsplit""" + __config__ = [("activated", "bool", "Activated", False)] - __threaded__ = ["packageFinished"] + + __description__ = """Merges parts splitted with hjsplit""" __author_name__ = "and9000" __author_mail__ = "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("\.[0-9]{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 + if re.search("\.[0-9]{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'] @@ -59,7 +45,7 @@ class MergeFiles(Hook): for name, file_list in files.iteritems(): self.logInfo("Starting merging of %s" % name) - final_file = open(join(download_folder, fs_encode(name)), "wb") + final_file = open(save_join(download_folder, name), "wb") for splitted_file in file_list: self.logDebug("Merging part %s" % splitted_file) @@ -70,10 +56,10 @@ class MergeFiles(Hook): size_written = 0 s_file_size = int(os.path.getsize(os.path.join(download_folder, splitted_file))) while True: - f_buffer = s_file.read(BUFFER_SIZE) + f_buffer = s_file.read(self.BUFFER_SIZE) if f_buffer: final_file.write(f_buffer) - size_written += BUFFER_SIZE + size_written += self.BUFFER_SIZE pyfile.setProgress((size_written * 100) / s_file_size) else: break diff --git a/module/plugins/hooks/MultiDebridCom.py b/module/plugins/hooks/MultiDebridCom.py index f2dfb18ca..c5d1464f8 100644 --- a/module/plugins/hooks/MultiDebridCom.py +++ b/module/plugins/hooks/MultiDebridCom.py @@ -1,28 +1,15 @@ # -*- coding: utf-8 -*- -############################################################################ -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU Affero General Public License as # -# published by the Free Software Foundation, either version 3 of the # -# License, or (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU Affero General Public License for more details. # -# # -# You should have received a copy of the GNU Affero General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -############################################################################ -from module.plugins.internal.MultiHoster import MultiHoster -from module.network.RequestFactory import getURL from module.common.json_layer import json_loads +from module.network.RequestFactory import getURL +from module.plugins.internal.MultiHoster import MultiHoster class MultiDebridCom(MultiHoster): __name__ = "MultiDebridCom" - __version__ = "0.01" __type__ = "hook" + __version__ = "0.01" + __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), ("hosterList", "str", "Hoster list (comma separated)", ""), @@ -33,6 +20,7 @@ class MultiDebridCom(MultiHoster): __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" + def getHoster(self): json_data = getURL('http://multi-debrid.com/api.php?hosts', decode=True) self.logDebug('JSON data: ' + json_data) diff --git a/module/plugins/hooks/MultiHome.py b/module/plugins/hooks/MultiHome.py index b1635a588..e2167b65e 100644 --- a/module/plugins/hooks/MultiHome.py +++ b/module/plugins/hooks/MultiHome.py @@ -1,22 +1,5 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay -""" - from time import time from module.plugins.Hook import Hook @@ -24,19 +7,23 @@ from module.plugins.Hook import Hook class MultiHome(Hook): __name__ = "MultiHome" + __type__ = "hook" __version__ = "0.11" - __description__ = """Ip address changer""" + __config__ = [("activated", "bool", "Activated", False), ("interfaces", "str", "Interfaces", "None")] + + __description__ = """Ip address changer""" __author_name__ = "mkaay" __author_mail__ = "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.parseInterfaces([self.config['download']['interface']]) self.setConfig("interfaces", self.toConfig()) def toConfig(self): @@ -71,6 +58,7 @@ class MultiHome(Hook): class Interface(object): + def __init__(self, adress): self.adress = adress self.history = {} diff --git a/module/plugins/hooks/MultishareCz.py b/module/plugins/hooks/MultishareCz.py index 0291738f5..9249106d6 100644 --- a/module/plugins/hooks/MultishareCz.py +++ b/module/plugins/hooks/MultishareCz.py @@ -8,17 +8,20 @@ from module.plugins.internal.MultiHoster import MultiHoster class MultishareCz(MultiHoster): __name__ = "MultishareCz" - __version__ = "0.04" __type__ = "hook" + __version__ = "0.04" + __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), ("hosterList", "str", "Hoster list (comma separated)", "uloz.to")] + __description__ = """MultiShare.cz hook plugin""" __author_name__ = "zoidberg" __author_mail__ = "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/OverLoadMe.py b/module/plugins/hooks/OverLoadMe.py index e15d0b05f..5be0b8482 100644 --- a/module/plugins/hooks/OverLoadMe.py +++ b/module/plugins/hooks/OverLoadMe.py @@ -6,18 +6,21 @@ from module.plugins.internal.MultiHoster import MultiHoster class OverLoadMe(MultiHoster): __name__ = "OverLoadMe" - __version__ = "0.01" __type__ = "hook" + __version__ = "0.01" + __config__ = [("activated", "bool", "Activated", False), ("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""" __author_name__ = "marley" __author_mail__ = "marley@over-load.me" + def getHoster(self): https = "https" if self.getConfig("https") else "http" page = getURL(https + "://api.over-load.me/hoster.php", diff --git a/module/plugins/hooks/Premium4Me.py b/module/plugins/hooks/Premium4Me.py index 57b188bb9..9c6701b06 100644 --- a/module/plugins/hooks/Premium4Me.py +++ b/module/plugins/hooks/Premium4Me.py @@ -6,16 +6,18 @@ from module.plugins.internal.MultiHoster import MultiHoster class Premium4Me(MultiHoster): __name__ = "Premium4Me" - __version__ = "0.03" __type__ = "hook" + __version__ = "0.03" __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for downloads from supported hosters:", "all"), ("hosterList", "str", "Hoster list (comma separated)", "")] + __description__ = """Premium.to hook plugin""" __author_name__ = ("RaNaN", "zoidberg", "stickell") __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") + def getHoster(self): page = getURL("http://premium.to/api/hosters.php?authcode=%s" % self.account.authcode) return [x.strip() for x in page.replace("\"", "").split(";")] diff --git a/module/plugins/hooks/PremiumizeMe.py b/module/plugins/hooks/PremiumizeMe.py index 9f1a70a70..e7291ece9 100644 --- a/module/plugins/hooks/PremiumizeMe.py +++ b/module/plugins/hooks/PremiumizeMe.py @@ -1,16 +1,14 @@ # -*- coding: utf-8 -*- -from module.plugins.internal.MultiHoster import MultiHoster - 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" - __version__ = "0.12" __type__ = "hook" - __description__ = """Premiumize.me hook plugin""" + __version__ = "0.12" __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), @@ -18,9 +16,11 @@ class PremiumizeMe(MultiHoster): ("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""" __author_name__ = "Florian Franzen" __author_mail__ = "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(): @@ -39,7 +39,7 @@ class PremiumizeMe(MultiHoster): if data['status'] != 200: return [] - # Extract hosters from json file + # Extract hosters from json file return data['result']['hosterlist'] def coreReady(self): @@ -50,5 +50,5 @@ class PremiumizeMe(MultiHoster): 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 + # 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 index 54f814231..9b9b7cda9 100644 --- a/module/plugins/hooks/RPNetBiz.py +++ b/module/plugins/hooks/RPNetBiz.py @@ -1,23 +1,26 @@ # -*- coding: utf-8 -*- -from module.plugins.internal.MultiHoster import MultiHoster 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" - __version__ = "0.1" __type__ = "hook" - __description__ = """RPNet.biz hook plugin""" + __version__ = "0.1" + __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 stanard download if download fails", False), ("interval", "int", "Reload interval in hours (0 to disable)", 24)] + + __description__ = """RPNet.biz hook plugin""" __author_name__ = "Dman" __author_mail__ = "dmanugm@gmail.com" + def getHoster(self): # No hosts supported if no account if not self.account or not self.account.canUse(): @@ -34,7 +37,7 @@ class RPNetBiz(MultiHoster): if 'error' in hoster_list: return [] - # Extract hosters from json file + # Extract hosters from json file return hoster_list['hosters'] def coreReady(self): @@ -45,5 +48,5 @@ class RPNetBiz(MultiHoster): self.logError(_("Please enter your %s account or deactivate this plugin") % "rpnet") return - # Run the overwriten core ready which actually enables the multihoster hook + # 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 index 566f9005f..87902ac7f 100644 --- a/module/plugins/hooks/RealdebridCom.py +++ b/module/plugins/hooks/RealdebridCom.py @@ -6,8 +6,8 @@ from module.plugins.internal.MultiHoster import MultiHoster class RealdebridCom(MultiHoster): __name__ = "RealdebridCom" - __version__ = "0.43" __type__ = "hook" + __version__ = "0.43" __config__ = [("activated", "bool", "Activated", False), ("https", "bool", "Enable HTTPS", False), @@ -15,10 +15,12 @@ class RealdebridCom(MultiHoster): ("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""" __author_name__ = "Devirex Hazzard" __author_mail__ = "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() diff --git a/module/plugins/hooks/RehostTo.py b/module/plugins/hooks/RehostTo.py index 6c3a77ca3..d504bb83b 100644 --- a/module/plugins/hooks/RehostTo.py +++ b/module/plugins/hooks/RehostTo.py @@ -6,8 +6,8 @@ from module.plugins.internal.MultiHoster import MultiHoster class RehostTo(MultiHoster): __name__ = "RehostTo" - __version__ = "0.43" __type__ = "hook" + __version__ = "0.43" __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), @@ -19,6 +19,7 @@ class RehostTo(MultiHoster): __author_name__ = "RaNaN" __author_mail__ = "RaNaN@pyload.org" + def getHoster(self): page = getURL("http://rehost.to/api.php?cmd=get_supported_och_dl&long_ses=%s" % self.long_ses) return [x.strip() for x in page.replace("\"", "").split(",")] @@ -33,7 +34,7 @@ class RehostTo(MultiHoster): return data = self.account.getAccountInfo(user) - self.ses = data["ses"] - self.long_ses = data["long_ses"] + self.ses = data['ses'] + self.long_ses = data['long_ses'] return MultiHoster.coreReady(self) diff --git a/module/plugins/hooks/ReloadCc.py b/module/plugins/hooks/ReloadCc.py deleted file mode 100644 index 9960a2699..000000000 --- a/module/plugins/hooks/ReloadCc.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHoster import MultiHoster - -from module.common.json_layer import json_loads -from module.network.RequestFactory import getURL - - -class ReloadCc(MultiHoster): - __name__ = "ReloadCc" - __version__ = "0.3" - __type__ = "hook" - __description__ = """Reload.cc hook plugin""" - - __config__ = [("activated", "bool", "Activated", False), - ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "")] - - __author_name__ = "Reload Team" - __author_mail__ = "hello@reload.cc" - - interval = 0 # Disable periodic calls - - def getHoster(self): - # If no accounts are available there will be no hosters available - if not self.account or not self.account.canUse(): - print "ReloadCc: No accounts available" - return [] - - # Get account data - (user, data) = self.account.selectAccount() - - # Get supported hosters list from reload.cc using the json API v1 - query_params = dict( - via='pyload', - v=1, - get_supported='true', - get_traffic='true', - user=user - ) - - try: - query_params.update(dict(hash=self.account.infos[user]['pwdhash'])) - except Exception: - query_params.update(dict(pwd=data['password'])) - - answer = getURL("http://api.reload.cc/login", get=query_params) - data = json_loads(answer) - - # If account is not valid thera are no hosters available - if data['status'] != "ok": - print "ReloadCc: Status is not ok: %s" % data['status'] - return [] - - # Extract hosters from json file - return data['msg']['supportedHosters'] - - def coreReady(self): - # Get account plugin and check if there is a valid account available - self.account = self.core.accountManager.getAccountPlugin("ReloadCc") - if not self.account.canUse(): - self.account = None - self.logError("Please add a valid reload.cc 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/RestartFailed.py b/module/plugins/hooks/RestartFailed.py index 85553d738..3aef6f8cd 100644 --- a/module/plugins/hooks/RestartFailed.py +++ b/module/plugins/hooks/RestartFailed.py @@ -1,57 +1,42 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: Walter Purcaro -""" - from module.plugins.Hook import Hook class RestartFailed(Hook): __name__ = "RestartFailed" - __version__ = "1.53" - __description__ = """Periodically restart all failed downloads in queue""" + __type__ = "hook" + __version__ = "1.55" + __config__ = [("activated", "bool", "Activated", False), - ("interval", "int", "Interval in minutes", 90)] + ("interval", "int", "Check interval in minutes", 90)] + + __description__ = """Periodically restart all failed downloads in queue""" __author_name__ = "Walter Purcaro" __author_mail__ = "vuolter@gmail.com" - event_list = ["pluginConfigChanged"] - - MIN_INTERVAL = 15 * 60 # seconds + MIN_INTERVAL = 15 * 60 #: 15m minimum check interval (value is in seconds) - def periodical(self): - self.logDebug("Restart all failed downloads now") - self.core.api.restartFailed() + event_list = ["pluginConfigChanged"] - def restartPeriodical(self, interval): - self.logDebug("Set periodical interval to %s seconds" % interval) - if self.cb: - self.core.scheduler.removeJob(self.cb) - self.interval = interval - self.cb = self.core.scheduler.addJob(interval, self._periodical, threaded=False) def pluginConfigChanged(self, plugin, name, value): - value *= 60 if name == "interval": - if self.interval != value > self.MIN_INTERVAL: - self.restartPeriodical(value) + interval = value * 60 + if self.MIN_INTERVAL <= interval != self.interval: + self.core.scheduler.removeJob(self.cb) + self.interval = interval + self.initPeriodical() else: - self.logWarning("Cannot change interval: given value is equal to the current or \ - smaller than %s seconds" % self.MIN_INTERVAL) + self.logDebug("Invalid interval value, kept current") + + def periodical(self): + self.logInfo("Restart failed downloads") + self.api.restartFailed() + + def setup(self): + self.api = self.core.api + self.interval = self.MIN_INTERVAL def coreReady(self): - self.pluginConfigChanged(plugin="RestartFailed", name="interval", value=self.getConfig("interval")) + self.pluginConfigChanged(self.__name__, "interval", self.getConfig("interval")) diff --git a/module/plugins/hooks/SimplyPremiumCom.py b/module/plugins/hooks/SimplyPremiumCom.py index 60d164c66..a946d391e 100644 --- a/module/plugins/hooks/SimplyPremiumCom.py +++ b/module/plugins/hooks/SimplyPremiumCom.py @@ -1,38 +1,26 @@ # -*- coding: utf-8 -*- -############################################################################ -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU Affero General Public License as # -# published by the Free Software Foundation, either version 3 of the # -# License, or (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU Affero General Public License for more details. # -# # -# You should have received a copy of the GNU Affero General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -############################################################################ - -from module.plugins.internal.MultiHoster import MultiHoster -from module.network.RequestFactory import getURL 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" - __version__ = "0.02" __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""" + + __description__ = """Simply-Premium.com hook plugin""" __author_name__ = "EvolutionClip" __author_mail__ = "evolutionclip@live.de" + def getHoster(self): json_data = getURL('http://www.simply-premium.com/api/hosts.php?format=json&online=1') json_data = json_loads(json_data) diff --git a/module/plugins/hooks/SimplydebridCom.py b/module/plugins/hooks/SimplydebridCom.py index a523d2404..ab13f312e 100644 --- a/module/plugins/hooks/SimplydebridCom.py +++ b/module/plugins/hooks/SimplydebridCom.py @@ -6,15 +6,18 @@ from module.plugins.internal.MultiHoster import MultiHoster class SimplydebridCom(MultiHoster): __name__ = "SimplydebridCom" - __version__ = "0.01" __type__ = "hook" + __version__ = "0.01" + __config__ = [("activated", "bool", "Activated", False), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), ("hosterList", "str", "Hoster list (comma separated)", "")] + __description__ = """Simply-Debrid.com hook plugin""" __author_name__ = "Kagenoshin" __author_mail__ = "kagenoshin@gmx.ch" + def getHoster(self): page = getURL("http://simply-debrid.com/api.php?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 index af6039ecd..f25c5e2b4 100644 --- a/module/plugins/hooks/UnSkipOnFail.py +++ b/module/plugins/hooks/UnSkipOnFail.py @@ -1,35 +1,23 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: hgg -""" from os.path import basename -from module.utils import fs_encode -from module.plugins.Hook import Hook from module.PyFile import PyFile +from module.plugins.Hook import Hook +from module.utils import fs_encode class UnSkipOnFail(Hook): - __name__ = 'UnSkipOnFail' - __version__ = '0.01' - __description__ = """When a download fails, restart skipped duplicates""" + __name__ = "UnSkipOnFail" + __type__ = "hook" + __version__ = "0.01" + __config__ = [("activated", "bool", "Activated", True)] + + __description__ = """When a download fails, restart skipped duplicates""" __author_name__ = "hagg" - __author_mail__ = "" + __author_mail__ = None + def downloadFailed(self, pyfile): pyfile_name = basename(pyfile.name) diff --git a/module/plugins/hooks/UnrestrictLi.py b/module/plugins/hooks/UnrestrictLi.py index 4f8f11625..ee5d79269 100644 --- a/module/plugins/hooks/UnrestrictLi.py +++ b/module/plugins/hooks/UnrestrictLi.py @@ -1,28 +1,15 @@ # -*- coding: utf-8 -*- -############################################################################ -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU Affero General Public License as # -# published by the Free Software Foundation, either version 3 of the # -# License, or (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU Affero General Public License for more details. # -# # -# You should have received a copy of the GNU Affero General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -############################################################################ -from module.plugins.internal.MultiHoster import MultiHoster -from module.network.RequestFactory import getURL 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" - __version__ = "0.02" __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)", ""), @@ -34,6 +21,7 @@ class UnrestrictLi(MultiHoster): __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" + def getHoster(self): json_data = getURL('http://unrestrict.li/api/jdownloader/hosts.php?format=json') json_data = json_loads(json_data) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 9f8ccdb80..546e6e6e8 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -1,67 +1,81 @@ # -*- coding: utf-8 -*- -import sys import re +import sys -from os import remove, stat -from os.path import join, isfile -from time import time +from operator import itemgetter +from os import path, remove, stat -from module.ConfigParser import IGNORE from module.network.RequestFactory import getURL -from module.plugins.Hook import threaded, Expose, Hook +from module.plugins.Hook import Expose, Hook, threaded +from module.utils import save_join class UpdateManager(Hook): __name__ = "UpdateManager" - __version__ = "0.24" - __description__ = """Check for updates""" + __type__ = "hook" + __version__ = "0.35" + __config__ = [("activated", "bool", "Activated", True), ("mode", "pyLoad + plugins;plugins only", "Check updates for", "pyLoad + plugins"), ("interval", "int", "Check interval in hours", 8), ("reloadplugins", "bool", "Monitor plugins for code changes (debug mode only)", True), ("nodebugupdate", "bool", "Don't check for updates in debug mode", True)] - __author_name__ = ("RaNaN", "stickell", "Walter Purcaro") - __author_mail__ = ("ranan@pyload.org", "l.stickell@yahoo.it", "vuolter@gmail.com") - SERVER_URL = "http://updatemanager.pyload.org" - MIN_TIME = 3 * 60 * 60 #: 3h minimum check interval + __description__ = """ Check for updates """ + __author_name__ = "Walter Purcaro" + __author_mail__ = "vuolter@gmail.com" + event_list = ["pluginConfigChanged"] + SERVER_URL = "http://updatemanager.pyload.org" + MIN_INTERVAL = 3 * 60 * 60 #: 3h minimum check interval (value is in seconds) + def pluginConfigChanged(self, plugin, name, value): - if name == "interval" and 0 < value != self.interval: - self.interval = max(value * 60 * 60, self.MIN_TIME) - self.initPeriodical() + 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 and self.core.debug: + if value is True and self.core.debug: self.periodical2() def coreReady(self): - self.pluginConfigChanged(self.__name__, "reloadplugins", self.getConfig("reloadplugins")) + 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_TIME + self.interval = self.MIN_INTERVAL self.updating = False - self.info = {"pyload": False, "version": None, "plugins": 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(10, self.periodical2, threaded=True) + 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()) + lambda m: m and (m.__name__.startswith("module.plugins.") or + m.__name__.startswith("userplugins.")) and + m.__name__.count(".") >= 2, sys.modules.itervalues() + ) reloads = [] @@ -70,7 +84,7 @@ class UpdateManager(Hook): id = (type, name) if type in self.core.pluginManager.plugins: f = m.__file__.replace(".pyc", ".py") - if not isfile(f): + if not path.isfile(f): continue mtime = stat(f).st_mtime @@ -83,18 +97,24 @@ class UpdateManager(Hook): return True if self.core.pluginManager.reloadPlugins(reloads) else False - @threaded def periodical(self): - if not self.info["pyload"] and not (self.getConfig("nodebugupdate") and self.core.debug): - self.updating = True - self.update(onlyplugin=True if self.getConfig("mode") == "plugins only" else False) - self.updating = False + if not self.info['pyload'] and not (self.getConfig("nodebugupdate") and self.core.debug): + self.updateThread() - def server_response(self): + def server_request(self): try: return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines() except: - self.logWarning(_("Not able to connect server to get updates")) + 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 == 2: + self.core.api.restart() + else: + self.updating = False @Expose def updatePlugins(self): @@ -104,53 +124,54 @@ class UpdateManager(Hook): @Expose def update(self, onlyplugin=False): """ check for updates """ - data = self.server_response() + data = self.server_request() if not data: - r = False + exitcode = 0 elif data[0] == "None": - self.logInfo(_("No pyLoad version available")) + self.logInfo(_("No new pyLoad version available")) updates = data[1:] - r = self._updatePlugins(updates) + exitcode = self._updatePlugins(updates) elif onlyplugin: - r = False + 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 ***")) - r = self.info["pyload"] = True - self.info["version"] = newversion - return r + 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"]: + if self.info['plugins']: return False #: plugins were already updated updated = [] vre = re.compile(r'__version__.*=.*("|\')([0-9.]+)') url = updates[0] - schema = updates[1].split("|") - if 'BLACKLIST' in updates: + 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:] - for plugin in updates: - info = dict(zip(schema, plugin.split("|"))) - filename = info["name"] - prefix = info["type"] - version = info["version"] + upgradable = sorted(map(lambda x: dict(zip(schema, x.split('|'))), updates), key=itemgetter("type", "name")) + for plugin in upgradable: + filename = plugin['name'] + prefix = plugin['type'] + version = plugin['version'] if filename.endswith(".pyc"): name = filename[:filename.find("_")] else: name = filename.replace(".py", "") - #TODO: obsolete in 0.5.0 + #@TODO: obsolete after 0.4.10 if prefix.endswith("s"): type = prefix[:-1] else: @@ -158,77 +179,103 @@ class UpdateManager(Hook): plugins = getattr(self.core.pluginManager, "%sPlugins" % type) - if name not in plugins or name in IGNORE or (type, name) in IGNORE: - continue - - oldver = float(plugins[name]["v"]) + oldver = float(plugins[name]['v']) if name in plugins else None newver = float(version) - if oldver >= newver: - continue + if not oldver: + msg = "New [%(type)s] %(name)s (v%(newver)s)" + elif newver > oldver: + msg = "New version of [%(type)s] %(name)s (v%(oldver)s -> v%(newver)s)" else: - self.logInfo(_("New version of [%(type)s] %(name)s (v%(oldver)s -> v%(newver)s)") % { - "type": type, - "name": name, - "oldver": oldver, - "newver": newver - }) + continue + + self.logInfo(_(msg) % { + 'type': type, + 'name': name, + 'oldver': oldver, + 'newver': newver, + }) try: - content = getURL(url % info) + content = getURL(url % plugin) + m = vre.search(content) + if m and m.group(2) == version: + f = open(save_join("userplugins", prefix, filename), "wb") + f.write(content) + f.close() + updated.append((prefix, name)) + else: + raise Exception, _("Version mismatch") except Exception, e: - self.logError(_("Error when updating plugin %s") % filename, str(e)) - continue + self.logError(_("Error updating plugin %s") % filename, str(e)) - m = vre.search(content) - if not m or m.group(2) != version: - self.logError(_("Error when updating plugin %s") % name, _("Version mismatch")) - continue + if blacklist: + blacklisted = sorted(map(lambda x: (x.split('|')[0], x.split('|')[1].rsplit('.', 1)[0]), blacklist)) - f = open(join("userplugins", prefix, filename), "wb") - f.write(content) - f.close() - updated.append((prefix, name)) + # Always protect UpdateManager from self-removing + try: + blacklisted.remove(("hook", "UpdateManager")) + except: + pass - if blacklist: - removed = self.removePlugins(map(lambda x: x.split('|'), blacklist)) + removed = self.removePlugins(blacklisted) for t, n in removed: - self.logInfo(_("Removed blacklisted plugin: [%(type)s] %(name)s") % { - "type": t, - "name": n + self.logInfo(_("Removed blacklisted plugin [%(type)s] %(name)s") % { + 'type': t, + 'name': n, }) 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, pyLoad will be restarted now ***")) - self.info["plugins"] = True - self.core.scheduler.addJob(4, self.core.api.restart(), threaded=False) #: risky, but pyload doesn't let more - return True + 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 False + exitcode = 0 + + return exitcode #: 0 = No plugins updated; 1 = Plugins updated; 2 = Plugins updated, but restart required @Expose def removePlugins(self, type_plugins): - """ delete plugins under userplugins directory""" + """ delete plugins from disk """ + if not type_plugins: - return None + return self.logDebug("Request deletion of plugins: %s" % type_plugins) removed = [] for type, name in type_plugins: - py = join("userplugins", type, name) - pyc = join("userplugins", type, name.replace('.py', '.pyc')) - if isfile(py): + 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 deleting \"%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 deleting \"%s\"" % path.basename(filename), str(e)) + err = True + + if not err: id = (type, name) - remove(py) removed.append(id) - if isfile(pyc): - remove(pyc) return removed #: return a list of the plugins successfully removed diff --git a/module/plugins/hooks/Vipleech4uCom.py b/module/plugins/hooks/Vipleech4uCom.py deleted file mode 100644 index b2156b017..000000000 --- a/module/plugins/hooks/Vipleech4uCom.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -import re - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - - -class Vipleech4uCom(MultiHoster): - __name__ = "Vipleech4uCom" - __version__ = "0.01" - __type__ = "hook" - __config__ = [("activated", "bool", "Activated", "False"), - ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "")] - __description__ = """Vipleech4u.com hook plugin""" - __author_name__ = ("Kagenoshin") - __author_mail__ = ("kagenoshin@gmx.ch") - - HOSTER_PATTERN = re.compile(r'align\s*?=\s*?["\']*?left.*?<\s*?strong\s*?>([^<]*?)<', re.I) - - def getHoster(self): - hosters = { - 'depositfiles': ['depositfiles.com', 'dfiles.eu'], - 'uploaded': ['uploaded.to', 'uploaded.net', 'ul.to'], - 'rapidggator': ['rapidgator.net'], # they have a typo it's called rapidgator - 'freakshare': ['freakshare.net', 'freakshare.com'], - 'filefactory': ['filefactory.com'], - 'bitshare': ['bitshare.com'], - 'share-online': ['share-online.biz', 'egoshare.com'], - 'youtube': ['youtube.com'], - 'turbobit': ['turbobit.net', 'unextfiles.com'], - 'firedrive': ['firedrive.com', 'putlocker.com'], - 'filepost': ['filepost.com', 'fp.io'], - 'netload': ['netload.in'], - 'uploadhero': ['uploadhero.com'], - 'ryushare': ['ryushare.com'], - } - - #check if the list is still valid - self.check_for_new_or_removed_hosters(hosters) - - #build list - hoster_list = [] - - for item in hosters.itervalues(): - hoster_list.extend(item) - - return hoster_list - - def check_for_new_or_removed_hosters(self, hosters): - #get the old hosters - old_hosters = hosters.keys() - - #load the current hosters from vipleech4u.com - page = getURL('http://vipleech4u.com/hosts.php') - current_hosters = self.HOSTER_PATTERN.findall(page) - current_hosters = [x.lower() for x in current_hosters] - - #let's look for new hosters - new_hosters = [] - - for hoster in current_hosters: - if not hoster in old_hosters: - new_hosters.append(hoster) - - #let's look for removed hosters - removed_hosters = [] - - for hoster in old_hosters: - if not hoster in current_hosters: - removed_hosters.append(hoster) - - if new_hosters: - self.logDebug('The following new hosters were found on vipleech4u.com: %s' % str(new_hosters)) - - if removed_hosters: - self.logDebug('The following hosters were removed from vipleech4u.com: %s' % str(removed_hosters)) - - if not (new_hosters and removed_hosters): - self.logDebug('The hoster list is still valid.') diff --git a/module/plugins/hooks/WindowsPhoneToastNotify.py b/module/plugins/hooks/WindowsPhoneToastNotify.py index 7c005fcbb..01570b966 100644 --- a/module/plugins/hooks/WindowsPhoneToastNotify.py +++ b/module/plugins/hooks/WindowsPhoneToastNotify.py @@ -1,38 +1,27 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: RaNaN, Godofdream, zoidberg -""" -import time import httplib +import time + from module.plugins.Hook import Hook class WindowsPhoneToastNotify(Hook): __name__ = "WindowsPhoneToastNotify" + __type__ = "hook" __version__ = "0.02" - __description__ = """Send push notifications to Windows Phone""" - __author_name__ = "Andy Voigt" - __author_mail__ = "phone-support@hotmail.de" + __config__ = [("activated", "bool", "Activated", False), ("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""" + __author_name__ = "Andy Voigt" + __author_mail__ = "phone-support@hotmail.de" + + def setup(self): self.info = {} diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py index 19ecc08b6..eb0376921 100644 --- a/module/plugins/hooks/XFileSharingPro.py +++ b/module/plugins/hooks/XFileSharingPro.py @@ -7,16 +7,19 @@ from module.plugins.Hook import Hook class XFileSharingPro(Hook): __name__ = "XFileSharingPro" - __version__ = "0.11" __type__ = "hook" + __version__ = "0.11" + __config__ = [("activated", "bool", "Activated", True), ("loadDefault", "bool", "Include default (built-in) hoster list", True), ("includeList", "str", "Include hosters (comma separated)", ""), ("excludeList", "str", "Exclude hosters (comma separated)", "")] + __description__ = """XFileSharingPro hook plugin""" __author_name__ = "zoidberg" __author_mail__ = "zoidberg@mujmail.cz" + def coreReady(self): self.loadPattern() @@ -61,8 +64,8 @@ class XFileSharingPro(Hook): #self.logDebug(regexp) dict = self.core.pluginManager.hosterPlugins['XFileSharingPro'] - dict["pattern"] = regexp - dict["re"] = re.compile(regexp) + dict['pattern'] = regexp + dict['re'] = re.compile(regexp) self.logDebug("Pattern loaded - handling %d hosters" % len(hosterList)) def getConfigSet(self, option): @@ -71,5 +74,5 @@ class XFileSharingPro(Hook): def unload(self): dict = self.core.pluginManager.hosterPlugins['XFileSharingPro'] - dict["pattern"] = r"^unmatchable$" - dict["re"] = re.compile(r"^unmatchable$") + dict['pattern'] = r'^unmatchable$' + dict['re'] = re.compile(r'^unmatchable$') diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py index 5ecf4e153..c4a94a8bc 100644 --- a/module/plugins/hooks/XMPPInterface.py +++ b/module/plugins/hooks/XMPPInterface.py @@ -1,36 +1,19 @@ # -*- coding: utf-8 -*- -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: RaNaN - @interface-version: 0.2 -""" - from pyxmpp import streamtls from pyxmpp.all import JID, Message -from pyxmpp.jabber.client import JabberClient 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" - __description__ = """Connect to jabber and let owner perform different tasks""" + __config__ = [("activated", "bool", "Activated", False), ("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"), ("pw", "str", "Password", ""), @@ -39,9 +22,12 @@ class XMPPInterface(IRCInterface, JabberClient): ("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""" __author_name__ = "RaNaN" __author_mail__ = "RaNaN@pyload.org" + implements(IMessageHandlersProvider) def __init__(self, core, manager): @@ -120,16 +106,14 @@ class XMPPInterface(IRCInterface, JabberClient): The handlers returned will be called when matching message is received in a client session.""" - return [ - ("normal", self.message), - ] + 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(u'pyLoad XMPP: Message from %s received.' % (unicode(stanza.get_from(), ))) + self.logDebug(u'pyLoad XMPP: Message from %s received.' % (unicode(stanza.get_from(),))) self.logDebug(u'pyLoad XMPP: Body: %s Subject: %s Type: %s' % (body, subject, t)) if t == "headline": @@ -230,9 +214,7 @@ class VersionHandler(object): 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), - ] + 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.""" diff --git a/module/plugins/hooks/ZeveraCom.py b/module/plugins/hooks/ZeveraCom.py index 4dee83ccb..0d5e23118 100644 --- a/module/plugins/hooks/ZeveraCom.py +++ b/module/plugins/hooks/ZeveraCom.py @@ -6,15 +6,18 @@ from module.plugins.internal.MultiHoster import MultiHoster class ZeveraCom(MultiHoster): __name__ = "ZeveraCom" - __version__ = "0.02" __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)", "")] + __description__ = """Real-Debrid.com hook plugin""" __author_name__ = "zoidberg" __author_mail__ = "zoidberg@mujmail.cz" + def getHoster(self): page = getURL("http://www.zevera.com/jDownloader.ashx?cmd=gethosters") return [x.strip() for x in page.replace("\"", "").split(",")] |