diff options
Diffstat (limited to 'module/plugins/addons')
35 files changed, 0 insertions, 3854 deletions
| diff --git a/module/plugins/addons/AlldebridCom.py b/module/plugins/addons/AlldebridCom.py deleted file mode 100644 index 6818b8c43..000000000 --- a/module/plugins/addons/AlldebridCom.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- 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" - -    __config__ = [("activated", "bool", "Activated", "False"), -                  ("https", "bool", "Enable HTTPS", "False"), -                  ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), -                  ("hosterList", "str", "Hoster list (comma separated)", ""), -                  ("unloadFailing", "bool", "Revert to stanard download if download fails", "False"), -                  ("interval", "int", "Reload interval in hours (0 to disable)", "24")] - -    __description__ = """Real-Debrid.com hook plugin""" -    __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() -         -        return [x.strip() for x in page.split(",") if x.strip()] diff --git a/module/plugins/addons/BypassCaptcha.py b/module/plugins/addons/BypassCaptcha.py deleted file mode 100644 index 24ad17dd8..000000000 --- a/module/plugins/addons/BypassCaptcha.py +++ /dev/null @@ -1,143 +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: RaNaN, Godofdream, zoidberg -""" - -from thread import start_new_thread -from pycurl import FORM_FILE, LOW_SPEED_TIME - -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader - -from module.plugins.Hook import Hook - -PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32" - -class BypassCaptchaException(Exception): -    def __init__(self, err): -        self.err = err - -    def getCode(self): -        return self.err - -    def __str__(self): -        return "<BypassCaptchaException %s>" % self.err - -    def __repr__(self): -        return "<BypassCaptchaException %s>" % self.err - -class BypassCaptcha(Hook): -    __name__ = "BypassCaptcha" -    __version__ = "0.03" -    __description__ = """send captchas to BypassCaptcha.com""" -    __config__ = [("activated", "bool", "Activated", True), -                  ("force", "bool", "Force BC even if client is connected", False), -                  ("passkey", "password", "Passkey", "")] -    __author_name__ = ("RaNaN", "Godofdream", "zoidberg") -    __author_mail__ = ("RaNaN@pyload.org", "soilfcition@gmail.com", "zoidberg@mujmail.cz") - -    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 = {} - -    def getCredits(self): -        response = getURL(self.GETCREDITS_URL, -                      post = {"key": self.getConfig("passkey")} -                      ) -                                                                          -        data = dict([x.split(' ',1) for x in response.splitlines()]) -        return int(data['Left']) -         - -    def submit(self, captcha, captchaType="file", match=None): -        req = getRequest() - -        #raise timeout threshold -        req.c.setopt(LOW_SPEED_TIME, 80) - -        try: -            response = req.load(self.SUBMIT_URL,  -                            post={"vendor_key": PYLOAD_KEY, -                                  "key": self.getConfig("passkey"), -                                  "gen_task_id": "1", -                                  "file": (FORM_FILE, captcha)}, -                            multipart=True) -        finally: -            req.close() - -        data = dict([x.split(' ',1) for x in response.splitlines()]) -        if not data or "Value" not in data: -            raise BypassCaptchaException(response) -             -        result = data['Value'] -        ticket = data['TaskId'] -        self.logDebug("result %s : %s" % (ticket,result)) - -        return ticket, result - -    def respond(self, ticket, success): -        try: -            response = getURL(self.RESPOND_URL,  -                              post={"task_id": ticket, -                                    "key": self.getConfig("passkey"), -                                    "cv": 1 if success else 0} -                              ) -        except BadHeader, e: -            self.logError("Could not send response.", str(e)) - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False -         -        if not task.isTextual(): -            return False - -        if not self.getConfig("passkey"): -            return False - -        if self.core.isClientConnected() and not self.getConfig("force"): -            return False - -        if self.getCredits() > 0: -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(100) -            start_new_thread(self.processCaptcha, (task,)) - -        else: -            self.logInfo("Your %s account has not enough credits" % self.__name__) - -    def captchaCorrect(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            self.respond(task.data["ticket"], True) - -    def captchaInvalid(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            self.respond(task.data["ticket"], False) - -    def processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except BypassCaptchaException, e: -            task.error = e.getCode() -            return - -        task.data["ticket"] = ticket -        task.setResult(result)
\ No newline at end of file diff --git a/module/plugins/addons/CaptchaBrotherhood.py b/module/plugins/addons/CaptchaBrotherhood.py deleted file mode 100644 index bdf547827..000000000 --- a/module/plugins/addons/CaptchaBrotherhood.py +++ /dev/null @@ -1,169 +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, 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 Image - -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader -from module.plugins.Hook import Hook - -class CaptchaBrotherhoodException(Exception): -    def __init__(self, err): -        self.err = err - -    def getCode(self): -        return self.err - -    def __str__(self): -        return "<CaptchaBrotherhoodException %s>" % self.err - -    def __repr__(self): -        return "<CaptchaBrotherhoodException %s>" % self.err - -class CaptchaBrotherhood(Hook): -    __name__ = "CaptchaBrotherhood" -    __version__ = "0.04" -    __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", ""),] -    __author_name__ = ("RaNaN", "zoidberg") -    __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") -     -    API_URL = "http://www.captchabrotherhood.com/" - -    def setup(self): -        self.info = {} - -    def getCredits(self): -        response = getURL(self.API_URL + "askCredits.aspx", -                          get = {"username": self.getConfig("username"), -                                 "password": self.getConfig("passkey")}) -        if not response.startswith("OK"): -            raise CaptchaBrotherhoodException(response) -        else: -            credits = int(response[3:]) -            self.logInfo(_("%d credits left") % credits) -            self.info["credits"] = credits -            return credits - -    def submit(self, captcha, captchaType="file", match=None):                -        try: -            img = Image.open(captcha) -            output = StringIO.StringIO() -            self.logDebug("CAPTCHA IMAGE", img, img.format, img.mode) -            if img.format in ("GIF", "JPEG"): -                img.save(output, img.format) -            else:     -                if img.mode != "RGB": -                    img = img.convert("RGB") -                img.save(output, "JPEG") -            data = output.getvalue() -            output.close() -        except Exception, e: -            raise CaptchaBrotherhoodException("Reading or converting captcha image failed: %s" % e) -         -        req = getRequest() - -        url = "%ssendNewCaptcha.aspx?%s" % (self.API_URL,  -                   urlencode({"username": self.getConfig("username"), -                              "password": self.getConfig("passkey"), -                              "captchaSource": "pyLoad", -                              "timeout": "80"}) -                   ) - -        req.c.setopt(pycurl.URL, url) -        req.c.setopt(pycurl.POST, 1) -        req.c.setopt(pycurl.POSTFIELDS, data) -        req.c.setopt(pycurl.HTTPHEADER, [ "Content-Type: text/html" ])         - -        try: -            req.c.perform() -            response = req.getResponse() -        except Exception, e: -            raise CaptchaBrotherhoodException("Submit captcha image failed") -             -        req.close() - -        if not response.startswith("OK"): -            raise CaptchaBrotherhoodException(response[1]) -        -        ticket = response[3:] -         -        for i in range(15): -            sleep(5) -            response = self.get_api("askCaptchaResult", ticket) -            if response.startswith("OK-answered"): -                return ticket, response[12:]  - -        raise CaptchaBrotherhoodException("No solution received in time") - -    def get_api(self, api, ticket): -        response = getURL("%s%s.aspx" % (self.API_URL, api),  -                          get={"username": self.getConfig("username"), -                               "password": self.getConfig("passkey"), -                               "captchaID": ticket} -                          ) -        if not response.startswith("OK"): -            raise CaptchaBrotherhoodException("Unknown response: %s" % response) -         -        return response - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False -             -        if not task.isTextual(): -            return False - -        if not self.getConfig("username") or not self.getConfig("passkey"): -            return False - -        if self.core.isClientConnected() and not self.getConfig("force"): -            return False - -        if self.getCredits() > 10: -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(100) -            start_new_thread(self.processCaptcha, (task,)) -        else: -            self.logInfo("Your CaptchaBrotherhood Account has not enough credits") - -    def captchaInvalid(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            response = self.get_api("complainCaptcha", task.data['ticket']) - -    def processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except CaptchaBrotherhoodException, e: -            task.error = e.getCode() -            return - -        task.data["ticket"] = ticket -        task.setResult(result)
\ No newline at end of file diff --git a/module/plugins/addons/CaptchaTrader.py b/module/plugins/addons/CaptchaTrader.py deleted file mode 100644 index 889fa38ef..000000000 --- a/module/plugins/addons/CaptchaTrader.py +++ /dev/null @@ -1,159 +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 -""" - -try: -    from json import loads -except ImportError: -    from simplejson import loads - -from thread import start_new_thread -from pycurl import FORM_FILE, LOW_SPEED_TIME - -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader - -from module.plugins.Addon import Addon - -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(Addon): -    __name__ = "CaptchaTrader" -    __version__ = "0.14" -    __description__ = """send captchas to captchatrader.com""" -    __config__ = [("activated", "bool", "Activated", True), -                  ("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 = 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 = 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 = 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/addons/Checksum.py b/module/plugins/addons/Checksum.py deleted file mode 100644 index b290838bb..000000000 --- a/module/plugins/addons/Checksum.py +++ /dev/null @@ -1,169 +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: zoidberg -""" -from __future__ import with_statement -import hashlib, 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 - -def computeChecksum(local_file, algorithm):  -    if algorithm in getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")): -        h = getattr(hashlib, algorithm)() -        chunk_size = 128 * h.block_size -         -        with open(local_file, 'rb') as f:  -            for chunk in iter(lambda: f.read(chunk_size), ''):  -                 h.update(chunk) -         -        return h.hexdigest() -          -    elif algorithm in ("adler32", "crc32"): -        hf = getattr(zlib, algorithm) -        last = 0 -         -        with open(local_file, 'rb') as f:  -            for chunk in iter(lambda: f.read(8192), ''):  -                last = hf(chunk, last) -         -        return "%x" % last -     -    else: -        return None       - -class Checksum(Hook): -    __name__ = "Checksum" -    __version__ = "0.07" -    __description__ = "Verify downloaded file size and checksum (enable in general preferences)" -    __config__ = [("activated", "bool", "Activated", True), -                  ("action", "fail;retry;nothing", "What to do if check fails?", "retry"), -                  ("max_tries", "int", "Number of retries", 2)] -    __author_name__ = ("zoidberg") -    __author_mail__ = ("zoidberg@mujmail.cz") -     -    methods = { 'sfv':'crc32', 'crc': 'crc32', 'hash': 'md5'} -    regexps = { 'sfv': r'^(?P<name>[^;].+)\s+(?P<hash>[0-9A-Fa-f]{8})$', -                'md5': r'^(?P<name>[0-9A-Fa-f]{32})  (?P<file>.+)$', -                'crc': r'filename=(?P<name>.+)\nsize=(?P<size>\d+)\ncrc32=(?P<hash>[0-9A-Fa-f]{8})$',   -                'default': r'^(?P<hash>[0-9A-Fa-f]+)\s+\*?(?P<name>.+)$' } -     -    def setup(self):     -        if not self.config['general']['checksum']: -            self.logInfo("Checksum validation is disabled in general configuration") - -        self.algorithms = sorted(getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse = True) -        self.algorithms.extend(["crc32", "adler32"])                     -        self.formats = self.algorithms + ['sfv', 'crc', 'hash']                                    -              -    def downloadFinished(self, pyfile): -        """  -        Compute checksum for the downloaded file and compare it with the hash provided by the hoster. -        pyfile.plugin.check_data should be a dictionary which can contain: -        a) if known, the exact filesize in bytes (e.g. "size": 123456789) -        b) hexadecimal hash string with algorithm name as key (e.g. "md5": "d76505d0869f9f928a17d42d66326307")     -        """                 -        if hasattr(pyfile.plugin, "check_data") and (isinstance(pyfile.plugin.check_data, dict)): -            data = pyfile.plugin.check_data.copy()         -        elif hasattr(pyfile.plugin, "api_data") and (isinstance(pyfile.plugin.api_data, dict)): -            data = pyfile.plugin.api_data.copy()   -        else: -            return  -         -        self.logDebug(data)        -         -        if not pyfile.plugin.lastDownload: -            self.checkFailed(pyfile, None, "No file downloaded")  -                -        local_file = fs_encode(pyfile.plugin.lastDownload) -        #download_folder = self.config['general']['download_folder'] -        #local_file = fs_encode(save_join(download_folder, pyfile.package().folder, pyfile.name)) -         -        if not isfile(local_file): -            self.checkFailed(pyfile, None, "File does not exist")   -         -        # validate file size -        if "size" in data: -            api_size = int(data['size']) -            file_size = getsize(local_file) -            if api_size != file_size: -                self.logWarning("File %s has incorrect size: %d B (%d expected)" % (pyfile.name, file_size, api_size)) -                self.checkFailed(pyfile, local_file, "Incorrect file size") -            del data['size'] -                 -        # validate checksum -        if data and self.config['general']['checksum']:                                                        -            if "checksum" in data: -                data['md5'] = data['checksum'] -             -            for key in self.algorithms: -                if key in data:  -                    checksum = computeChecksum(local_file, key.replace("-","").lower())                     -                    if checksum: -                        if checksum == data[key]: -                            self.logInfo('File integrity of "%s" verified by %s checksum (%s).' % (pyfile.name, key.upper(), checksum)) -                            return -                        else: -                            self.logWarning("%s checksum for file %s does not match (%s != %s)" % (key.upper(), pyfile.name, checksum, data[key]))     -                            self.checkFailed(pyfile, local_file, "Checksums do not match") -                    else: -                        self.logWarning("Unsupported hashing algorithm: %s" % key.upper())   -            else: -                self.logWarning("Unable to validate checksum for file %s" % (pyfile.name)) -     -    def checkFailed(self, pyfile, local_file, msg): -        action = self.getConfig("action") -        if action == "fail": -            pyfile.plugin.fail(reason = msg) -        elif action == "retry": -            if local_file: -                remove(local_file) -            pyfile.plugin.retry(reason = msg, max_tries = self.getConfig("max_tries")) - -            -    def packageFinished(self, pypack): -        download_folder = save_join(self.config['general']['download_folder'], pypack.folder, "") -         -        for link in pypack.getChildren().itervalues(): -            file_type = splitext(link["name"])[1][1:].lower() -            #self.logDebug(link, file_type) -             -            if file_type not in self.formats: -                continue -             -            hash_file = fs_encode(save_join(download_folder, link["name"]))    -            if not isfile(hash_file): -                self.logWarning("File not found: %s" % link["name"]) -                continue -                 -            with open(hash_file) as f: -                text = f.read() -                 -            for m in re.finditer(self.regexps.get(file_type, self.regexps['default']), text): -                data = m.groupdict()  -                self.logDebug(link["name"], data) -                                -                local_file = fs_encode(save_join(download_folder, data["name"])) -                algorithm = self.methods.get(file_type, file_type) -                checksum = computeChecksum(local_file, algorithm) -                if checksum == data["hash"]: -                    self.logInfo('File integrity of "%s" verified by %s checksum (%s).' % (data["name"], algorithm, checksum)) -                else: -                    self.logWarning("%s checksum for file %s does not match (%s != %s)" % (algorithm, data["name"], checksum, data["hash"]))
\ No newline at end of file diff --git a/module/plugins/addons/ClickAndLoad.py b/module/plugins/addons/ClickAndLoad.py deleted file mode 100644 index 6d6928557..000000000 --- a/module/plugins/addons/ClickAndLoad.py +++ /dev/null @@ -1,89 +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: RaNaN -    @interface-version: 0.2 -""" - -import socket -import thread - -from module.plugins.Addon import Addon - -class ClickAndLoad(Addon): -    __name__ = "ClickAndLoad" -    __version__ = "0.2" -    __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")] -    __author_name__ = ("RaNaN", "mkaay") -    __author_mail__ = ("RaNaN@pyload.de", "mkaay@mkaay.de") - -    def activate(self): -        self.port = int(self.core.config['webinterface']['port']) -        if self.core.config['webinterface']['activated']: -            try: -                if self.getConfig("extern"): -                    ip = "0.0.0.0" -                else: -                    ip = "127.0.0.1" - -                thread.start_new_thread(proxy, (self, ip, self.port, 9666)) -            except: -                self.log.error("ClickAndLoad port already in use.") - - -def proxy(self, *settings): -    thread.start_new_thread(server, (self,) + settings) -    lock = thread.allocate_lock() -    lock.acquire() -    lock.acquire() - - -def server(self, *settings): -    try: -        dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -        dock_socket.bind((settings[0], settings[2])) -        dock_socket.listen(5) -        while True: -            client_socket = dock_socket.accept()[0] -            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -            server_socket.connect(("127.0.0.1", settings[1])) -            thread.start_new_thread(forward, (client_socket, server_socket)) -            thread.start_new_thread(forward, (server_socket, client_socket)) -    except socket.error, e: -        if hasattr(e, "errno"): -            errno = e.errno -        else: -            errno = e.args[0] - -        if errno == 98: -            self.core.log.warning(_("Click'N'Load: Port 9666 already in use")) -            return -        thread.start_new_thread(server, (self,) + settings) -    except: -        thread.start_new_thread(server, (self,) + settings) - - -def forward(source, destination): -    string = ' ' -    while string: -        string = source.recv(1024) -        if string: -            destination.sendall(string) -        else: -            #source.shutdown(socket.SHUT_RD) -            destination.shutdown(socket.SHUT_WR) diff --git a/module/plugins/addons/DeathByCaptcha.py b/module/plugins/addons/DeathByCaptcha.py deleted file mode 100644 index 59ff40ded..000000000 --- a/module/plugins/addons/DeathByCaptcha.py +++ /dev/null @@ -1,210 +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, zoidberg -""" -from __future__ import with_statement - -from thread import start_new_thread -from pycurl import FORM_FILE, HTTPHEADER, RESPONSE_CODE -from time import sleep -from base64 import b64encode -import re - -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader -from module.plugins.Hook import Hook -from module.common.json_layer import json_loads - -class DeathByCaptchaException(Exception): -    DBC_ERRORS = {'not-logged-in': 'Access denied, check your credentials', -                  'invalid-credentials': 'Access denied, check your credentials', -                  'banned': 'Access denied, account is suspended', -                  'insufficient-funds': 'Insufficient account balance to decrypt CAPTCHA', -                  'invalid-captcha': 'CAPTCHA is not a valid image', -                  'service-overload': 'CAPTCHA was rejected due to service overload, try again later', -                  'invalid-request': 'Invalid request', -                  'timed-out': 'No CAPTCHA solution received in time' }  -     -    def __init__(self, err): -        self.err = err - -    def getCode(self): -        return self.err -         -    def getDesc(self): -        if self.err in self.DBC_ERRORS.keys(): -            return self.DBC_ERRORS[self.err] -        else: -            return self.err - -    def __str__(self): -        return "<DeathByCaptchaException %s>" % self.err - -    def __repr__(self): -        return "<DeathByCaptchaException %s>" % self.err - -class DeathByCaptcha(Hook): -    __name__ = "DeathByCaptcha" -    __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)] -    __author_name__ = ("RaNaN", "zoidberg") -    __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") - -    API_URL = "http://api.dbcapi.me/api/" - -    def setup(self): -        self.info = {} - -    def call_api(self, api="captcha", post=False, multipart=False): -        req = getRequest() -        req.c.setopt(HTTPHEADER, ["Accept: application/json",  -                                  "User-Agent: pyLoad %s" % self.core.version]) -         -        if post: -            if not isinstance(post, dict): -                post = {} -            post.update({"username": self.getConfig("username"), -                         "password": self.getConfig("passkey")})                           -         -        response = None -        try: -            json = req.load("%s%s" % (self.API_URL, api),  -                            post = post, -                            multipart=multipart) -            self.logDebug(json)             -            response = json_loads(json) -             -            if "error" in response: -                raise DeathByCaptchaException(response['error']) -            elif "status" not in response: -                raise DeathByCaptchaException(str(response)) -             -        except BadHeader, e: -            if 403 == e.code: -                raise DeathByCaptchaException('not-logged-in')             -            elif 413 == e.code: -                raise DeathByCaptchaException('invalid-captcha') -            elif 503 == e.code: -                raise DeathByCaptchaException('service-overload') -            elif e.code in (400, 405): -                raise DeathByCaptchaException('invalid-request') -            else: -                raise -                                                    -        finally: -            req.close() -             -        return response -         -    def getCredits(self): -        response = self.call_api("user", True) - -        if 'is_banned' in response and response['is_banned']: -            raise DeathByCaptchaException('banned') -        elif 'balance' in response and 'rate' in response: -            self.info.update(response) -        else: -            raise DeathByCaptchaException(response) -             -    def getStatus(self): -        response = self.call_api("status", False) - -        if 'is_service_overloaded' in response and response['is_service_overloaded']: -            raise DeathByCaptchaException('service-overload') - -    def submit(self, captcha, captchaType="file", match=None): -        #workaround multipart-post bug in HTTPRequest.py  -        if re.match("^[A-Za-z0-9]*$", self.getConfig("passkey")): -            multipart = True -            data = (FORM_FILE, captcha) -        else: -            multipart = False -            with open(captcha, 'rb') as f: -                data = f.read() -            data = "base64:" + b64encode(data)          -         -        response = self.call_api("captcha", {"captchafile": data}, multipart) -         -        if "captcha" not in response: -            raise DeathByCaptchaException(response) -        ticket = response['captcha'] -         -        for i in range(24): -            sleep(5) -            response = self.call_api("captcha/%d" % ticket, False)                -            if response['text'] and response['is_correct']: -                break -        else: -            raise DeathByCaptchaException('timed-out')             -                 -        result = response['text'] -        self.logDebug("result %s : %s" % (ticket,result)) - -        return ticket, result - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False -     -        if not task.isTextual(): -            return False - -        if not self.getConfig("username") or not self.getConfig("passkey"): -            return False - -        if self.core.isClientConnected() and not self.getConfig("force"): -            return False -         -        try: -            self.getStatus() -            self.getCredits()                                                          -        except DeathByCaptchaException, e: -            self.logError(e.getDesc()) -            return False -         -        balance, rate = self.info["balance"], self.info["rate"] -        self.logInfo("Account balance: US$%.3f (%d captchas left at %.2f cents each)" % (balance / 100, balance // rate, rate)) -             -        if balance > rate:             -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(180) -            start_new_thread(self.processCaptcha, (task,))         - -    def captchaInvalid(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            try: -                response = self.call_api("captcha/%d/report" % task.data["ticket"], True) -            except DeathByCaptchaException, e: -                self.logError(e.getDesc()) -            except Exception, e: -                self.logError(e) - -    def processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except DeathByCaptchaException, e: -            task.error = e.getCode() -            self.logError(e.getDesc()) -            return - -        task.data["ticket"] = ticket -        task.setResult(result)
\ No newline at end of file diff --git a/module/plugins/addons/DebridItaliaCom.py b/module/plugins/addons/DebridItaliaCom.py deleted file mode 100644 index 80cdc45f6..000000000 --- a/module/plugins/addons/DebridItaliaCom.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- 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.05" -    __type__ = "hook" -    __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__ = """Debriditalia.com hook plugin""" -    __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", -                "bitshare.com", "share-links.biz", "putlocker.com", "uploaded.to", -                "speedload.org", "rapidgator.net", "likeupload.net", "cyberlocker.ch", -                "depositfiles.com", "extabit.com", "filefactory.com", "sharefiles.co", -                "ryushare.com", "tusfiles.net", "nowvideo.co", "cloudzer.net", "letitbit.net"] diff --git a/module/plugins/addons/DeleteFinished.py b/module/plugins/addons/DeleteFinished.py deleted file mode 100644 index e0df69eef..000000000 --- a/module/plugins/addons/DeleteFinished.py +++ /dev/null @@ -1,86 +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: Walter Purcaro -""" - -from module.plugins.Hook import Hook -from time import time - - -class DeleteFinished(Hook): -    __name__ = "DeleteFinished" -    __version__ = "0.5" -    __description__ = "Automatically delete finished packages from queue" -    __config__ = [ -        ("activated", "bool", "Activated", "False"), -        ("interval", "int", "Delete every (hours)", "72") -    ] -    __author_name__ = ("Walter Purcaro") -    __author_mail__ = ("vuolter@gmail.com") - -    def wakeup(self, pypack): -        # self.logDebug("self.wakeup") -        self.removeEvent("packageFinished", self.wakeup) -        self.info["sleep"] = False - -    def periodical(self): -        # self.logDebug("self.periodical") -        if not self.info["sleep"]: -            self.core.api.deleteFinished() -            self.logDebug("called self.core.api.deleteFinished") -            self.info["sleep"] = True -            self.addEvent("packageFinished", self.wakeup) - -    def addEvent(self, event, handler): -        if event in self.manager.events: -            if handler not in self.manager.events[event]: -                self.manager.events[event].append(handler) -                # self.logDebug("self.addEvent: " + event + ": added handler") -            else: -                # self.logDebug("self.addEvent: " + event + ": NOT added handler") -                return False -        else: -            self.manager.events[event] = [handler] -            # self.logDebug("self.addEvent: " + event + ": added event and handler") -        return True - -    def removeEvent(self, event, handler): -        if event in self.manager.events and handler in self.manager.events[event]: -            self.manager.events[event].remove(handler) -            # self.logDebug("self.removeEvent: " + event + ": removed handler") -            return True -        else: -            # self.logDebug("self.removeEvent: " + event + ": NOT removed handler") -            return False - -    def configEvents(self, plugin=None, name=None, value=None): -        # self.logDebug("self.configEvents") -        interval = self.getConfig("interval") * 3600 -        if interval != self.interval: -            self.interval = interval - -    def unload(self): -        # self.logDebug("self.unload") -        self.removeEvent("pluginConfigChanged", self.configEvents) -        self.removeEvent("packageFinished", self.wakeup) - -    def coreReady(self): -        # self.logDebug("self.coreReady") -        self.info = {"sleep": True} -        self.addEvent("pluginConfigChanged", self.configEvents) -        self.configEvents() -        self.addEvent("packageFinished", self.wakeup) diff --git a/module/plugins/addons/DownloadScheduler.py b/module/plugins/addons/DownloadScheduler.py deleted file mode 100644 index 4049d71c5..000000000 --- a/module/plugins/addons/DownloadScheduler.py +++ /dev/null @@ -1,86 +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. -    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 - - -class DownloadScheduler(Hook): -    __name__ = "DownloadScheduler" -    __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")] -    __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 - -    def coreReady(self): -        self.updateSchedule() - -    def updateSchedule(self, schedule=None): -        if schedule is None: -            schedule = self.getConfig("timetable") - -        schedule = re.findall("(\d{1,2}):(\d{2})[\s]*(-?\d+)", -                              schedule.lower().replace("full", "-1").replace("none", "0")) -        if not schedule: -            self.logError("Invalid schedule") -            return - -        t0 = localtime() -        now = (t0.tm_hour, t0.tm_min, t0.tm_sec, "X") -        schedule = sorted([(int(x[0]), int(x[1]), 0, int(x[2])) for x in schedule] + [now]) - -        self.logDebug("Schedule", schedule) - -        for i, v in enumerate(schedule): -            if v[3] == "X": -                last, next = schedule[i - 1], schedule[(i + 1) % len(schedule)] -                self.logDebug("Now/Last/Next", now, last, next) - -                self.setDownloadSpeed(last[3]) - -                next_time = (((24 + next[0] - now[0]) * 60 + next[1] - now[1]) * 60 + next[2] - now[2]) % 86400 -                self.core.scheduler.removeJob(self.cb) -                self.cb = self.core.scheduler.addJob(next_time, self.updateSchedule, threaded=False) - -    def setDownloadSpeed(self, speed): -        if speed == 0: -            abort = self.getConfig("abort") -            self.logInfo("Stopping download server. (Running downloads will %sbe aborted.)" % ('' if abort else 'not ')) -            self.core.api.pauseServer() -            if abort: -                self.core.api.stopAllDownloads() -        else: -            self.core.api.unpauseServer() - -            if speed > 0: -                self.logInfo("Setting download speed to %d kB/s" % speed) -                self.core.api.setConfigValue("download", "limit_speed", 1) -                self.core.api.setConfigValue("download", "max_speed", speed) -            else: -                self.logInfo("Setting download speed to FULL") -                self.core.api.setConfigValue("download", "limit_speed", 0) -                self.core.api.setConfigValue("download", "max_speed", -1) diff --git a/module/plugins/addons/EasybytezCom.py b/module/plugins/addons/EasybytezCom.py deleted file mode 100644 index 6a4ded85b..000000000 --- a/module/plugins/addons/EasybytezCom.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster -import re - -class EasybytezCom(MultiHoster): -    __name__ = "EasybytezCom" -    __version__ = "0.03" -    __type__ = "hook" -    __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] -         -        try: -            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(',') -        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']
\ No newline at end of file diff --git a/module/plugins/addons/Ev0InFetcher.py b/module/plugins/addons/Ev0InFetcher.py deleted file mode 100644 index 608baf217..000000000 --- a/module/plugins/addons/Ev0InFetcher.py +++ /dev/null @@ -1,87 +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 -""" -from module.lib import feedparser -from time import mktime, time - -from module.plugins.Addon import Addon - -class Ev0InFetcher(Addon): -    __name__ = "Ev0InFetcher" -    __version__ = "0.2" -    __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), -                  ("shows", "str", "Shows to check for (comma separated)", ""), -                  ("quality", "xvid;x264;rmvb", "Video Format", "xvid"), -                  ("hoster", "str", "Hoster to use (comma separated)", "NetloadIn,RapidshareCom,MegauploadCom,HotfileCom")] -    __author_name__ = ("mkaay") -    __author_mail__ = ("mkaay@mkaay.de") - -    def setup(self): -        self.interval = self.getConfig("interval") * 60 - -    def filterLinks(self, links): -        results = self.core.pluginManager.parseUrls(links) -        sortedLinks = {} -         -        for url, hoster in results[0]: -            if hoster not in sortedLinks: -                sortedLinks[hoster] = [] -            sortedLinks[hoster].append(url) -         -        for h in self.getConfig("hoster").split(","): -            try: -                return sortedLinks[h.strip()] -            except: -                continue -        return [] -     -    def periodical(self): -        def normalizefiletitle(filename): -            filename = filename.replace('.', ' ') -            filename = filename.replace('_', ' ') -            filename = filename.lower() -            return filename -         -        shows = [s.strip() for s in self.getConfig("shows").split(",")] -         -        feed = feedparser.parse("http://feeds.feedburner.com/ev0in/%s?format=xml" % self.getConfig("quality")) - -        showStorage = {} -        for show in shows: -            showStorage[show] = int(self.getStorage("show_%s_lastfound" % show, 0)) -         -        found = False -        for item in feed['items']: -            for show, lastfound in showStorage.iteritems(): -                if show.lower() in normalizefiletitle(item['title']) and lastfound < int(mktime(item.date_parsed)): -                    links = self.filterLinks(item['description'].split("<br />")) -                    packagename = item['title'].encode("utf-8") -                    self.core.log.info("Ev0InFetcher: new episode '%s' (matched '%s')" % (packagename, show)) -                    self.core.api.addPackage(packagename, links, 1 if self.getConfig("queue") else 0) -                    self.setStorage("show_%s_lastfound" % show, int(mktime(item.date_parsed))) -                    found = True -        if not found: -            #self.core.log.debug("Ev0InFetcher: no new episodes found") -            pass - -        for show, lastfound in self.getStorage().iteritems(): -            if int(lastfound) > 0 and int(lastfound) + (3600*24*30) < int(time()): -                self.delStorage("show_%s_lastfound" % show) -                self.core.log.debug("Ev0InFetcher: cleaned '%s' record" % show) diff --git a/module/plugins/addons/ExpertDecoders.py b/module/plugins/addons/ExpertDecoders.py deleted file mode 100644 index 2e66e49ca..000000000 --- a/module/plugins/addons/ExpertDecoders.py +++ /dev/null @@ -1,112 +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, zoidberg -""" -from __future__ import with_statement - -from thread import start_new_thread -from pycurl import FORM_FILE, LOW_SPEED_TIME -from uuid import uuid4 -from base64 import b64encode - -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader - -from module.plugins.Hook import Hook - -class ExpertDecoders(Hook): -    __name__ = "ExpertDecoders" -    __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", ""),] -    __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 = {} - -    def getCredits(self):     -        response = getURL(self.API_URL, post = { "key": self.getConfig("passkey"), "action": "balance" }) -         -        if response.isdigit():                 -            self.logInfo(_("%s credits left") % response) -            self.info["credits"] = credits = int(response) -            return credits  -        else: -            self.logError(response) -            return 0 -         -    def processCaptcha(self, task):         -        task.data["ticket"] = ticket = uuid4() -        result = None -         -        with open(task.captchaFile, 'rb') as f: -            data = f.read()         -        data = b64encode(data)          -        #self.logDebug("%s: %s : %s" % (ticket, task.captchaFile, data)) - -        req = getRequest() -        #raise timeout threshold -        req.c.setopt(LOW_SPEED_TIME, 80) -         -        try: -            result = req.load(self.API_URL,  -                              post={ "action": "upload", -                                     "key": self.getConfig("passkey"), -                                     "file": data,  -                            		   	 "gen_task_id": ticket } -                              ) -        finally: -            req.close() - -        self.logDebug("result %s : %s" % (ticket, result)) -        task.setResult(result) - -    def newCaptchaTask(self, task): -        if not task.isTextual(): -            return False - -        if not self.getConfig("passkey"): -            return False - -        if self.core.isClientConnected() and not self.getConfig("force"): -            return False - -        if self.getCredits() > 0: -            task.handler.append(self) -            task.setWaiting(100) -            start_new_thread(self.processCaptcha, (task,)) - -        else: -            self.logInfo(_("Your ExpertDecoders Account has not enough credits")) - -    def captchaInvalid(self, task): -        if "ticket" in task.data: -             -            try: -                response = getURL(self.API_URL,  -                              post={ "action": "refund", -                                     "key": self.getConfig("passkey"), -                                     "gen_task_id": task.data["ticket"] } -                              ) -                self.logInfo("Request refund: %s" % response) - -            except BadHeader, e: -                self.logError("Could not send refund request.", str(e))
\ No newline at end of file diff --git a/module/plugins/addons/ExternalScripts.py b/module/plugins/addons/ExternalScripts.py deleted file mode 100644 index 8f5a5841e..000000000 --- a/module/plugins/addons/ExternalScripts.py +++ /dev/null @@ -1,118 +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: RaNaN -""" - -import subprocess -from os import access, X_OK, makedirs -from os.path import basename - -from module.plugins.Addon import Addon -from module.utils.fs import save_join, exists, join, listdir - -class ExternalScripts(Addon): -    __name__ = "ExternalScripts" -    __version__ = "0.22" -    __description__ = """Run external scripts""" -    __config__ = [("activated", "bool", "Activated", "True")] -    __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'] - -        for folder in folders: - -            self.scripts[folder] = [] - -            self.initPluginType(folder, join(pypath, 'scripts', folder)) -            self.initPluginType(folder, join('scripts', folder)) - -        for script_type, names in self.scripts.iteritems(): -            if names: -                self.logInfo((_("Installed scripts for %s: ") % script_type ) + ", ".join([basename(x) for x in names])) - - -    def initPluginType(self, folder, path): -        if not exists(path): -            try: -                makedirs(path) -            except : -                self.logDebug("Script folder %s not created" % folder) -                return - -        for f in listdir(path): -            if f.startswith("#") or f.startswith(".") or f.startswith("_") or f.endswith("~") or f.endswith(".swp"): -                continue - -            if not access(join(path,f), X_OK): -                self.logWarning(_("Script not executable:") + " %s/%s" % (folder, f)) - -            self.scripts[folder].append(join(path, f)) - -    def callScript(self, script, *args): -        try: -            cmd = [script] + [str(x) if not isinstance(x, basestring) else x for x in args] -            #output goes to pyload -            subprocess.Popen(cmd, bufsize=-1) -        except Exception, e: -            self.logError(_("Error in %(script)s: %(error)s") % { "script" :basename(script), "error": str(e)}) - -    def downloadPreparing(self, pyfile): -        for script in self.scripts['download_preparing']: -            self.callScript(script, pyfile.pluginname, pyfile.url, pyfile.id) - -    def downloadFinished(self, pyfile): -        for script in self.scripts['download_finished']: -            self.callScript(script, pyfile.pluginname, pyfile.url, pyfile.name, -                            save_join(self.core.config['general']['download_folder'], pyfile.package().folder, pyfile.name), -                            pyfile.id) - - -    def packageFinished(self, pypack): -        for script in self.scripts['package_finished']: -            folder = self.core.config['general']['download_folder'] -            folder = save_join(folder, pypack.folder) - -            self.callScript(script, pypack.name, folder, pypack.password, pypack.id) - -    def beforeReconnecting(self, ip): -        for script in self.scripts['before_reconnect']: -            self.callScript(script, ip) - -    def afterReconnecting(self, ip): -        for script in self.scripts['after_reconnect']: -            self.callScript(script, ip) - -    def unrarFinished(self, folder, fname): -        for script in self.scripts["unrar_finished"]: -            self.callScript(script, folder, fname) - -    def allDownloadsFinished(self): -        for script in self.scripts["all_dls_finished"]: -            self.callScript(script) - -    def allDownloadsProcessed(self): -        for script in self.scripts["all_dls_processed"]: -            self.callScript(script) - diff --git a/module/plugins/addons/ExtractArchive.py b/module/plugins/addons/ExtractArchive.py deleted file mode 100644 index 369b20ba9..000000000 --- a/module/plugins/addons/ExtractArchive.py +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import sys -import os -from os.path import basename, isfile, isdir, join -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 -if sys.version_info < (2, 7) and os.name != "nt": -    from subprocess import Popen -    import errno - -    def _eintr_retry_call(func, *args): -        while True: -            try: -                return func(*args) -            except OSError, e: -                if e.errno == errno.EINTR: -                    continue -                raise - -    # unsued timeout option for older python version -    def wait(self, timeout=0): -        """Wait for child process to terminate.  Returns returncode -        attribute.""" -        if self.returncode is None: -            try: -                pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) -            except OSError, e: -                if e.errno != errno.ECHILD: -                    raise -                    # This happens if SIGCLD is set to be ignored or waiting -                # for child processes has otherwise been disabled for our -                # process.  This child is dead, we can't get the status. -                sts = 0 -            self._handle_exitstatus(sts) -        return self.returncode - -    Popen.wait = wait - -if os.name != "nt": -    from os import chown -    from pwd import getpwnam -    from grp import getgrnam - -from module.utils.fs import save_join, fs_encode, exists, remove, chmod, makedirs -from module.plugins.Addon import Addon, threaded, Expose -from module.plugins.internal.AbstractExtractor import ArchiveError, CRCError, WrongPassword - -class ExtractArchive(Addon): -    """ -    Provides: unrarFinished (folder, filename) -    """ -    __name__ = "ExtractArchive" -    __version__ = "0.12" -    __description__ = "Extract different kind of archives" -    __config__ = [("activated", "bool", "Activated", True), -        ("fullpath", "bool", "Extract full path", True), -        ("overwrite", "bool", "Overwrite files", True), -        ("passwordfile", "file", "password file", "unrar_passwords.txt"), -        ("deletearchive", "bool", "Delete archives when done", False), -        ("subfolder", "bool", "Create subfolder for each package", False), -        ("destination", "folder", "Extract files to", ""), -        ("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") -    __author_mail__ = ("admin<at>pyload.org") - -    event_list = ["allDownloadsProcessed"] - -    def setup(self): -        self.plugins = [] -        self.passwords = [] -        names = [] - -        for p in ("UnRar", "UnZip"): -            try: -                module = self.core.pluginManager.loadModule("internal", p) -                klass = getattr(module, p) -                if klass.checkDeps(): -                    names.append(p) -                    self.plugins.append(klass) - -            except OSError, e: -                if e.errno == 2: -                    self.logInfo(_("No %s installed") % p) -                else: -                    self.logWarning(_("Could not activate %s") % p, str(e)) -                    if self.core.debug: -                        print_exc() - -            except Exception, e: -                self.logWarning(_("Could not activate %s") % p, str(e)) -                if self.core.debug: -                    print_exc() - -        if names: -            self.logInfo(_("Activated") + " " + " ".join(names)) -        else: -            self.logInfo(_("No Extract plugins activated")) - -        # queue with package ids -        self.queue = [] - -    @Expose -    def extractPackage(self, id): -        """ Extract package with given id""" -        self.manager.startThread(self.extract, [id]) - -    def packageFinished(self, pypack): -        if self.getConfig("queue"): -            self.logInfo(_("Package %s queued for later extracting") % pypack.name) -            self.queue.append(pypack.id) -        else: -            self.manager.startThread(self.extract, [pypack.id]) - - -    @threaded -    def allDownloadsProcessed(self, thread): -        local = copy(self.queue) -        del self.queue[:] -        self.extract(local, thread) - - -    def extract(self, ids, thread=None): -        # reload from txt file -        self.reloadPasswords() - -        # dl folder -        dl = self.config['general']['download_folder'] - -        extracted = [] - -        #iterate packages -> plugins -> targets -        for pid in ids: -            p = self.core.files.getPackage(pid) -            self.logInfo(_("Check package %s") % p.name) -            if not p: continue - -            # determine output folder -            out = save_join(dl, p.folder, "") -            # force trailing slash - -            if self.getConfig("destination") and self.getConfig("destination").lower() != "none": - -                out = save_join(dl, p.folder, self.getConfig("destination"), "") -                #relative to package folder if destination is relative, otherwise absolute path overwrites them - -                if self.getConf("subfolder"): -                    out = join(out, fs_encode(p.folder)) - -                if not exists(out): -                    makedirs(out) - -            files_ids = [(save_join(dl, p.folder, x["name"]), x["id"]) for x in p.getChildren().itervalues()] -            matched = False - -            # check as long there are unseen files -            while files_ids: -                new_files_ids = [] - -                for plugin in self.plugins: -                    targets = plugin.getTargets(files_ids) -                    if targets: -                        self.logDebug("Targets for %s: %s" % (plugin.__name__, targets)) -                        matched = True -                    for target, fid in targets: -                        if target in extracted: -                            self.logDebug(basename(target), "skipped") -                            continue -                        extracted.append(target) #prevent extracting same file twice - -                        klass = plugin(self, target, out, self.getConfig("fullpath"), self.getConfig("overwrite"), -                            self.getConfig("renice")) -                        klass.init() - -                        self.logInfo(basename(target), _("Extract to %s") % out) -                        new_files = self.startExtracting(klass, fid, p.password.strip().splitlines(), thread) -                        self.logDebug("Extracted: %s" % new_files) -                        self.setPermissions(new_files) - -                        for file in new_files: -                            if not exists(file): -                                self.logDebug("new file %s does not exists" % file) -                                continue -                            if self.getConfig("recursive") and isfile(file): -                                new_files_ids.append((file, fid)) #append as new target - -                files_ids = new_files_ids # also check extracted files - -            if not matched: self.logInfo(_("No files found to extract")) - -    def startExtracting(self, plugin, fid, passwords, thread): -        pyfile = self.core.files.getFile(fid) -        if not pyfile: return [] - -        pyfile.setCustomStatus(_("extracting")) -        thread.addActive(pyfile) #keep this file until everything is done - -        try: -            progress = lambda x: pyfile.setProgress(x) -            success = False - -            if not plugin.checkArchive(): -                plugin.extract(progress) -                success = True -            else: -                self.logInfo(basename(plugin.file), _("Password protected")) -                self.logDebug("Passwords: %s" % str(passwords)) - -                pwlist = copy(self.getPasswords()) -                #remove already supplied pws from list (only local) -                for pw in passwords: -                    if pw in pwlist: pwlist.remove(pw) - -                for pw in passwords + pwlist: -                    try: -                        self.logDebug("Try password: %s" % pw) -                        if plugin.checkPassword(pw): -                            plugin.extract(progress, pw) -                            self.addPassword(pw) -                            success = True -                            break -                    except WrongPassword: -                        self.logDebug("Password was wrong") - -            if not success: -                self.logError(basename(plugin.file), _("Wrong password")) -                return [] - -            if self.core.debug: -                self.logDebug("Would delete: %s" % ", ".join(plugin.getDeleteFiles())) - -            if self.getConfig("deletearchive"): -                files = plugin.getDeleteFiles() -                self.logInfo(_("Deleting %s files") % len(files)) -                for f in files: -                    if exists(f): remove(f) -                    else: self.logDebug("%s does not exists" % f) - -            self.logInfo(basename(plugin.file), _("Extracting finished")) -            self.manager.dispatchEvent("unrarFinished", plugin.out, plugin.file) - -            return plugin.getExtractedFiles() - - -        except ArchiveError, e: -            self.logError(basename(plugin.file), _("Archive Error"), str(e)) -        except CRCError: -            self.logError(basename(plugin.file), _("CRC Mismatch")) -        except Exception, e: -            if self.core.debug: -                print_exc() -            self.logError(basename(plugin.file), _("Unknown Error"), str(e)) - -        return [] - -    @Expose -    def getPasswords(self): -        """ List of saved passwords """ -        return self.passwords - - -    def reloadPasswords(self): -        pwfile = self.getConfig("passwordfile") -        if not exists(pwfile): -            open(pwfile, "wb").close() - -        passwords = [] -        f = open(pwfile, "rb") -        for pw in f.read().splitlines(): -            passwords.append(pw) -        f.close() - -        self.passwords = passwords - - -    @Expose -    def addPassword(self, pw): -        """  Adds a password to saved list""" -        pwfile = self.getConfig("passwordfile") - -        if pw in self.passwords: self.passwords.remove(pw) -        self.passwords.insert(0, pw) - -        f = open(pwfile, "wb") -        for pw in self.passwords: -            f.write(pw + "\n") -        f.close() - -    def setPermissions(self, files): -        for f in files: -            if not exists(f): continue -            try: -                if self.core.config["permission"]["change_file"]: -                    if isfile(f): -                        chmod(f, int(self.core.config["permission"]["file"], 8)) -                    elif isdir(f): -                        chmod(f, int(self.core.config["permission"]["folder"], 8)) - -                if self.core.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.log.warning(_("Setting User and Group failed"), e) diff --git a/module/plugins/addons/HotFolder.py b/module/plugins/addons/HotFolder.py deleted file mode 100644 index d05026448..000000000 --- a/module/plugins/addons/HotFolder.py +++ /dev/null @@ -1,85 +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: 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 module.plugins.Addon import Addon - -class HotFolder(Addon): -    __name__ = "HotFolder" -    __version__ = "0.1" -    __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")] -    __threaded__ = [] -    __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")) -           -        if self.getConfig("watch_file"): - -            if not exists(self.getConfig("file")): -                f = open(self.getConfig("file"), "wb") -                f.close() -             -             -            f = open(self.getConfig("file"), "rb") -            content = f.read().strip() -            f.close() -            f = open(self.getConfig("file"), "wb") -            f.close() -            if content: -                name = "%s_%s.txt" % (self.getConfig("file"), time.strftime("%H-%M-%S_%d%b%Y") ) - -                f = open(join(self.getConfig("folder"), "finished", name), "wb") -                f.write(content) -                f.close() - -                self.core.api.addPackage(f.name, [f.name], 1) -               -        for f in listdir(self.getConfig("folder")): -            path = join(self.getConfig("folder"), f) -             -            if not isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."): -                continue -             -            newpath = join(self.getConfig("folder"), "finished", f if self.getConfig("keep") else "tmp_"+f) -            move(path, newpath) -             -            self.log.info(_("Added %s from HotFolder") % f) -            self.core.api.addPackage(f, [newpath], 1) -             -        
\ No newline at end of file diff --git a/module/plugins/addons/IRCInterface.py b/module/plugins/addons/IRCInterface.py deleted file mode 100644 index c261fc6f3..000000000 --- a/module/plugins/addons/IRCInterface.py +++ /dev/null @@ -1,431 +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: RaNaN -    @author: jeix -    @interface-version: 0.2 -""" - -from select import select -import socket -from threading import Thread -import time -from time import sleep -from traceback import print_exc -import re - -from module.plugins.Addon import Addon -from module.network.RequestFactory import getURL -from module.utils import formatSize -from module.Api import PackageDoesNotExists, FileDoesNotExists - -from pycurl import FORM_FILE - -class IRCInterface(Thread, Addon): -    __name__ = "IRCInterface" -    __version__ = "0.1" -    __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"), -        ("ident", "str", "Clients ident", "pyload-irc"), -        ("realname", "str", "Realname", "pyload-irc"), -        ("nick", "str", "Nickname the Client will take", "pyLoad-IRC"), -        ("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here!"), -        ("info_file", "bool", "Inform about every file finished", "False"), -        ("info_pack", "bool", "Inform about every package finished", "True"), -        ("captcha", "bool", "Send captcha requests", "True")] -    __author_name__ = ("Jeix") -    __author_mail__ = ("Jeix@hasnomail.com") -     -    def __init__(self, core, manager): -        Thread.__init__(self) -        Addon.__init__(self, core, manager) -        self.setDaemon(True) -        #   self.sm = core.server_methods -        self.api = core.api #todo, only use api -         -    def coreReady(self): -        self.new_package = {} -         -        self.abort = False -         -        self.links_added = 0 -        self.more = [] - -        self.start() -         -         -    def packageFinished(self, pypack): -        try: -            if self.getConfig("info_pack"): -                self.response(_("Package finished: %s") % pypack.name) -        except: -            pass -         -    def downloadFinished(self, pyfile): -        try: -            if self.getConfig("info_file"): -                self.response(_("Download finished: %(name)s @ %(plugin)s ") % { "name" : pyfile.name, "plugin": pyfile.pluginname} ) -        except: -            pass - -    def newCaptchaTask(self, task): -        if self.getConfig("captcha") and task.isTextual(): -            task.handler.append(self) -            task.setWaiting(60) - -            page = getURL("http://www.freeimagehosting.net/upload.php", post={"attached" : (FORM_FILE, task.captchaFile)}, multipart=True) - -            url = re.search(r"\[img\]([^\[]+)\[/img\]\[/url\]", page).group(1) -            self.response(_("New Captcha Request: %s") % url) -            self.response(_("Answer with 'c %s text on the captcha'") % task.id) - -    def run(self): -        # connect to IRC etc. -        self.sock = socket.socket() -        host = self.getConfig("host") -        self.sock.connect((host, self.getConfig("port"))) -        nick = self.getConfig("nick") -        self.sock.send("NICK %s\r\n" % nick) -        self.sock.send("USER %s %s bla :%s\r\n" % (nick, host, nick)) -        for t in self.getConfig("owner").split(): -            if t.strip().startswith("#"): -                self.sock.send("JOIN %s\r\n" % t.strip()) -        self.log.info("pyLoad IRC: Connected to %s!" % host) -        self.log.info("pyLoad IRC: Switching to listening mode!") -        try:         -            self.main_loop() -             -        except IRCError, ex: -            self.sock.send("QUIT :byebye\r\n") -            print_exc() -            self.sock.close() - -             -    def main_loop(self): -        readbuffer = "" -        while True: -            sleep(1) -            fdset = select([self.sock], [], [], 0) -            if self.sock not in fdset[0]: -                continue -             -            if self.abort: -                raise IRCError("quit") -             -            readbuffer += self.sock.recv(1024) -            temp = readbuffer.split("\n") -            readbuffer = temp.pop() - -            for line in temp: -                line  = line.rstrip() -                first = line.split() - -                if first[0] == "PING": -                    self.sock.send("PONG %s\r\n" % first[1]) -                     -                if first[0] == "ERROR": -                    raise IRCError(line) -                     -                msg = line.split(None, 3) -                if len(msg) < 4: -                    continue -                     -                msg = { -                    "origin":msg[0][1:], -                    "action":msg[1], -                    "target":msg[2], -                    "text":msg[3][1:] -                } -                 -                self.handle_events(msg) -         -         -    def handle_events(self, msg): -        if not msg["origin"].split("!", 1)[0] in self.getConfig("owner").split(): -            return -             -        if msg["target"].split("!", 1)[0] != self.getConfig("nick"): -            return -             -        if msg["action"] != "PRIVMSG": -            return -             -        # HANDLE CTCP ANTI FLOOD/BOT PROTECTION -        if msg["text"] == "\x01VERSION\x01": -            self.log.debug("Sending CTCP VERSION.") -            self.sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface")) -            return -        elif msg["text"] == "\x01TIME\x01": -            self.log.debug("Sending CTCP TIME.") -            self.sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time())) -            return -        elif msg["text"] == "\x01LAG\x01": -            self.log.debug("Received CTCP LAG.") # don't know how to answer -            return -          -        trigger = "pass" -        args = None - -        try: -            temp = msg["text"].split() -            trigger = temp[0] -            if len(temp) > 1: -                args = temp[1:] -        except: -            pass - -        handler = getattr(self, "event_%s" % trigger, self.event_pass) -        try: -            res = handler(args) -            for line in res: -                self.response(line, msg["origin"]) -        except Exception, e: -            self.log.error("pyLoad IRC: "+ repr(e)) -         -         -    def response(self, msg, origin=""): -        if origin == "": -            for t in self.getConfig("owner").split(): -                self.sock.send("PRIVMSG %s :%s\r\n" % (t.strip(), msg)) -        else: -            self.sock.send("PRIVMSG %s :%s\r\n" % (origin.split("!", 1)[0], msg)) -         -         -#### Events -    def event_pass(self, args): -        return [] -         -    def event_status(self, args): -        downloads = self.api.statusDownloads() -        if not downloads: -            return ["INFO: There are no active downloads currently."] -             -        temp_progress = "" -        lines = ["ID - Name - Status - Speed - ETA - Progress"] -        for data in downloads: - -            if data.status == 5: -                temp_progress = data.format_wait -            else: -                temp_progress = "%d%% (%s)" % (data.percent, data.format_size) - -            lines.append("#%d - %s - %s - %s - %s - %s" % -                     ( -                     data.fid, -                     data.name, -                     data.statusmsg, -                     "%s/s" % formatSize(data.speed), -                     "%s" % data.format_eta, -                     temp_progress -                     ) -                     ) -        return lines -             -    def event_queue(self, args): -        ps = self.api.getQueueData() -         -        if not ps: -            return ["INFO: There are no packages in queue."] -         -        lines = [] -        for pack in ps: -            lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.links) )) -                 -        return lines -         -    def event_collector(self, args): -        ps = self.api.getCollectorData() -        if not ps: -            return ["INFO: No packages in collector!"] -         -        lines = [] -        for pack in ps: -            lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.links) )) -                 -        return lines -             -    def event_info(self, args): -        if not args: -            return ['ERROR: Use info like this: info <id>'] -             -        info = None -        try: -            info = self.api.getFileData(int(args[0])) -         -        except FileDoesNotExists: -            return ["ERROR: Link doesn't exists."] - -        return ['LINK #%s: %s (%s) [%s][%s]' % (info.fid, info.name, info.format_size, info.statusmsg, -                                                info.plugin)] -         -    def event_packinfo(self, args): -        if not args: -            return ['ERROR: Use packinfo like this: packinfo <id>'] -             -        lines = [] -        pack = None -        try: -            pack = self.api.getPackageData(int(args[0])) -         -        except PackageDoesNotExists: -            return ["ERROR: Package doesn't exists."] -         -        id = args[0] - -        self.more = [] -         -        lines.append('PACKAGE #%s: "%s" with %d links' % (id, pack.name, len(pack.links)) ) -        for pyfile in pack.links: -            self.more.append('LINK #%s: %s (%s) [%s][%s]' % (pyfile.fid, pyfile.name, pyfile.format_size, -                                                             pyfile.statusmsg, pyfile.plugin)) - -        if len(self.more) < 6: -            lines.extend(self.more) -            self.more = [] -        else: -            lines.extend(self.more[:6]) -            self.more = self.more[6:] -            lines.append("%d more links do display." % len(self.more)) -             -             -        return lines -     -    def event_more(self, args): -        if not self.more: -            return ["No more information to display."] -         -        lines = self.more[:6] -        self.more = self.more[6:] -        lines.append("%d more links do display." % len(self.more)) -         -        return lines -     -    def event_start(self, args): -         -        self.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>!'] -             - -             -        pack = args[0].strip() -        links = [x.strip() for x in args[1:]] -         -        count_added = 0 -        count_failed = 0 -        try: -            id = int(pack)  -            pack = self.api.getPackageData(id) -            if not pack: -                return ["ERROR: Package doesn't exists."] -             -            #TODO add links -             -            return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack["name"], id)] -             -        except: -            # create new package -            id = self.api.addPackage(pack, links, 1) -            return ["INFO: Created new Package %s [#%d] with %d links." % (pack, id, len(links))] -              -         -    def event_del(self, args): -        if len(args) < 2: -            return ["ERROR: Use del command like this: del -p|-l <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] -             -        if args[0] == "-p": -            ret = self.api.deletePackages(map(int, args[1:])) -            return ["INFO: Deleted %d packages!" % len(args[1:])] -             -        elif args[0] == "-l": -            ret = self.api.delLinks(map(int, args[1:])) -            return ["INFO: Deleted %d links!" % len(args[1:])] - -        else: -            return ["ERROR: Use del command like this: del <-p|-l> <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] -             -    def event_push(self, args): -        if not args: -            return ["ERROR: Push package to queue like this: push <package id>"] - -        id = int(args[0]) -        try: -            info = self.api.getPackageInfo(id) -        except PackageDoesNotExists: -            return ["ERROR: Package #%d does not exist." % id] - -        self.api.pushToQueue(id) -        return ["INFO: Pushed package #%d to queue." % id] - -    def event_pull(self, args): -        if not args: -            return ["ERROR: Pull package from queue like this: pull <package id>."] - -        id = int(args[0]) -        if not self.api.getPackageData(id): -            return ["ERROR: Package #%d does not exist." % id] - -        self.api.pullFromQueue(id) -        return ["INFO: Pulled package #%d from queue to collector." % id] - -    def event_c(self, args): -        """ captcha answer """ -        if not args: -            return ["ERROR: Captcha ID missing."] - -        task = self.core.captchaManager.getTaskByID(args[0]) -        if not task: -            return ["ERROR: Captcha Task with ID %s does not exists." % args[0]] -         -        task.setResult(" ".join(args[1:])) -        return ["INFO: Result %s saved." % " ".join(args[1:])] - - -    def event_help(self, args): -        lines = ["The following commands are available:", -                 "add <package|packid> <links> [...] Adds link to package. (creates new package if it does not exist)", -                 "queue                       Shows all packages in the queue", -                 "collector                   Shows all packages in collector", -                 "del -p|-l <id> [...]        Deletes all packages|links with the ids specified", -                 "info <id>                   Shows info of the link with id <id>", -                 "packinfo <id>               Shows info of the package with id <id>", -                 "more                        Shows more info when the result was truncated", -                 "start                       Starts all downloads", -                 "stop                        Stops the download (but not abort active downloads)", -                 "push <id>                   Push package to queue", -                 "pull <id>                   Pull package from queue", -                 "status                      Show general download status", -                 "help                        Shows this help message"] -        return lines -         -         -class IRCError(Exception): -    def __init__(self, value): -        self.value = value -    def __str__(self): -        return repr(self.value) diff --git a/module/plugins/addons/ImageTyperz.py b/module/plugins/addons/ImageTyperz.py deleted file mode 100644 index 59b6334a7..000000000 --- a/module/plugins/addons/ImageTyperz.py +++ /dev/null @@ -1,160 +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, zoidberg -""" -from __future__ import with_statement - -from thread import start_new_thread -from pycurl import FORM_FILE, LOW_SPEED_TIME - -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader - -from module.plugins.Hook import Hook -import re -from base64 import b64encode - -class ImageTyperzException(Exception): -    def __init__(self, err): -        self.err = err - -    def getCode(self): -        return self.err - -    def __str__(self): -        return "<ImageTyperzException %s>" % self.err - -    def __repr__(self): -        return "<ImageTyperzException %s>" % self.err - -class ImageTyperz(Hook): -    __name__ = "ImageTyperz" -    __version__ = "0.03" -    __description__ = """send captchas to ImageTyperz.com""" -    __config__ = [("activated", "bool", "Activated", True), -                  ("username", "str", "Username", ""), -                  ("passkey", "password", "Password", ""), -                  ("force", "bool", "Force IT even if client is connected", False)] -    __author_name__ = ("RaNaN", "zoidberg") -    __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") - -    SUBMIT_URL = "http://captchatypers.com/Forms/UploadFileAndGetTextNEW.ashx" -    RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx" -    GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx" - -    def setup(self): -        self.info = {} - -    def getCredits(self): -        response = getURL(self.GETCREDITS_URL, -                      post = {"action": "REQUESTBALANCE", -                              "username": self.getConfig("username"), -                              "password": self.getConfig("passkey")} -                      ) -                                                                          -        if response.startswith('ERROR'): -            raise ImageTyperzException(response) -             -        try: -            balance = float(response) -        except: -            raise ImageTyperzException("invalid response") -             -        self.logInfo("Account balance: $%s left" % response) -        return balance  - -    def submit(self, captcha, captchaType="file", match=None): -        req = getRequest() -        #raise timeout threshold -        req.c.setopt(LOW_SPEED_TIME, 80) -         -        try: -            #workaround multipart-post bug in HTTPRequest.py  -            if re.match("^[A-Za-z0-9]*$", self.getConfig("passkey")): -                multipart = True -                data = (FORM_FILE, captcha) -            else: -                multipart = False -                with open(captcha, 'rb') as f: -                    data = f.read() -                data = b64encode(data) -                 -            response = req.load(self.SUBMIT_URL, -                                post={ "action": "UPLOADCAPTCHA", -                                       "username": self.getConfig("username"), -                                       "password": self.getConfig("passkey"), -                                       "file": data}, -                                multipart = multipart) -        finally: -            req.close() - -        if response.startswith("ERROR"): -            raise ImageTyperzException(response) -        else: -            data = response.split('|') -            if len(data) == 2: -                ticket, result = data -            else: -                raise ImageTyperzException("Unknown response %s" % response)       -         -        return ticket, result - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False -         -        if not task.isTextual(): -            return False - -        if not self.getConfig("username") or not self.getConfig("passkey"): -            return False - -        if self.core.isClientConnected() and not self.getConfig("force"): -            return False - -        if self.getCredits() > 0: -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(100) -            start_new_thread(self.processCaptcha, (task,)) - -        else: -            self.logInfo("Your %s account has not enough credits" % self.__name__) - -    def captchaInvalid(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            response = getURL(self.RESPOND_URL, -                              post={"action": "SETBADIMAGE", -                                    "username": self.getConfig("username"), -                                    "password": self.getConfig("passkey"), -                                    "imageid": task.data["ticket"]} -                              ) -             -            if response == "SUCCESS": -                self.logInfo("Bad captcha solution received, requested refund") -            else: -                self.logError("Bad captcha solution received, refund request failed", response)  - -    def processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except ImageTyperzException, e: -            task.error = e.getCode() -            return - -        task.data["ticket"] = ticket -        task.setResult(result)
\ No newline at end of file diff --git a/module/plugins/addons/LinkdecrypterCom.py b/module/plugins/addons/LinkdecrypterCom.py deleted file mode 100644 index d3d6bce68..000000000 --- a/module/plugins/addons/LinkdecrypterCom.py +++ /dev/null @@ -1,59 +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: zoidberg -""" - -import re - -from module.plugins.Hook import Hook -from module.network.RequestFactory import getURL -from module.utils import remove_chars - -class LinkdecrypterCom(Hook): -    __name__ = "LinkdecrypterCom" -    __version__ = "0.17" -    __description__ = """linkdecrypter.com - regexp loader""" -    __config__ = [ ("activated", "bool", "Activated" , "True") ] -    __author_name__ = ("zoidberg") - -    def coreReady(self): -        page = getURL("http://linkdecrypter.com/") -        m = re.search(r'<b>Supported\(\d+\)</b>: <i>([^+<]*)', page) -        if not m: -            self.logError(_("Crypter list not found")) -            return - -        builtin = [ name.lower() for name in self.core.pluginManager.crypterPlugins.keys() ] -        builtin.extend([ "downloadserienjunkiesorg" ]) - -        crypter_pattern = re.compile("(\w[\w.-]+)") -        online = [] -        for crypter in m.group(1).split(', '): -            m = re.match(crypter_pattern, crypter) -            if m and remove_chars(m.group(1), "-.") not in builtin: -                online.append(m.group(1).replace(".", "\\.")) - -        if not online: -            self.logError(_("Crypter list is empty")) -            return -              -        regexp = r"https?://([^.]+\.)*?(%s)/.*" % "|".join(online) - -        dict = self.core.pluginManager.crypterPlugins[self.__name__] -        dict["pattern"] = regexp -        dict["re"] = re.compile(regexp) -         -        self.logDebug("REGEXP: " + regexp) diff --git a/module/plugins/addons/MergeFiles.py b/module/plugins/addons/MergeFiles.py deleted file mode 100644 index 48f997681..000000000 --- a/module/plugins/addons/MergeFiles.py +++ /dev/null @@ -1,94 +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: and9000 -""" - -import os -import re -import sys -import traceback - -from os.path import join -from module.utils import save_join, fs_encode -from module.plugins.Addon import Addon - -BUFFER_SIZE = 4096 - -class MergeFiles(Addon): -    __name__ = "MergeFiles" -    __version__ = "0.1" -    __description__ = "Merges parts splitted with hjsplit" -    __config__ = [ -        ("activated" , "bool" , "Activated"  , "False"), -        ] -    __threaded__ = ["packageFinished"] -    __author_name__ = ("and9000") -    __author_mail__ = ("me@has-no-mail.com") - -    def setup(self): -        # nothing to do -        pass -         -    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 -                 -        download_folder = self.core.config['general']['download_folder'] -                 -        if self.core.config['general']['folder_per_package']: -            download_folder = save_join(download_folder, pack.folder) - -        for name, file_list in files.iteritems(): -            self.core.log.info("Starting merging of %s" % name) -            final_file = open(join(download_folder, fs_encode(name)), "wb") - -            for splitted_file in file_list: -                self.core.log.debug("Merging part %s" % splitted_file) -                pyfile = self.core.files.getFile(fid_dict[splitted_file]) -                pyfile.setStatus("processing") -                try: -                    s_file = open(os.path.join(download_folder, splitted_file), "rb") -                    size_written = 0 -                    s_file_size = int(os.path.getsize(os.path.join(download_folder, splitted_file))) -                    while True: -                        f_buffer = s_file.read(BUFFER_SIZE) -                        if f_buffer: -                            final_file.write(f_buffer) -                            size_written += BUFFER_SIZE -                            pyfile.setProgress((size_written*100)/s_file_size) -                        else: -                            break -                    s_file.close() -                    self.core.log.debug("Finished merging part %s" % splitted_file) -                except Exception, e: -                    print traceback.print_exc() -                finally: -                    pyfile.setProgress(100) -                    pyfile.setStatus("finished") -                    pyfile.release() -                     -            final_file.close() -            self.core.log.info("Finished merging of %s" % name) -                 - diff --git a/module/plugins/addons/MultiDebridCom.py b/module/plugins/addons/MultiDebridCom.py deleted file mode 100644 index c95138648..000000000 --- a/module/plugins/addons/MultiDebridCom.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- 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 - - -class MultiDebridCom(MultiHoster): -    __name__ = "MultiDebridCom" -    __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)", ""), -                  ("unloadFailing", "bool", "Revert to standard download if download fails", "False"), -                  ("interval", "int", "Reload interval in hours (0 to disable)", "24")] - -    __description__ = """Multi-debrid.com hook plugin""" -    __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) -        json_data = json_loads(json_data) - -        return json_data['hosts'] diff --git a/module/plugins/addons/MultiHome.py b/module/plugins/addons/MultiHome.py deleted file mode 100644 index af3f55416..000000000 --- a/module/plugins/addons/MultiHome.py +++ /dev/null @@ -1,82 +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 -""" - -from module.plugins.Addon import Addon -from time import time - -class MultiHome(Addon): -    __name__ = "MultiHome" -    __version__ = "0.1" -    __description__ = """ip address changer""" -    __config__ = [ ("activated", "bool", "Activated" , "False"), -                   ("interfaces", "str", "Interfaces" , "None") ] -    __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.setConfig("interfaces", self.toConfig()) -     -    def toConfig(self): -        return ";".join([i.adress for i in self.interfaces]) -     -    def parseInterfaces(self, interfaces): -        for interface in interfaces: -            if not interface or str(interface).lower() == "none": -                continue -            self.interfaces.append(Interface(interface)) -     -    def coreReady(self): -        requestFactory = self.core.requestFactory -        oldGetRequest = requestFactory.getRequest -        def getRequest(pluginName, account=None): -            iface = self.bestInterface(pluginName, account) -            if iface: -                iface.useFor(pluginName, account) -                requestFactory.iface = lambda: iface.adress -                self.log.debug("Multihome: using address: "+iface.adress) -            return oldGetRequest(pluginName, account) -        requestFactory.getRequest = getRequest -     -    def bestInterface(self, pluginName, account): -        best = None -        for interface in self.interfaces: -            if not best or interface.lastPluginAccess(pluginName, account) < best.lastPluginAccess(pluginName, account): -                best = interface -        return best - -class Interface(object): -    def __init__(self, adress): -        self.adress = adress -        self.history = {} -     -    def lastPluginAccess(self, pluginName, account): -        if (pluginName, account) in self.history: -            return self.history[(pluginName, account)] -        return 0 -     -    def useFor(self, pluginName, account): -        self.history[(pluginName, account)] = time() -     -    def __repr__(self): -        return "<Interface - %s>" % self.adress diff --git a/module/plugins/addons/MultiHoster.py b/module/plugins/addons/MultiHoster.py deleted file mode 100644 index 825085df8..000000000 --- a/module/plugins/addons/MultiHoster.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import re -from types import MethodType - -from module.plugins.MultiHoster import MultiHoster as MultiHosterAccount, normalize -from module.plugins.Addon import Addon, AddEventListener -from module.plugins.PluginManager import PluginTuple - -class MultiHoster(Addon): -    __version__ = "0.1" -    __internal__ = True -    __description__ = "Gives ability to use MultiHoster services. You need to add your account first." -    __config__ = [] -    __author_mail__ = ("pyLoad Team",) -    __author_mail__ = ("support@pyload.org",) - -    #TODO: multiple accounts - multihoster / config options - -    def init(self): - -        # overwritten plugins -        self.plugins = {} - -    def addHoster(self, account): - -        self.logDebug("New MultiHoster %s" % account.__name__) - -        pluginMap = {} -        for name in self.core.pluginManager.getPlugins("hoster").keys(): -            pluginMap[name.lower()] = name - -        supported = [] -        new_supported = [] - -        for hoster in account.getHosterList(): -            name = normalize(hoster) - -            if name in pluginMap: -                supported.append(pluginMap[name]) -            else: -                new_supported.append(hoster) - -        if not supported and not new_supported: -            account.logError(_("No Hoster loaded")) -            return - -        klass = self.core.pluginManager.getPluginClass(account.__name__) - -        # inject plugin plugin -        account.logDebug("Overwritten Hosters: %s" % ", ".join(sorted(supported))) -        for hoster in supported: -            self.plugins[hoster] = klass - -        account.logDebug("New Hosters: %s" % ", ".join(sorted(new_supported))) - -        # create new regexp -        regexp = r".*(%s).*" % "|".join([klass.__pattern__] + [x.replace(".", "\\.") for x in new_supported]) - -        # recreate plugin tuple for new regexp -        hoster = self.core.pluginManager.getPlugins("hoster") -        p = hoster[account.__name__] -        new = PluginTuple(p.version, re.compile(regexp), p.deps, p.user, p.path) -        hoster[account.__name__] = new - - - -    @AddEventListener("account:deleted") -    def refreshAccounts(self, plugin=None, user=None): - -        self.plugins = {} - -        for name, account in self.core.accountManager.iterAccounts(): -            if isinstance(account, MultiHosterAccount) and account.isUsable(): -                self.addHoster(account) - -    @AddEventListener("account:updated") -    def refreshAccount(self, plugin, user): - -        account = self.core.accountManager.getAccount(plugin, user) -        if isinstance(account, MultiHosterAccount) and account.isUsable(): -            self.addHoster(account) - -    def activate(self): -        self.refreshAccounts() - -        # new method for plugin manager -        def getPlugin(self2, name): -            if name in self.plugins: -                return self.plugins[name] -            return self2.getPluginClass(name) - -        pm = self.core.pluginManager -        pm.getPlugin = MethodType(getPlugin, pm, object) - - -    def deactivate(self): -        #restore state -        pm = self.core.pluginManager -        pm.getPlugin = pm.getPluginClass - diff --git a/module/plugins/addons/MultishareCz.py b/module/plugins/addons/MultishareCz.py deleted file mode 100644 index 7e5a3e007..000000000 --- a/module/plugins/addons/MultishareCz.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster -import re - -class MultishareCz(MultiHoster): -    __name__ = "MultishareCz" -    __version__ = "0.04" -    __type__ = "hook" -    __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)
\ No newline at end of file diff --git a/module/plugins/addons/Premium4Me.py b/module/plugins/addons/Premium4Me.py deleted file mode 100644 index b49eb41a9..000000000 --- a/module/plugins/addons/Premium4Me.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*-
 -
 -from module.network.RequestFactory import getURL
 -from module.plugins.internal.MultiHoster import MultiHoster
 -
 -class Premium4Me(MultiHoster):
 -    __name__ = "Premium4Me"
 -    __version__ = "0.02"
 -    __type__ = "hook"
 -
 -    __config__ = [("activated", "bool", "Activated", "False"),
 -        ("hosterListMode", "all;listed;unlisted", "Use for downloads from supported hosters:", "all"),
 -        ("hosterList", "str", "Hoster list (comma separated)", "")]
 -    __description__ = """premium4.me hook plugin"""
 -    __author_name__ = ("RaNaN", "zoidberg")
 -    __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz")
 -
 -    def getHoster(self):
 -
 -        page = getURL("http://premium4.me/api/hosters.php?authcode=%s" % self.account.authcode)
 -        return [x.strip() for x in page.replace("\"", "").split(";")]
 -
 -    def coreReady(self):
 -
 -        self.account = self.core.accountManager.getAccountPlugin("Premium4Me")
 -
 -        user = self.account.selectAccount()[0]
 -
 -        if not user:
 -            self.logError(_("Please add your premium4.me account first and restart pyLoad"))
 -            return
 -
 -        return MultiHoster.coreReady(self)
\ No newline at end of file diff --git a/module/plugins/addons/PremiumizeMe.py b/module/plugins/addons/PremiumizeMe.py deleted file mode 100644 index a10c24f85..000000000 --- a/module/plugins/addons/PremiumizeMe.py +++ /dev/null @@ -1,50 +0,0 @@ -from module.plugins.internal.MultiHoster import MultiHoster - -from module.common.json_layer      import json_loads -from module.network.RequestFactory import getURL - -class PremiumizeMe(MultiHoster): -    __name__ = "PremiumizeMe" -    __version__ = "0.12" -    __type__ = "hook" -    __description__ = """Premiumize.Me hook plugin""" - -    __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")] - -    __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(): -            return [] -         -        # Get account data -        (user, data) = self.account.selectAccount() -         -        # Get supported hosters list from premiumize.me using the json API v1 (see https://secure.premiumize.me/?show=api) -        answer = getURL("https://api.premiumize.me/pm-api/v1.php?method=hosterlist¶ms[login]=%s¶ms[pass]=%s" % (user, data['password'])) -        data = json_loads(answer) -         -         -        # If account is not valid thera are no hosters available -        if data['status'] != 200: -            return [] -         -        # Extract hosters from json file  -        return data['result']['hosterlist']  -             -    def coreReady(self): -        # Get account plugin and check if there is a valid account available -        self.account = self.core.accountManager.getAccountPlugin("PremiumizeMe")      -        if not self.account.canUse(): -            self.account = None -            self.logError(_("Please add a valid premiumize.me account first and restart pyLoad.")) -            return -                   -        # Run the overwriten core ready which actually enables the multihoster hook  -        return MultiHoster.coreReady(self)
\ No newline at end of file diff --git a/module/plugins/addons/RealdebridCom.py b/module/plugins/addons/RealdebridCom.py deleted file mode 100644 index be74b47c3..000000000 --- a/module/plugins/addons/RealdebridCom.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - -class RealdebridCom(MultiHoster): -    __name__ = "RealdebridCom" -    __version__ = "0.43" -    __type__ = "hook" - -    __config__ = [("activated", "bool", "Activated", "False"), -                  ("https", "bool", "Enable HTTPS", "False"), -                  ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"), -                  ("hosterList", "str", "Hoster list (comma separated)", ""), -                  ("unloadFailing", "bool", "Revert to stanard download if download fails", "False"), -                  ("interval", "int", "Reload interval in hours (0 to disable)", "24")] -    __description__ = """Real-Debrid.com hook plugin""" -    __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() - -        return [x.strip() for x in page.split(",") if x.strip()] diff --git a/module/plugins/addons/RehostTo.py b/module/plugins/addons/RehostTo.py deleted file mode 100644 index 7ca5e5cde..000000000 --- a/module/plugins/addons/RehostTo.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - -class RehostTo(MultiHoster): -    __name__ = "RehostTo" -    __version__ = "0.42" -    __type__ = "hook" - -    __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__ = """rehost.to hook plugin""" -    __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(",")] - - -    def coreReady(self): - -        self.account = self.core.accountManager.getAccountPlugin("RehostTo") - -        user = self.account.selectAccount()[0] - -        if not user: -            self.log.error("Rehost.to: "+ _("Please add your rehost.to account first and restart pyLoad")) -            return - -        data = self.account.getAccountInfo(user) -        self.ses = data["ses"] -        self.long_ses = data["long_ses"] - -        return MultiHoster.coreReady(self)
\ No newline at end of file diff --git a/module/plugins/addons/RestartFailed.py b/module/plugins/addons/RestartFailed.py deleted file mode 100644 index 7ee53deb9..000000000 --- a/module/plugins/addons/RestartFailed.py +++ /dev/null @@ -1,124 +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: Walter Purcaro -""" - -from module.plugins.Hook import Hook -from time import time - - -class RestartFailed(Hook): -    __name__ = "RestartFailed" -    __version__ = "1.5" -    __description__ = "Automatically restart failed/aborted downloads" -    __config__ = [ -        ("activated", "bool", "Activated", "True"), -        ("dlFail", "bool", "Restart when download fail", "True"), -        ("dlFail_n", "int", "Only when failed downloads are at least", "5"), -        ("dlFail_i", "int", "Only when elapsed time since last restart is (min)", "10"), -        ("dlPrcs", "bool", "Restart after all downloads are processed", "True"), -        ("recnt", "bool", "Restart after reconnecting", "True"), -        ("rsLoad", "bool", "Restart on plugin activation", "False") -    ] -    __author_name__ = ("Walter Purcaro") -    __author_mail__ = ("vuolter@gmail.com") - -    def restart(self, arg=None): -        # self.logDebug("self.restart") -        self.info["timerflag"] = False -        self.info["dlfailed"] = 0 -        self.core.api.restartFailed() -        self.logDebug("self.restart: self.core.api.restartFailed") -        self.info["lastrstime"] = time() - -    def periodical(self): -        # self.logDebug("self.periodical") -        if self.info["timerflag"]: -            self.restart() - -    def checkInterval(self, arg=None): -        # self.logDebug("self.checkInterval") -        now = time() -        lastrstime = self.info["lastrstime"] -        interval = self.getConfig("dlFail_i") * 60 -        if now < lastrstime + interval: -            self.info["timerflag"] = True -        else: -            self.restart() - -    def checkFailed(self, pyfile): -        # self.logDebug("self.checkFailed") -        self.info["dlfailed"] += 1 -        curr = self.info["dlfailed"] -        max = self.getConfig("dlFail_n") -        if curr >= max: -            self.checkInterval() - -    def addEvent(self, event, handler): -        if event in self.manager.events: -            if handler not in self.manager.events[event]: -                self.manager.events[event].append(handler) -                # self.logDebug("self.addEvent: " + event + ": added handler") -            else: -                # self.logDebug("self.addEvent: " + event + ": NOT added handler") -                return False -        else: -            self.manager.events[event] = [handler] -            # self.logDebug("self.addEvent: " + event + ": added event and handler") -        return True - -    def removeEvent(self, event, handler): -        if event in self.manager.events and handler in self.manager.events[event]: -            self.manager.events[event].remove(handler) -            # self.logDebug("self.removeEvent: " + event + ": removed handler") -            return True -        else: -            # self.logDebug("self.removeEvent: " + event + ": NOT removed handler") -            return False - -    def configEvents(self, plugin=None, name=None, value=None): -        # self.logDebug("self.configEvents") -        self.interval = self.getConfig("dlFail_i") * 60 -        dlFail = self.getConfig("dlFail") -        dlPrcs = self.getConfig("dlPrcs") -        recnt = self.getConfig("recnt") -        if dlPrcs: -            self.addEvent("allDownloadsProcessed", self.checkInterval) -        else: -            self.removeEvent("allDownloadsProcessed", self.checkInterval) -            if not dlFail: -                self.info["timerflag"] = False -        if recnt: -            self.addEvent("afterReconnecting", self.restart) -        else: -            self.removeEvent("afterReconnecting", self.restart) - -    def unload(self): -        # self.logDebug("self.unload") -        self.removeEvent("pluginConfigChanged", self.configEvents) -        self.removeEvent("downloadFailed", self.checkFailed) -        self.removeEvent("allDownloadsProcessed", self.checkInterval) -        self.removeEvent("afterReconnecting", self.restart) - -    def coreReady(self): -        # self.logDebug("self.coreReady") -        self.info = {"dlfailed": 0, "lastrstime": 0, "timerflag": False} -        if self.getConfig("rsLoad"): -            self.restart() -        self.addEvent("downloadFailed", self.checkFailed) -        self.addEvent("pluginConfigChanged", self.configEvents) -        self.configEvents() diff --git a/module/plugins/addons/UnSkipOnFail.py b/module/plugins/addons/UnSkipOnFail.py deleted file mode 100644 index 4b7a58be8..000000000 --- a/module/plugins/addons/UnSkipOnFail.py +++ /dev/null @@ -1,97 +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: hgg -""" -from os.path import basename - -from module.utils import fs_encode -from module.plugins.Hook import Hook -from module.PyFile import PyFile - -class UnSkipOnFail(Hook): -    __name__ = 'UnSkipOnFail' -    __version__ = '0.01' -    __description__ = 'When a download fails, restart "skipped" duplicates.' -    __config__ = [('activated', 'bool', 'Activated', True),] -    __author_name__ = ('hagg',) -    __author_mail__ = ('') - -    def downloadFailed(self, pyfile): -        pyfile_name = basename(pyfile.name) -        pid = pyfile.package().id -        msg = 'look for skipped duplicates for %s (pid:%s)...' -        self.logInfo(msg % (pyfile_name, pid)) -        dups = self.findDuplicates(pyfile) -        for link in dups: -            # check if link is "skipped"(=4) -            if link.status == 4: -                lpid = link.packageID -                self.logInfo('restart "%s" (pid:%s)...' % (pyfile_name, lpid)) -                self.setLinkStatus(link, "queued") - -    def findDuplicates(self, pyfile): -        """ Search all packages for duplicate links to "pyfile". -            Duplicates are links that would overwrite "pyfile". -            To test on duplicity the package-folder and link-name -            of twolinks are compared (basename(link.name)). -            So this method returns a list of all links with equal -            package-folders and filenames as "pyfile", but except -            the data for "pyfile" iotselöf. -            It does MOT check the link's status. -        """ -        dups = [] -        pyfile_name = fs_encode(basename(pyfile.name)) -        # get packages (w/o files, as most file data is useless here) -        queue = self.core.api.getQueue() -        for package in queue: -            # check if package-folder equals pyfile's package folder -            if fs_encode(package.folder) == fs_encode(pyfile.package().folder): -                # now get packaged data w/ files/links -                pdata = self.core.api.getPackageData(package.pid) -                if pdata.links: -                    for link in pdata.links: -                        link_name = fs_encode(basename(link.name)) -                        # check if link name collides with pdata's name -                        if link_name == pyfile_name: -                            # at last check if it is not pyfile itself -                            if link.fid != pyfile.id: -                                dups.append(link) -        return dups - -    def setLinkStatus(self, link, new_status): -        """ Change status of "link" to "new_status". -            "link" has to be a valid FileData object, -            "new_status" has to be a valid status name -              (i.e. "queued" for this Plugin) -            It creates a temporary PyFile object using -            "link" data, changes its status, and tells -            the core.files-manager to save its data. -        """ -        pyfile = PyFile(self.core.files, -                        link.fid, -                        link.url, -                        link.name, -                        link.size, -                        link.status, -                        link.error, -                        link.plugin, -                        link.packageID, -                        link.order) -        pyfile.setStatus(new_status) -        self.core.files.save() -        pyfile.release() - diff --git a/module/plugins/addons/UpdateManager.py b/module/plugins/addons/UpdateManager.py deleted file mode 100644 index c800b44bf..000000000 --- a/module/plugins/addons/UpdateManager.py +++ /dev/null @@ -1,201 +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: RaNaN -""" - -import sys -import re -from os import stat -from os.path import join, exists -from time import time - -from module.ConfigParser import IGNORE -from module.network.RequestFactory import getURL -from module.plugins.Hook import threaded, Expose, Hook - -class UpdateManager(Hook): -    __name__ = "UpdateManager" -    __version__ = "0.13" -    __description__ = """checks for updates""" -    __config__ = [("activated", "bool", "Activated", "True"), -        ("interval", "int", "Check interval in minutes", "480"), -        ("debug", "bool", "Check for plugin changes when in debug mode", False)] -    __author_name__ = ("RaNaN") -    __author_mail__ = ("ranan@pyload.org") - -    URL = "http://get.pyload.org/check2/%s/" -    MIN_TIME = 3 * 60 * 60 # 3h minimum check interval - -    @property -    def debug(self): -        return self.core.debug and self.getConfig("debug") - -    def setup(self): -        if self.debug: -            self.logDebug("Monitoring file changes") -            self.interval = 4 -            self.last_check = 0 #timestamp of updatecheck -            self.old_periodical = self.periodical -            self.periodical = self.checkChanges -            self.mtimes = {}  #recordes times -        else: -            self.interval = max(self.getConfig("interval") * 60, self.MIN_TIME) - -        self.updated = False -        self.reloaded = True -        self.version = "None" - -        self.info = {"pyload": False, "plugins": False} - -    @threaded -    def periodical(self): - -        updates = self.checkForUpdate() -        if updates: -            self.checkPlugins(updates) - -        if self.updated and not self.reloaded: -            self.info["plugins"] = True -            self.log.info(_("*** Plugins have been updated, please restart pyLoad ***")) -        elif self.updated and self.reloaded: -            self.log.info(_("Plugins updated and reloaded")) -            self.updated = False -        elif self.version == "None": -            self.log.info(_("No plugin updates available")) - -    @Expose -    def recheckForUpdates(self): -        """recheck if updates are available""" -        self.periodical() - -    def checkForUpdate(self): -        """checks if an update is available, return result""" - -        try: -            if self.version == "None": # No updated known -                version_check = getURL(self.URL % self.core.api.getServerVersion()).splitlines() -                self.version = version_check[0] - -                # Still no updates, plugins will be checked -                if self.version == "None": -                    self.log.info(_("No Updates for pyLoad")) -                    return version_check[1:] - - -            self.info["pyload"] = True -            self.log.info(_("***  New pyLoad Version %s available  ***") % self.version) -            self.log.info(_("***  Get it here: http://pyload.org/download  ***")) - -        except: -            self.log.warning(_("Not able to connect server for updates")) - -        return None # Nothing will be done - - -    def checkPlugins(self, updates): -        """ checks for plugins updates""" - -        # plugins were already updated -        if self.info["plugins"]: return - -        reloads = [] - -        vre = re.compile(r'__version__.*=.*("|\')([0-9.]+)') -        url = updates[0] -        schema = updates[1].split("|") -        updates = updates[2:] - -        for plugin in updates: -            info = dict(zip(schema, plugin.split("|"))) -            filename = info["name"] -            prefix = info["type"] -            version = info["version"] - -            if filename.endswith(".pyc"): -                name = filename[:filename.find("_")] -            else: -                name = filename.replace(".py", "") - -            #TODO: obsolete in 0.5.0 -            if prefix.endswith("s"): -                type = prefix[:-1] -            else: -                type = prefix - -            plugins = getattr(self.core.pluginManager, "%sPlugins" % type) - -            if name in plugins: -                if float(plugins[name]["v"]) >= float(version): -                    continue - -            if name in IGNORE or (type, name) in IGNORE: -                continue - -            self.log.info(_("New version of %(type)s|%(name)s : %(version).2f") % { -                "type": type, -                "name": name, -                "version": float(version) -            }) - -            try: -                content = getURL(url % info) -            except Exception, e: -                self.logWarning(_("Error when updating %s") % filename, str(e)) -                continue - -            m = vre.search(content) -            if not m or m.group(2) != version: -                self.logWarning(_("Error when updating %s") % name, _("Version mismatch")) -                continue - -            f = open(join("userplugins", prefix, filename), "wb") -            f.write(content) -            f.close() -            self.updated = True - -            reloads.append((prefix, name)) - -        self.reloaded = self.core.pluginManager.reloadPlugins(reloads) - -    def checkChanges(self): - -        if self.last_check + max(self.getConfig("interval") * 60, self.MIN_TIME) < time(): -            self.old_periodical() -            self.last_check = time() - -        modules = filter( -            lambda m: m and (m.__name__.startswith("module.plugins.") or m.__name__.startswith("userplugins.")) and m.__name__.count(".") >= 2, -            sys.modules.itervalues()) - -        reloads = [] - -        for m in modules: -            root, type, name = m.__name__.rsplit(".", 2) -            id = (type, name) -            if type in self.core.pluginManager.plugins: -                f = m.__file__.replace(".pyc", ".py") -                if not exists(f): continue - -                mtime = stat(f).st_mtime - -                if id not in self.mtimes: -                    self.mtimes[id] = mtime -                elif self.mtimes[id] < mtime: -                    reloads.append(id) -                    self.mtimes[id] = mtime - -        self.core.pluginManager.reloadPlugins(reloads) diff --git a/module/plugins/addons/XFileSharingPro.py b/module/plugins/addons/XFileSharingPro.py deleted file mode 100644 index 105c70113..000000000 --- a/module/plugins/addons/XFileSharingPro.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.Hook import Hook -import re - -class XFileSharingPro(Hook): -    __name__ = "XFileSharingPro" -    __version__ = "0.04" -    __type__ = "hook" -    __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__ = """Hoster URL pattern loader for the generic XFileSharingPro plugin""" -    __author_name__ = ("zoidberg") -    __author_mail__ = ("zoidberg@mujmail.cz") -           -    def coreReady(self): -        self.loadPattern() -       -    def loadPattern(self):          -        hosterList = self.getConfigSet('includeList') -        excludeList = self.getConfigSet('excludeList')          -         -        if self.getConfig('loadDefault'):         -            hosterList |= set(( -            #WORKING HOSTERS: -            "aieshare.com", "asixfiles.com", "banashare.com", "cyberlocker.ch", "eyesfile.co", "eyesfile.com", -            "fileband.com", "filedwon.com", "filedownloads.org", "hipfile.com", "kingsupload.com", "mlfat4arab.com",  -            "netuploaded.com", "odsiebie.pl", "q4share.com", "ravishare.com", "uptobox.com", "verzend.be",   -            #NOT TESTED:             -            "bebasupload.com", "boosterking.com", "divxme.com", "filevelocity.com", "glumbouploads.com", "grupload.com", "heftyfile.com",  -            "host4desi.com", "laoupload.com", "linkzhost.com", "movreel.com", "rockdizfile.com", "limfile.com" -            "share76.com", "sharebeast.com", "sharehut.com", "sharerun.com", "shareswift.com", "sharingonline.com", "6ybh-upload.com",  -            "skipfile.com", "spaadyshare.com", "space4file.com", "uploadbaz.com", "uploadc.com",  -            "uploaddot.com", "uploadfloor.com", "uploadic.com", "uploadville.com", "vidbull.com", "zalaa.com",  -            "zomgupload.com", "kupload.org", "movbay.org", "multishare.org", "omegave.org", "toucansharing.org", "uflinq.org", -            "banicrazy.info", "flowhot.info", "upbrasil.info", "shareyourfilez.biz", "bzlink.us", "cloudcache.cc", "fileserver.cc" -            "farshare.to", "filemaze.ws", "filehost.ws", "filestock.ru", "moidisk.ru", "4up.im", "100shared.com", -            #WRONG FILE NAME: -            "sendmyway.com", "upchi.co.il", "180upload.com",  -            #NOT WORKING: -            "amonshare.com", "imageporter.com", "file4safe.com", -            #DOWN OR BROKEN: -            "ddlanime.com", "fileforth.com", "loombo.com", "goldfile.eu", "putshare.com" -            ))              -               -        hosterList -= (excludeList) -        hosterList -= set(('', u'')) -         -        if not hosterList: -            self.unload() -            return -                                             -        regexp = r"http://(?:[^/]*\.)?(%s)/\w{12}" % ("|".join(sorted(hosterList)).replace('.','\.')) -        #self.logDebug(regexp) -         -        dict = self.core.pluginManager.hosterPlugins['XFileSharingPro'] -        dict["pattern"] = regexp -        dict["re"] = re.compile(regexp) -        self.logDebug("Pattern loaded - handling %d hosters" % len(hosterList)) -         -    def getConfigSet(self, option): -        s = self.getConfig(option).lower().replace('|',',').replace(';',',') -        return set([x.strip() for x in s.split(',')]) -         -    def unload(self): -        dict = self.core.pluginManager.hosterPlugins['XFileSharingPro'] -        dict["pattern"] = r"^unmatchable$" -        dict["re"] = re.compile(r"^unmatchable$")
\ No newline at end of file diff --git a/module/plugins/addons/XMPPInterface.py b/module/plugins/addons/XMPPInterface.py deleted file mode 100644 index e8ef1d2ca..000000000 --- a/module/plugins/addons/XMPPInterface.py +++ /dev/null @@ -1,276 +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: RaNaN -    @interface-version: 0.2 -""" - -from pyxmpp import streamtls -from pyxmpp.all import JID, Message, Presence -from pyxmpp.jabber.client import JabberClient -from pyxmpp.interface import implements -from pyxmpp.interfaces import * - -from module.plugins.addons.IRCInterface import IRCInterface - -class XMPPInterface(IRCInterface, JabberClient): -    __name__ = "XMPPInterface" -    __version__ = "0.1" -    __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", ""), -            ("tls", "bool", "Use TLS", False), -            ("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"), -            ("info_file", "bool", "Inform about every file finished", "False"), -            ("info_pack", "bool", "Inform about every package finished", "True"), -            ("captcha", "bool", "Send captcha requests", "True")] -    __author_name__ = ("RaNaN") -    __author_mail__ = ("RaNaN@pyload.org") - -    implements(IMessageHandlersProvider) - -    def __init__(self, core, manager): -        IRCInterface.__init__(self, core, manager) - -        self.jid = JID(self.getConfig("jid")) -        password = self.getConfig("pw") - -        # if bare JID is provided add a resource -- it is required -        if not self.jid.resource: -            self.jid = JID(self.jid.node, self.jid.domain, "pyLoad") - -        if self.getConfig("tls"): -            tls_settings = streamtls.TLSSettings(require=True, verify_peer=False) -            auth = ("sasl:PLAIN", "sasl:DIGEST-MD5") -        else: -            tls_settings = None -            auth = ("sasl:DIGEST-MD5", "digest") - -        # setup client with provided connection information -        # and identity data -        JabberClient.__init__(self, self.jid, password, -                              disco_name="pyLoad XMPP Client", disco_type="bot", -                              tls_settings=tls_settings, auth_methods=auth) - -        self.interface_providers = [ -            VersionHandler(self), -            self, -            ] - -    def coreReady(self): -        self.new_package = {} - -        self.start() - -    def packageFinished(self, pypack): -        try: -            if self.getConfig("info_pack"): -                self.announce(_("Package finished: %s") % pypack.name) -        except: -            pass - -    def downloadFinished(self, pyfile): -        try: -            if self.getConfig("info_file"): -                self.announce( -                    _("Download finished: %(name)s @ %(plugin)s") % {"name": pyfile.name, "plugin": pyfile.pluginname}) -        except: -            pass - -    def run(self): -        # connect to IRC etc. -        self.connect() -        try: -            self.loop() -        except Exception, ex: -            self.core.log.error("pyLoad XMPP: %s" % str(ex)) - -    def stream_state_changed(self, state, arg): -        """This one is called when the state of stream connecting the component -        to a server changes. This will usually be used to let the user -        know what is going on.""" -        self.log.debug("pyLoad XMPP: *** State changed: %s %r ***" % (state, arg)) - -    def disconnected(self): -        self.log.debug("pyLoad XMPP: Client was disconnected") - -    def stream_closed(self, stream): -        self.log.debug("pyLoad XMPP: Stream was closed | %s" % stream) - -    def stream_error(self, err): -        self.log.debug("pyLoad XMPP: Stream Error: %s" % err) - -    def get_message_handlers(self): -        """Return list of (message_type, message_handler) tuples. - -        The handlers returned will be called when matching message is received -        in a client session.""" -        return [ -                ("normal", self.message), -                ] - -    def presence_control(self, stanza): -        from_jid = unicode(stanza.get_from_jid()) -        stanza_type = stanza.get_type() -        self.log.debug("pyLoad XMPP: %s stanza from %s" % (stanza_type, -            from_jid)) - -        if from_jid in self.getConfig("owners"): -            return stanza.make_accept_response() - -        return stanza.make_deny_response() - -    def session_started(self): -        self.stream.send(Presence()) - -        self.stream.set_presence_handler("subscribe", self.presence_control) -        self.stream.set_presence_handler("subscribed", self.presence_control) -        self.stream.set_presence_handler("unsubscribe", self.presence_control) -        self.stream.set_presence_handler("unsubscribed", self.presence_control) - -    def message(self, stanza): -        """Message handler for the component.""" -        subject = stanza.get_subject() -        body = stanza.get_body() -        t = stanza.get_type() -        self.log.debug(u'pyLoad XMPP: Message from %s received.' % (unicode(stanza.get_from(), ))) -        self.log.debug(u'pyLoad XMPP: Body: %s Subject: %s Type: %s' % (body, subject, t)) - -        if t == "headline": -            # 'headline' messages should never be replied to -            return True -        if subject: -            subject = u"Re: " + subject - -        to_jid = stanza.get_from() -        from_jid = stanza.get_to() - -        #j = JID() -        to_name = to_jid.as_utf8() -        from_name = from_jid.as_utf8() - -        names = self.getConfig("owners").split(";") - -        if to_name in names or to_jid.node + "@" + to_jid.domain in names: -            messages = [] - -            trigger = "pass" -            args = None - -            try: -                temp = body.split() -                trigger = temp[0] -                if len(temp) > 1: -                    args = temp[1:] -            except: -                pass - -            handler = getattr(self, "event_%s" % trigger, self.event_pass) -            try: -                res = handler(args) -                for line in res: -                    m = Message( -                        to_jid=to_jid, -                        from_jid=from_jid, -                        stanza_type=stanza.get_type(), -                        subject=subject, -                        body=line) - -                    messages.append(m) -            except Exception, e: -                self.log.error("pyLoad XMPP: " + repr(e)) - -            return messages - -        else: -            return True - -    def response(self, msg, origin=""): -        return self.announce(msg) - -    def announce(self, message): -        """ send message to all owners""" -        for user in self.getConfig("owners").split(";"): -            self.log.debug("pyLoad XMPP: Send message to %s" % user) - -            to_jid = JID(user) - -            m = Message(from_jid=self.jid, -                        to_jid=to_jid, -                        stanza_type="chat", -                        body=message) - -            stream = self.get_stream() -            if not stream: -                self.connect() -                stream = self.get_stream() - -            stream.send(m) - -    def beforeReconnecting(self, ip): -        self.disconnect() - -    def afterReconnecting(self, ip): -        self.connect() - - -class VersionHandler(object): -    """Provides handler for a version query. -     -    This class will answer version query and announce 'jabber:iq:version' namespace -    in the client's disco#info results.""" - -    implements(IIqHandlersProvider, IFeaturesProvider) - -    def __init__(self, client): -        """Just remember who created this.""" -        self.client = client - -    def get_features(self): -        """Return namespace which should the client include in its reply to a -        disco#info query.""" -        return ["jabber:iq:version"] - -    def get_iq_get_handlers(self): -        """Return list of tuples (element_name, namespace, handler) describing -        handlers of <iq type='get'/> stanzas""" -        return [ -                ("query", "jabber:iq:version", self.get_version), -                                                                ] - -    def get_iq_set_handlers(self): -        """Return empty list, as this class provides no <iq type='set'/> stanza handler.""" -        return [] - -    def get_version(self, iq): -        """Handler for jabber:iq:version queries. - -        jabber:iq:version queries are not supported directly by PyXMPP, so the -        XML node is accessed directly through the libxml2 API.  This should be -        used very carefully!""" -        iq = iq.make_result_response() -        q = iq.new_query("jabber:iq:version") -        q.newTextChild(q.ns(), "name", "Echo component") -        q.newTextChild(q.ns(), "version", "1.0") -        return iq - -    def unload(self): -        self.log.debug("pyLoad XMPP: unloading") -        self.disconnect() - -    def deactivate(self): -        self.unload() diff --git a/module/plugins/addons/ZeveraCom.py b/module/plugins/addons/ZeveraCom.py deleted file mode 100644 index cadf60069..000000000 --- a/module/plugins/addons/ZeveraCom.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - -class ZeveraCom(MultiHoster): -    __name__ = "ZeveraCom" -    __version__ = "0.02" -    __type__ = "hook" -    __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(",")]                           
\ No newline at end of file diff --git a/module/plugins/addons/__init__.py b/module/plugins/addons/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/module/plugins/addons/__init__.py +++ /dev/null | 
