diff options
Diffstat (limited to 'module/plugins/hooks')
54 files changed, 0 insertions, 5149 deletions
| diff --git a/module/plugins/hooks/AlldebridComHook.py b/module/plugins/hooks/AlldebridComHook.py deleted file mode 100644 index 092921134..000000000 --- a/module/plugins/hooks/AlldebridComHook.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class AlldebridComHook(MultiHook): -    __name__    = "AlldebridComHook" -    __type__    = "hook" -    __version__ = "0.16" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   ), -                  ("ssl"           , "bool"               , "Use HTTPS"                           , True )] - -    __description__ = """Alldebrid.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Andy Voigt", "spamsales@online.de")] - - -    def getHosters(self): -        https = "https" if self.getConfig('ssl') else "http" -        html = self.getURL(https + "://www.alldebrid.com/api.php", get={'action': "get_host"}).replace("\"", "").strip() - -        return [x.strip() for x in html.split(",") if x.strip()] diff --git a/module/plugins/hooks/AndroidPhoneNotify.py b/module/plugins/hooks/AndroidPhoneNotify.py deleted file mode 100644 index 67a0ea4f0..000000000 --- a/module/plugins/hooks/AndroidPhoneNotify.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- - -import time - -from module.network.RequestFactory import getURL -from module.plugins.Hook import Hook, Expose - - -class AndroidPhoneNotify(Hook): -    __name__    = "AndroidPhoneNotify" -    __type__    = "hook" -    __version__ = "0.07" - -    __config__ = [("apikey"         , "str" , "API key"                                  , ""   ), -                  ("notifycaptcha"  , "bool", "Notify captcha request"                   , True ), -                  ("notifypackage"  , "bool", "Notify package finished"                  , True ), -                  ("notifyprocessed", "bool", "Notify packages processed"                , True ), -                  ("notifyupdate"   , "bool", "Notify plugin updates"                    , True ), -                  ("notifyexit"     , "bool", "Notify pyLoad shutdown"                   , True ), -                  ("sendtimewait"   , "int" , "Timewait in seconds between notifications", 5    ), -                  ("sendpermin"     , "int" , "Max notifications per minute"             , 12   ), -                  ("ignoreclient"   , "bool", "Send notifications if client is connected", False)] - -    __description__ = """Send push notifications to your Android Phone (using notifymyandroid.com)""" -    __license__     = "GPLv3" -    __authors__     = [("Steven Kosyra" , "steven.kosyra@gmail.com"), -                       ("Walter Purcaro", "vuolter@gmail.com"      )] - - -    event_list = ["allDownloadsProcessed", "plugin_updated"] -    interval   = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info          = {}  #@TODO: Remove in 0.4.10 -        self.last_notify   = 0 -        self.notifications = 0 - - -    def plugin_updated(self, type_plugins): -        if not self.getConfig('notifyupdate'): -            return - -        self.notify(_("Plugins updated"), str(type_plugins)) - - -    def coreExiting(self): -        if not self.getConfig('notifyexit'): -            return - -        if self.core.do_restart: -            self.notify(_("Restarting pyLoad")) -        else: -            self.notify(_("Exiting pyLoad")) - - -    def newCaptchaTask(self, task): -        if not self.getConfig('notifycaptcha'): -            return - -        self.notify(_("Captcha"), _("New request waiting user input")) - - -    def packageFinished(self, pypack): -        if self.getConfig('notifypackage'): -            self.notify(_("Package finished"), pypack.name) - - -    def allDownloadsProcessed(self): -        if not self.getConfig('notifyprocessed'): -            return - -        if any(True for pdata in self.core.api.getQueue() if pdata.linksdone < pdata.linkstotal): -            self.notify(_("Package failed"), _("One or more packages was not completed successfully")) -        else: -            self.notify(_("All packages finished")) - - -    @Expose -    def notify(self, -               event, -               msg="", -               key=self.getConfig('apikey')): - -        if not key: -            return - -        if self.core.isClientConnected() and not self.getConfig('ignoreclient'): -            return - -        elapsed_time = time.time() - self.last_notify - -        if elapsed_time < self.getConf("sendtimewait"): -            return - -        if elapsed_time > 60: -            self.notifications = 0 - -        elif self.notifications >= self.getConf("sendpermin"): -            return - - -        getURL("http://www.notifymyandroid.com/publicapi/notify", -               get={'apikey'     : key, -                    'application': "pyLoad", -                    'event'      : event, -                    'description': msg}) - -        self.last_notify    = time.time() -        self.notifications += 1 diff --git a/module/plugins/hooks/AntiVirus.py b/module/plugins/hooks/AntiVirus.py deleted file mode 100644 index ac9373a37..000000000 --- a/module/plugins/hooks/AntiVirus.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import shutil -import subprocess - -try: -    import send2trash -except ImportError: -    pass - -from module.plugins.Hook import Hook, Expose, threaded -from module.utils import fs_encode, save_join - - -class AntiVirus(Hook): -    __name__    = "AntiVirus" -    __type__    = "hook" -    __version__ = "0.08" - -    #@TODO: add trash option (use Send2Trash lib) -    __config__ = [("action"    , "Antivirus default;Delete;Quarantine", "Manage infected files"                     , "Antivirus default"), -                  ("quardir"   , "folder"                             , "Quarantine folder"                         , ""                 ), -                  ("deltotrash", "bool"                               , "Move to trash (recycle bin) instead delete", True               ), -                  ("scanfailed", "bool"                               , "Scan incompleted files (failed downloads)" , False              ), -                  ("cmdfile"   , "file"                               , "Antivirus executable"                      , ""                 ), -                  ("cmdargs"   , "str"                                , "Scan options"                              , ""                 ), -                  ("ignore-err", "bool"                               , "Ignore scan errors"                        , False              )] - -    __description__ = """Scan downloaded files with antivirus program""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    @Expose -    @threaded -    def scan(self, pyfile, thread): -        file     = fs_encode(pyfile.plugin.lastDownload) -        filename = os.path.basename(pyfile.plugin.lastDownload) -        cmdfile  = fs_encode(self.getConfig('cmdfile')) -        cmdargs  = fs_encode(self.getConfig('cmdargs').strip()) - -        if not os.path.isfile(file) or not os.path.isfile(cmdfile): -            return - -        thread.addActive(pyfile) -        pyfile.setCustomStatus(_("virus scanning")) -        pyfile.setProgress(0) - -        try: -            p = subprocess.Popen([cmdfile, cmdargs, file], bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - -            out, err = map(str.strip, p.communicate()) - -            if out: -                self.logInfo(filename, out) - -            if err: -                self.logWarning(filename, err) -                if not self.getConfig('ignore-err'): -                    self.logDebug("Delete/Quarantine task is aborted") -                    return - -            if p.returncode: -                pyfile.error = _("infected file") -                action = self.getConfig('action') -                try: -                    if action == "Delete": -                        if not self.getConfig('deltotrash'): -                            os.remove(file) - -                        else: -                            try: -                                send2trash.send2trash(file) - -                            except Exception: -                                self.logWarning(_("Unable to move file to trash, move to quarantine instead")) -                                pyfile.setCustomStatus(_("file moving")) -                                shutil.move(file, self.getConfig('quardir')) - -                    elif action == "Quarantine": -                        pyfile.setCustomStatus(_("file moving")) -                        shutil.move(file, self.getConfig('quardir')) - -                except (IOError, shutil.Error), e: -                    self.logError(filename, action + " action failed!", e) - -            elif not out and not err: -                self.logDebug(filename, "No infected file found") - -        finally: -            pyfile.setProgress(100) -            thread.finishFile(pyfile) - - -    def downloadFinished(self, pyfile): -        return self.scan(pyfile) - - -    def downloadFailed(self, pyfile): -        #: Check if pyfile is still "failed", -        #  maybe might has been restarted in meantime -        if pyfile.status == 8 and self.getConfig('scanfailed'): -            return self.scan(pyfile) diff --git a/module/plugins/hooks/BypassCaptcha.py b/module/plugins/hooks/BypassCaptcha.py deleted file mode 100644 index 9e01edfa2..000000000 --- a/module/plugins/hooks/BypassCaptcha.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- - -import pycurl - -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook, threaded - - -class BypassCaptchaException(Exception): - -    def __init__(self, err): -        self.err = err - - -    def getCode(self): -        return self.err - - -    def __str__(self): -        return "<BypassCaptchaException %s>" % self.err - - -    def __repr__(self): -        return "<BypassCaptchaException %s>" % self.err - - -class BypassCaptcha(Hook): -    __name__    = "BypassCaptcha" -    __type__    = "hook" -    __version__ = "0.06" - -    __config__ = [("force", "bool", "Force BC even if client is connected", False), -                  ("passkey", "password", "Passkey", "")] - -    __description__ = """Send captchas to BypassCaptcha.com""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"     , "RaNaN@pyload.org"     ), -                       ("Godofdream", "soilfcition@gmail.com"), -                       ("zoidberg"  , "zoidberg@mujmail.cz"  )] - - -    interval = 0  #@TODO: Remove in 0.4.10 - -    PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32" - -    SUBMIT_URL = "http://bypasscaptcha.com/upload.php" -    RESPOND_URL = "http://bypasscaptcha.com/check_value.php" -    GETCREDITS_URL = "http://bypasscaptcha.com/ex_left.php" - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def getCredits(self): -        res = getURL(self.GETCREDITS_URL, post={"key": self.getConfig('passkey')}) - -        data = dict(x.split(' ', 1) for x in res.splitlines()) -        return int(data['Left']) - - -    def submit(self, captcha, captchaType="file", match=None): -        req = getRequest() - -        #raise timeout threshold -        req.c.setopt(pycurl.LOW_SPEED_TIME, 80) - -        try: -            res = req.load(self.SUBMIT_URL, -                           post={'vendor_key': self.PYLOAD_KEY, -                                 'key': self.getConfig('passkey'), -                                 'gen_task_id': "1", -                                 'file': (pycurl.FORM_FILE, captcha)}, -                           multipart=True) -        finally: -            req.close() - -        data = dict(x.split(' ', 1) for x in res.splitlines()) -        if not data or "Value" not in data: -            raise BypassCaptchaException(res) - -        result = data['Value'] -        ticket = data['TaskId'] -        self.logDebug("Result %s : %s" % (ticket, result)) - -        return ticket, result - - -    def respond(self, ticket, success): -        try: -            res = getURL(self.RESPOND_URL, post={"task_id": ticket, "key": self.getConfig('passkey'), -                                                      "cv": 1 if success else 0}) -        except BadHeader, e: -            self.logError(_("Could not send response"), e) - - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False - -        if not task.isTextual(): -            return False - -        if not self.getConfig('passkey'): -            return False - -        if self.core.isClientConnected() and not self.getConfig('force'): -            return False - -        if self.getCredits() > 0: -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(100) -            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) - - -    @threaded -    def _processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except BypassCaptchaException, e: -            task.error = e.getCode() -            return - -        task.data['ticket'] = ticket -        task.setResult(result) diff --git a/module/plugins/hooks/Captcha9Kw.py b/module/plugins/hooks/Captcha9Kw.py deleted file mode 100644 index 60482b8fc..000000000 --- a/module/plugins/hooks/Captcha9Kw.py +++ /dev/null @@ -1,254 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import re -import time - -from base64 import b64encode - -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getURL - -from module.plugins.Hook import Hook, threaded - - -class Captcha9Kw(Hook): -    __name__    = "Captcha9Kw" -    __type__    = "hook" -    __version__ = "0.28" - -    __config__ = [("ssl"           , "bool"    , "Use HTTPS"                                                                       , True                                                               ), -                  ("force"         , "bool"    , "Force captcha resolving even if client is connected"                             , True                                                               ), -                  ("confirm"       , "bool"    , "Confirm Captcha (cost +6 credits)"                                               , False                                                              ), -                  ("captchaperhour", "int"     , "Captcha per hour"                                                                , "9999"                                                             ), -                  ("captchapermin" , "int"     , "Captcha per minute"                                                              , "9999"                                                             ), -                  ("prio"          , "int"     , "Priority (max 10)(cost +0 -> +10 credits)"                                       , "0"                                                                ), -                  ("queue"         , "int"     , "Max. Queue (max 999)"                                                            , "50"                                                               ), -                  ("hoster_options", "string"  , "Hoster options (format: pluginname:prio=1:selfsolfe=1:confirm=1:timeout=900|...)", "ShareonlineBiz:prio=0:timeout=999 | UploadedTo:prio=0:timeout=999"), -                  ("selfsolve"     , "bool"    , "Selfsolve (manually solve your captcha in your 9kw client if active)"            , "0"                                                                ), -                  ("passkey"       , "password", "API key"                                                                         , ""                                                                 ), -                  ("timeout"       , "int"     , "Timeout in seconds (min 60, max 3999)"                                           , "900"                                                              )] - -    __description__ = """Send captchas to 9kw.eu""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"         , "RaNaN@pyload.org" ), -                       ("Walter Purcaro", "vuolter@gmail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - -    API_URL = "http://www.9kw.eu/index.cgi" - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 -        if self.getConfig('ssl'): -            self.API_URL = self.API_URL.replace("http://", "https://") - - -    def getCredits(self): -        res = getURL(self.API_URL, -                     get={'apikey': self.getConfig('passkey'), -                          'pyload': "1", -                          'source': "pyload", -                          'action': "usercaptchaguthaben"}) - -        if res.isdigit(): -            self.logInfo(_("%s credits left") % res) -            credits = self.info['credits'] = int(res) -            return credits -        else: -            self.logError(res) -            return 0 - - -    @threaded -    def _processCaptcha(self, task): -        try: -            with open(task.captchaFile, 'rb') as f: -                data = f.read() - -        except IOError, e: -            self.logError(e) -            return - -        pluginname = re.search(r'_([^_]*)_\d+.\w+', task.captchaFile).group(1) -        option     = {'min'           : 2, -                      'max'           : 50, -                      'phrase'        : 0, -                      'numeric'       : 0, -                      'case_sensitive': 0, -                      'math'          : 0, -                      'prio'          : min(max(self.getConfig('prio'), 0), 10), -                      'confirm'       : self.getConfig('confirm'), -                      'timeout'       : min(max(self.getConfig('timeout'), 300), 3999), -                      'selfsolve'     : self.getConfig('selfsolve'), -                      'cph'           : self.getConfig('captchaperhour'), -                      'cpm'           : self.getConfig('captchapermin')} - -        for opt in str(self.getConfig('hoster_options').split('|')): - -            details = map(str.strip, opt.split(':')) - -            if not details or details[0].lower() != pluginname.lower(): -                continue - -            for d in details: -                hosteroption = d.split("=") - -                if len(hosteroption) < 2 or not hosteroption[1].isdigit(): -                    continue - -                o = hosteroption[0].lower() -                if o in option: -                    option[o] = hosteroption[1] - -            break - -        post_data = {'apikey'        : self.getConfig('passkey'), -                     'prio'          : option['prio'], -                     'confirm'       : option['confirm'], -                     'maxtimeout'    : option['timeout'], -                     'selfsolve'     : option['selfsolve'], -                     'captchaperhour': option['cph'], -                     'captchapermin' : option['cpm'], -                     'case-sensitive': option['case_sensitive'], -                     'min_len'       : option['min'], -                     'max_len'       : option['max'], -                     'phrase'        : option['phrase'], -                     'numeric'       : option['numeric'], -                     'math'          : option['math'], -                     'oldsource'     : pluginname, -                     'pyload'        : "1", -                     'source'        : "pyload", -                     'base64'        : "1", -                     'mouse'         : 1 if task.isPositional() else 0, -                     'file-upload-01': b64encode(data), -                     'action'        : "usercaptchaupload"} - -        for _i in xrange(5): -            try: -                res = getURL(self.API_URL, post=post_data) -            except BadHeader, e: -                time.sleep(3) -            else: -                if res and res.isdigit(): -                    break -        else: -            self.logError(_("Bad upload: %s") % res) -            return - -        self.logDebug(_("NewCaptchaID ticket: %s") % res, task.captchaFile) - -        task.data["ticket"] = res - -        for _i in xrange(int(self.getConfig('timeout') / 5)): -            result = getURL(self.API_URL, -                            get={'apikey': self.getConfig('passkey'), -                                 'id'    : res, -                                 'pyload': "1", -                                 'info'  : "1", -                                 'source': "pyload", -                                 'action': "usercaptchacorrectdata"}) - -            if not result or result == "NO DATA": -                time.sleep(5) -            else: -                break -        else: -            self.logDebug("Could not send request: %s" % res) -            result = None - -        self.logInfo(_("Captcha result for ticket %s: %s") % (res, result)) - -        task.setResult(result) - - -    def newCaptchaTask(self, task): -        if not task.isTextual() and not task.isPositional(): -            return - -        if not self.getConfig('passkey'): -            return - -        if self.core.isClientConnected() and not self.getConfig('force'): -            return - -        credits = self.getCredits() - -        if not credits: -            self.logError(_("Your captcha 9kw.eu account has not enough credits")) -            return - -        queue = min(self.getConfig('queue'), 999) -        timeout = min(max(self.getConfig('timeout'), 300), 3999) -        pluginname = re.search(r'_([^_]*)_\d+.\w+', task.captchaFile).group(1) - -        for _i in xrange(5): -            servercheck = getURL("http://www.9kw.eu/grafik/servercheck.txt") -            if queue < re.search(r'queue=(\d+)', servercheck).group(1): -                break - -            time.sleep(10) -        else: -            self.fail(_("Too many captchas in queue")) - -        for opt in str(self.getConfig('hoster_options').split('|')): -            details = map(str.strip, opt.split(':')) - -            if not details or details[0].lower() != pluginname.lower(): -                continue - -            for d in details: -                hosteroption = d.split("=") - -                if len(hosteroption) > 1 \ -                   and hosteroption[0].lower() == 'timeout' \ -                   and hosteroption[1].isdigit(): -                    timeout = int(hosteroption[1]) - -            break - -        task.handler.append(self) - -        task.setWaiting(timeout) - -        self._processCaptcha(task) - - -    def _captchaResponse(self, task, correct): -        type = "correct" if correct else "refund" - -        if 'ticket' not in task.data: -            self.logDebug("No CaptchaID for %s request (task: %s)" % (type, task)) -            return - -        passkey = self.getConfig('passkey') - -        for _i in xrange(3): -            res = getURL(self.API_URL, -                         get={'action' : "usercaptchacorrectback", -                              'apikey' : passkey, -                              'api_key': passkey, -                              'correct': "1" if correct else "2", -                              'pyload' : "1", -                              'source' : "pyload", -                              'id'     : task.data["ticket"]}) - -            self.logDebug("Request %s: %s" % (type, res)) - -            if res == "OK": -                break - -            time.sleep(5) -        else: -            self.logDebug("Could not send %s request: %s" % (type, res)) - - -    def captchaCorrect(self, task): -        self._captchaResponse(task, True) - - -    def captchaInvalid(self, task): -        self._captchaResponse(task, False) diff --git a/module/plugins/hooks/CaptchaBrotherhood.py b/module/plugins/hooks/CaptchaBrotherhood.py deleted file mode 100644 index bda080037..000000000 --- a/module/plugins/hooks/CaptchaBrotherhood.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import StringIO -import pycurl -import time -import urllib - -try: -    from PIL import Image -except ImportError: -    import Image - -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook, threaded - - -class CaptchaBrotherhoodException(Exception): - -    def __init__(self, err): -        self.err = err - - -    def getCode(self): -        return self.err - - -    def __str__(self): -        return "<CaptchaBrotherhoodException %s>" % self.err - - -    def __repr__(self): -        return "<CaptchaBrotherhoodException %s>" % self.err - - -class CaptchaBrotherhood(Hook): -    __name__    = "CaptchaBrotherhood" -    __type__    = "hook" -    __version__ = "0.08" - -    __config__ = [("username", "str", "Username", ""), -                  ("force", "bool", "Force CT even if client is connected", False), -                  ("passkey", "password", "Password", "")] - -    __description__ = """Send captchas to CaptchaBrotherhood.com""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"   , "RaNaN@pyload.org"   ), -                       ("zoidberg", "zoidberg@mujmail.cz")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - -    API_URL = "http://www.captchabrotherhood.com/" - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def getCredits(self): -        res = getURL(self.API_URL + "askCredits.aspx", -                     get={"username": self.getConfig('username'), "password": self.getConfig('passkey')}) -        if not res.startswith("OK"): -            raise CaptchaBrotherhoodException(res) -        else: -            credits = int(res[3:]) -            self.logInfo(_("%d credits left") % credits) -            self.info['credits'] = credits -            return credits - - -    def submit(self, captcha, captchaType="file", match=None): -        try: -            img = Image.open(captcha) -            output = StringIO.StringIO() -            self.logDebug("CAPTCHA IMAGE", img, img.format, img.mode) -            if img.format in ("GIF", "JPEG"): -                img.save(output, img.format) -            else: -                if img.mode != "RGB": -                    img = img.convert("RGB") -                img.save(output, "JPEG") -            data = output.getvalue() -            output.close() -        except Exception, e: -            raise CaptchaBrotherhoodException("Reading or converting captcha image failed: %s" % e) - -        req = getRequest() - -        url = "%ssendNewCaptcha.aspx?%s" % (self.API_URL, -                                            urllib.urlencode({'username'     : self.getConfig('username'), -                                                              'password'     : self.getConfig('passkey'), -                                                              'captchaSource': "pyLoad", -                                                              'timeout'      : "80"})) - -        req.c.setopt(pycurl.URL, url) -        req.c.setopt(pycurl.POST, 1) -        req.c.setopt(pycurl.POSTFIELDS, data) -        req.c.setopt(pycurl.HTTPHEADER, ["Content-Type: text/html"]) - -        try: -            req.c.perform() -            res = req.getResponse() -        except Exception, e: -            raise CaptchaBrotherhoodException("Submit captcha image failed") - -        req.close() - -        if not res.startswith("OK"): -            raise CaptchaBrotherhoodException(res[1]) - -        ticket = res[3:] - -        for _i in xrange(15): -            time.sleep(5) -            res = self.api_response("askCaptchaResult", ticket) -            if res.startswith("OK-answered"): -                return ticket, res[12:] - -        raise CaptchaBrotherhoodException("No solution received in time") - - -    def api_response(self, api, ticket): -        res = getURL("%s%s.aspx" % (self.API_URL, api), -                          get={"username": self.getConfig('username'), -                               "password": self.getConfig('passkey'), -                               "captchaID": ticket}) -        if not res.startswith("OK"): -            raise CaptchaBrotherhoodException("Unknown response: %s" % res) - -        return res - - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False - -        if not task.isTextual(): -            return False - -        if not self.getConfig('username') or not self.getConfig('passkey'): -            return False - -        if self.core.isClientConnected() and not self.getConfig('force'): -            return False - -        if self.getCredits() > 10: -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(100) -            self._processCaptcha(task) -        else: -            self.logInfo(_("Your CaptchaBrotherhood Account has not enough credits")) - - -    def captchaInvalid(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            res = self.api_response("complainCaptcha", task.data['ticket']) - - -    @threaded -    def _processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except CaptchaBrotherhoodException, e: -            task.error = e.getCode() -            return - -        task.data['ticket'] = ticket -        task.setResult(result) diff --git a/module/plugins/hooks/Checksum.py b/module/plugins/hooks/Checksum.py deleted file mode 100644 index ab7daf701..000000000 --- a/module/plugins/hooks/Checksum.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import hashlib -import os -import re -import zlib - -from module.plugins.Hook import Hook -from module.utils import save_join, fs_encode - - -def computeChecksum(local_file, algorithm): -    if algorithm in getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")): -        h = getattr(hashlib, algorithm)() - -        with open(local_file, 'rb') as f: -            for chunk in iter(lambda: f.read(128 * h.block_size), ''): -                h.update(chunk) - -        return h.hexdigest() - -    elif algorithm in ("adler32", "crc32"): -        hf = getattr(zlib, algorithm) -        last = 0 - -        with open(local_file, 'rb') as f: -            for chunk in iter(lambda: f.read(8192), ''): -                last = hf(chunk, last) - -        return "%x" % last - -    else: -        return None - - -class Checksum(Hook): -    __name__    = "Checksum" -    __type__    = "hook" -    __version__ = "0.16" - -    __config__ = [("check_checksum", "bool", "Check checksum? (If False only size will be verified)", True), -                  ("check_action", "fail;retry;nothing", "What to do if check fails?", "retry"), -                  ("max_tries", "int", "Number of retries", 2), -                  ("retry_action", "fail;nothing", "What to do if all retries fail?", "fail"), -                  ("wait_time", "int", "Time to wait before each retry (seconds)", 1)] - -    __description__ = """Verify downloaded file size and checksum""" -    __license__     = "GPLv3" -    __authors__     = [("zoidberg"      , "zoidberg@mujmail.cz"), -                       ("Walter Purcaro", "vuolter@gmail.com"  ), -                       ("stickell"      , "l.stickell@yahoo.it")] - - -    interval = 0  #@TODO: Remove in 0.4.10 -    methods  = {'sfv' : 'crc32', -                'crc' : 'crc32', -                'hash': 'md5'} -    regexps  = {'sfv'    : r'^(?P<NAME>[^;].+)\s+(?P<HASH>[0-9A-Fa-f]{8})$', -                'md5'    : r'^(?P<NAME>[0-9A-Fa-f]{32})  (?P<FILE>.+)$', -                'crc'    : r'filename=(?P<NAME>.+)\nsize=(?P<SIZE>\d+)\ncrc32=(?P<HASH>[0-9A-Fa-f]{8})$', -                'default': r'^(?P<HASH>[0-9A-Fa-f]+)\s+\*?(?P<NAME>.+)$'} - - -    def coreReady(self): -        if not self.getConfig('check_checksum'): -            self.logInfo(_("Checksum validation is disabled in plugin configuration")) - - -    def setup(self): -        self.info       = {}  #@TODO: Remove in 0.4.10 -        self.algorithms = sorted( -            getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse=True) - -        self.algorithms.extend(["crc32", "adler32"]) - -        self.formats = self.algorithms + ["sfv", "crc", "hash"] - - -    def downloadFinished(self, pyfile): -        """ -        Compute checksum for the downloaded file and compare it with the hash provided by the hoster. -        pyfile.plugin.check_data should be a dictionary which can contain: -        a) if known, the exact filesize in bytes (e.g. "size": 123456789) -        b) hexadecimal hash string with algorithm name as key (e.g. "md5": "d76505d0869f9f928a17d42d66326307") -        """ -        if hasattr(pyfile.plugin, "check_data") and isinstance(pyfile.plugin.check_data, dict): -            data = pyfile.plugin.check_data.copy() - -        elif hasattr(pyfile.plugin, "api_data") and isinstance(pyfile.plugin.api_data, dict): -            data = pyfile.plugin.api_data.copy() - -        elif hasattr(pyfile.plugin, "info") and isinstance(pyfile.plugin.info, dict): -            data = pyfile.plugin.info.copy() -            data.pop('size', None)  #@NOTE: Don't check file size until a similary matcher will be implemented - -        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 os.path.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 = os.path.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") - -            data.pop('size', None) - -        # validate checksum -        if data and self.getConfig('check_checksum'): - -            if not 'md5' in data: -                for type in ("checksum", "hashsum", "hash"): -                    if type in data: -                        data['md5'] = data[type]  #@NOTE: What happens if it's not an md5 hash? -                        break - -            for key in self.algorithms: -                if key in data: -                    checksum = computeChecksum(local_file, key.replace("-", "").lower()) -                    if checksum: -                        if checksum == data[key].lower(): -                            self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') % -                                        (pyfile.name, key.upper(), checksum)) -                            break -                        else: -                            self.logWarning(_("%s checksum for file %s does not match (%s != %s)") % -                                           (key.upper(), pyfile.name, checksum, data[key])) -                            self.checkFailed(pyfile, local_file, "Checksums do not match") -                    else: -                        self.logWarning(_("Unsupported hashing algorithm"), key.upper()) -            else: -                self.logWarning(_("Unable to validate checksum for file: ") + pyfile.name) - - -    def checkFailed(self, pyfile, local_file, msg): -        check_action = self.getConfig('check_action') -        if check_action == "retry": -            max_tries = self.getConfig('max_tries') -            retry_action = self.getConfig('retry_action') -            if pyfile.plugin.retries < max_tries: -                if local_file: -                    os.remove(local_file) -                pyfile.plugin.retry(max_tries, self.getConfig('wait_time'), msg) -            elif retry_action == "nothing": -                return -        elif check_action == "nothing": -            return -        pyfile.plugin.fail(reason=msg) - - -    def packageFinished(self, pypack): -        download_folder = save_join(self.config['general']['download_folder'], pypack.folder, "") - -        for link in pypack.getChildren().itervalues(): -            file_type = os.path.splitext(link['name'])[1][1:].lower() - -            if file_type not in self.formats: -                continue - -            hash_file = fs_encode(save_join(download_folder, link['name'])) -            if not os.path.isfile(hash_file): -                self.logWarning(_("File not found"), link['name']) -                continue - -            with open(hash_file) as f: -                text = f.read() - -            for m in re.finditer(self.regexps.get(file_type, self.regexps['default']), text): -                data = m.groupdict() -                self.logDebug(link['name'], data) - -                local_file = fs_encode(save_join(download_folder, data['NAME'])) -                algorithm = self.methods.get(file_type, file_type) -                checksum = computeChecksum(local_file, algorithm) -                if checksum == data['HASH']: -                    self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') % -                                (data['NAME'], algorithm, checksum)) -                else: -                    self.logWarning(_("%s checksum for file %s does not match (%s != %s)") % -                                   (algorithm, data['NAME'], checksum, data['HASH'])) diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py deleted file mode 100644 index 2ddd66daa..000000000 --- a/module/plugins/hooks/ClickAndLoad.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- - -import socket -import time - -from threading import Lock - -from module.plugins.Hook import Hook, threaded - - -def forward(source, destination): -    try: -        bufsize = 1024 -        bufdata = source.recv(bufsize) -        while bufdata: -            destination.sendall(bufdata) -            bufdata = source.recv(bufsize) -    finally: -        destination.shutdown(socket.SHUT_WR) -        # destination.close() - - -#@TODO: IPv6 support -class ClickAndLoad(Hook): -    __name__    = "ClickAndLoad" -    __type__    = "hook" -    __version__ = "0.41" - -    __config__ = [("activated", "bool", "Activated"                             , True), -                  ("port"     , "int" , "Port"                                  , 9666), -                  ("extern"   , "bool", "Listen on the public network interface", True)] - -    __description__ = """Click'n'Load hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"         , "RaNaN@pyload.de"  ), -                       ("Walter Purcaro", "vuolter@gmail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def coreReady(self): -        if not self.config['webinterface']['activated']: -            return - -        ip      = "" if self.getConfig('extern') else "127.0.0.1" -        webport = self.config['webinterface']['port'] -        cnlport = self.getConfig('port') - -        self.proxy(ip, webport, cnlport) - - -    @threaded -    def proxy(self, ip, webport, cnlport): -        time.sleep(10)  #@TODO: Remove in 0.4.10 (implement addon delay on startup) - -        self.logInfo(_("Proxy listening on %s:%s") % (ip or "0.0.0.0", cnlport)) - -        self._server(ip, webport, cnlport) - -        lock = Lock() -        lock.acquire() -        lock.acquire() - - -    @threaded -    def _server(self, ip, webport, cnlport): -        try: -            dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -            dock_socket.bind((ip, cnlport)) -            dock_socket.listen(5) - -            while True: -                client_socket, client_addr = dock_socket.accept() -                self.logDebug("Connection from %s:%s" % client_addr) - -                server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -                server_socket.connect(("127.0.0.1", webport)) - -                self.manager.startThread(forward, client_socket, server_socket) -                self.manager.startThread(forward, server_socket, client_socket) - -        except socket.timeout: -            self.logDebug("Connection timed out, retrying...") -            return self._server(ip, webport, cnlport) - -        except socket.error, e: -            self.logError(e) -            time.sleep(240) -            return self._server(ip, webport, cnlport) diff --git a/module/plugins/hooks/DeathByCaptcha.py b/module/plugins/hooks/DeathByCaptcha.py deleted file mode 100644 index f9618f011..000000000 --- a/module/plugins/hooks/DeathByCaptcha.py +++ /dev/null @@ -1,220 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import pycurl -import re -import time - -from base64 import b64encode - -from module.common.json_layer import json_loads -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getRequest -from module.plugins.Hook import Hook, threaded - - -class DeathByCaptchaException(Exception): -    DBC_ERRORS = {'not-logged-in': 'Access denied, check your credentials', -                  'invalid-credentials': 'Access denied, check your credentials', -                  'banned': 'Access denied, account is suspended', -                  'insufficient-funds': 'Insufficient account balance to decrypt CAPTCHA', -                  'invalid-captcha': 'CAPTCHA is not a valid image', -                  'service-overload': 'CAPTCHA was rejected due to service overload, try again later', -                  'invalid-request': 'Invalid request', -                  'timed-out': 'No CAPTCHA solution received in time'} - - -    def __init__(self, err): -        self.err = err - - -    def getCode(self): -        return self.err - - -    def getDesc(self): -        if self.err in self.DBC_ERRORS.keys(): -            return self.DBC_ERRORS[self.err] -        else: -            return self.err - - -    def __str__(self): -        return "<DeathByCaptchaException %s>" % self.err - - -    def __repr__(self): -        return "<DeathByCaptchaException %s>" % self.err - - -class DeathByCaptcha(Hook): -    __name__    = "DeathByCaptcha" -    __type__    = "hook" -    __version__ = "0.06" - -    __config__ = [("username", "str", "Username", ""), -                  ("passkey", "password", "Password", ""), -                  ("force", "bool", "Force DBC even if client is connected", False)] - -    __description__ = """Send captchas to DeathByCaptcha.com""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"   , "RaNaN@pyload.org"   ), -                       ("zoidberg", "zoidberg@mujmail.cz")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - -    API_URL = "http://api.dbcapi.me/api/" - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def api_response(self, api="captcha", post=False, multipart=False): -        req = getRequest() -        req.c.setopt(pycurl.HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.core.version]) - -        if post: -            if not isinstance(post, dict): -                post = {} -            post.update({"username": self.getConfig('username'), -                         "password": self.getConfig('passkey')}) - -        res = None -        try: -            json = req.load("%s%s" % (self.API_URL, api), -                            post=post, -                            multipart=multipart) -            self.logDebug(json) -            res = json_loads(json) - -            if "error" in res: -                raise DeathByCaptchaException(res['error']) -            elif "status" not in res: -                raise DeathByCaptchaException(str(res)) - -        except BadHeader, e: -            if 403 == e.code: -                raise DeathByCaptchaException('not-logged-in') -            elif 413 == e.code: -                raise DeathByCaptchaException('invalid-captcha') -            elif 503 == e.code: -                raise DeathByCaptchaException('service-overload') -            elif e.code in (400, 405): -                raise DeathByCaptchaException('invalid-request') -            else: -                raise - -        finally: -            req.close() - -        return res - - -    def getCredits(self): -        res = self.api_response("user", True) - -        if 'is_banned' in res and res['is_banned']: -            raise DeathByCaptchaException('banned') -        elif 'balance' in res and 'rate' in res: -            self.info.update(res) -        else: -            raise DeathByCaptchaException(res) - - -    def getStatus(self): -        res = self.api_response("status", False) - -        if 'is_service_overloaded' in res and res['is_service_overloaded']: -            raise DeathByCaptchaException('service-overload') - - -    def submit(self, captcha, captchaType="file", match=None): -        #@NOTE: Workaround multipart-post bug in HTTPRequest.py -        if re.match("^\w*$", self.getConfig('passkey')): -            multipart = True -            data = (pycurl.FORM_FILE, captcha) -        else: -            multipart = False -            with open(captcha, 'rb') as f: -                data = f.read() -            data = "base64:" + b64encode(data) - -        res = self.api_response("captcha", {"captchafile": data}, multipart) - -        if "captcha" not in res: -            raise DeathByCaptchaException(res) -        ticket = res['captcha'] - -        for _i in xrange(24): -            time.sleep(5) -            res = self.api_response("captcha/%d" % ticket, False) -            if res['text'] and res['is_correct']: -                break -        else: -            raise DeathByCaptchaException('timed-out') - -        result = res['text'] -        self.logDebug("Result %s : %s" % (ticket, result)) - -        return ticket, result - - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False - -        if not task.isTextual(): -            return False - -        if not self.getConfig('username') or not self.getConfig('passkey'): -            return False - -        if self.core.isClientConnected() and not self.getConfig('force'): -            return False - -        try: -            self.getStatus() -            self.getCredits() -        except DeathByCaptchaException, e: -            self.logError(e.getDesc()) -            return False - -        balance, rate = self.info['balance'], self.info['rate'] -        self.logInfo(_("Account balance"), -                     _("US$%.3f (%d captchas left at %.2f cents each)") % (balance / 100, -                                                                           balance // rate, rate)) - -        if balance > rate: -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(180) -            self._processCaptcha(task) - - -    def captchaInvalid(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            try: -                res = self.api_response("captcha/%d/report" % task.data['ticket'], True) - -            except DeathByCaptchaException, e: -                self.logError(e.getDesc()) - -            except Exception, e: -                self.logError(e) - - -    @threaded -    def _processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except DeathByCaptchaException, e: -            task.error = e.getCode() -            self.logError(e.getDesc()) -            return - -        task.data['ticket'] = ticket -        task.setResult(result) diff --git a/module/plugins/hooks/DebridItaliaComHook.py b/module/plugins/hooks/DebridItaliaComHook.py deleted file mode 100644 index 36b307696..000000000 --- a/module/plugins/hooks/DebridItaliaComHook.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.internal.MultiHook import MultiHook - - -class DebridItaliaComHook(MultiHook): -    __name__    = "DebridItaliaComHook" -    __type__    = "hook" -    __version__ = "0.12" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Debriditalia.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("stickell"      , "l.stickell@yahoo.it"), -                       ("Walter Purcaro", "vuolter@gmail.com"  )] - - -    def getHosters(self): -        return self.getURL("http://debriditalia.com/api.php", get={'hosts': ""}).replace('"', '').split(',') diff --git a/module/plugins/hooks/DeleteFinished.py b/module/plugins/hooks/DeleteFinished.py deleted file mode 100644 index bde4ca259..000000000 --- a/module/plugins/hooks/DeleteFinished.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.database import style -from module.plugins.Hook import Hook - - -class DeleteFinished(Hook): -    __name__    = "DeleteFinished" -    __type__    = "hook" -    __version__ = "1.12" - -    __config__ = [("interval"  , "int" , "Check interval in hours"          , 72   ), -                  ("deloffline", "bool", "Delete package with offline links", False)] - -    __description__ = """Automatically delete all finished packages from queue""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    # event_list = ["pluginConfigChanged"] - -    MIN_CHECK_INTERVAL = 1 * 60 * 60  #: 1 hour - - -    ## overwritten methods ## -    def setup(self): -        self.info     = {}  #@TODO: Remove in 0.4.10 -        self.interval = self.MIN_CHECK_INTERVAL - - -    def periodical(self): -        if not self.info['sleep']: -            deloffline = self.getConfig('deloffline') -            mode = '0,1,4' if deloffline else '0,4' -            msg = _('delete all finished packages in queue list (%s packages with offline links)') -            self.logInfo(msg % (_('including') if deloffline else _('excluding'))) -            self.deleteFinished(mode) -            self.info['sleep'] = True -            self.addEvent('packageFinished', self.wakeup) - - -    # def pluginConfigChanged(self, plugin, name, value): -        # if name == "interval" and value != self.interval: -            # self.interval = value * 3600 -            # self.initPeriodical() - - -    def unload(self): -        self.manager.removeEvent('packageFinished', self.wakeup) - - -    def coreReady(self): -        self.info['sleep'] = True -        # interval = self.getConfig('interval') -        # self.pluginConfigChanged(self.__name__, 'interval', interval) -        self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60 * 60) -        self.addEvent('packageFinished', self.wakeup) - - -    ## own methods ## -    @style.queue -    def deleteFinished(self, mode): -        self.c.execute('DELETE FROM packages WHERE NOT EXISTS(SELECT 1 FROM links WHERE package=packages.id AND status NOT IN (%s))' % mode) -        self.c.execute('DELETE FROM links WHERE NOT EXISTS(SELECT 1 FROM packages WHERE id=links.package)') - - -    def wakeup(self, pypack): -        self.manager.removeEvent('packageFinished', self.wakeup) -        self.info['sleep'] = False - - -    ## event managing ## -    def addEvent(self, event, func): -        """Adds an event listener for event name""" -        if event in self.manager.events: -            if func in self.manager.events[event]: -                self.logDebug("Function already registered", func) -            else: -                self.manager.events[event].append(func) -        else: -            self.manager.events[event] = [func] diff --git a/module/plugins/hooks/DownloadScheduler.py b/module/plugins/hooks/DownloadScheduler.py deleted file mode 100644 index 9c74ac1d4..000000000 --- a/module/plugins/hooks/DownloadScheduler.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import time - -from module.plugins.Hook import Hook - - -class DownloadScheduler(Hook): -    __name__    = "DownloadScheduler" -    __type__    = "hook" -    __version__ = "0.22" - -    __config__ = [("timetable", "str", "List time periods as hh:mm full or number(kB/s)", -                   "0:00 full, 7:00 250, 10:00 0, 17:00 150"), -                  ("abort", "bool", "Abort active downloads when start period with speed 0", False)] - -    __description__ = """Download Scheduler""" -    __license__     = "GPLv3" -    __authors__     = [("zoidberg", "zoidberg@mujmail.cz"), -                       ("stickell", "l.stickell@yahoo.it")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info = {}    #@TODO: Remove in 0.4.10 -        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  = time.localtime() -        now = (t0.tm_hour, t0.tm_min, t0.tm_sec, "X") -        schedule = sorted([(int(x[0]), int(x[1]), 0, int(x[2])) for x in schedule] + [now]) - -        self.logDebug("Schedule", schedule) - -        for i, v in enumerate(schedule): -            if v[3] == "X": -                last, next = schedule[i - 1], schedule[(i + 1) % len(schedule)] -                self.logDebug("Now/Last/Next", now, last, next) - -                self.setDownloadSpeed(last[3]) - -                next_time = (((24 + next[0] - now[0]) * 60 + next[1] - now[1]) * 60 + next[2] - now[2]) % 86400 -                self.core.scheduler.removeJob(self.cb) -                self.cb = self.core.scheduler.addJob(next_time, self.updateSchedule, threaded=False) - - -    def setDownloadSpeed(self, speed): -        if speed == 0: -            abort = self.getConfig('abort') -            self.logInfo(_("Stopping download server. (Running downloads will %sbe aborted.)") % '' if abort else _('not ')) -            self.core.api.pauseServer() -            if abort: -                self.core.api.stopAllDownloads() -        else: -            self.core.api.unpauseServer() - -            if speed > 0: -                self.logInfo(_("Setting download speed to %d kB/s") % speed) -                self.core.api.setConfigValue("download", "limit_speed", 1) -                self.core.api.setConfigValue("download", "max_speed", speed) -            else: -                self.logInfo(_("Setting download speed to FULL")) -                self.core.api.setConfigValue("download", "limit_speed", 0) -                self.core.api.setConfigValue("download", "max_speed", -1) diff --git a/module/plugins/hooks/EasybytezComHook.py b/module/plugins/hooks/EasybytezComHook.py deleted file mode 100644 index 43efb5048..000000000 --- a/module/plugins/hooks/EasybytezComHook.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.internal.MultiHook import MultiHook - - -class EasybytezComHook(MultiHook): -    __name__    = "EasybytezComHook" -    __type__    = "hook" -    __version__ = "0.07" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """EasyBytez.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("zoidberg", "zoidberg@mujmail.cz")] - - -    def getHosters(self): -        user, data = self.account.selectAccount() - -        req  = self.account.getAccountRequest(user) -        html = req.load("http://www.easybytez.com") - -        return re.search(r'</textarea>\s*Supported sites:(.*)', html).group(1).split(',') diff --git a/module/plugins/hooks/ExpertDecoders.py b/module/plugins/hooks/ExpertDecoders.py deleted file mode 100644 index ccd48f664..000000000 --- a/module/plugins/hooks/ExpertDecoders.py +++ /dev/null @@ -1,103 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import pycurl -import uuid - -from base64 import b64encode - -from module.network.HTTPRequest import BadHeader -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook, threaded - - -class ExpertDecoders(Hook): -    __name__    = "ExpertDecoders" -    __type__    = "hook" -    __version__ = "0.04" - -    __config__ = [("force", "bool", "Force CT even if client is connected", False), -                  ("passkey", "password", "Access key", "")] - -    __description__ = """Send captchas to expertdecoders.com""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"   , "RaNaN@pyload.org"   ), -                       ("zoidberg", "zoidberg@mujmail.cz")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - -    API_URL = "http://www.fasttypers.org/imagepost.ashx" - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def getCredits(self): -        res = getURL(self.API_URL, post={"key": self.getConfig('passkey'), "action": "balance"}) - -        if res.isdigit(): -            self.logInfo(_("%s credits left") % res) -            self.info['credits'] = credits = int(res) -            return credits -        else: -            self.logError(res) -            return 0 - - -    @threaded -    def _processCaptcha(self, task): -        task.data['ticket'] = ticket = uuid.uuid4() -        result = None - -        with open(task.captchaFile, 'rb') as f: -            data = f.read() - -        req = getRequest() -        #raise timeout threshold -        req.c.setopt(pycurl.LOW_SPEED_TIME, 80) - -        try: -            result = req.load(self.API_URL, -                              post={'action'     : "upload", -                                    'key'        : self.getConfig('passkey'), -                                    'file'       : b64encode(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) -            self._processCaptcha(task) - -        else: -            self.logInfo(_("Your ExpertDecoders Account has not enough credits")) - - -    def captchaInvalid(self, task): -        if "ticket" in task.data: - -            try: -                res = getURL(self.API_URL, -                             post={'action': "refund", 'key': self.getConfig('passkey'), 'gen_task_id': task.data['ticket']}) -                self.logInfo(_("Request refund"), res) - -            except BadHeader, e: -                self.logError(_("Could not send refund request"), e) diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py deleted file mode 100644 index be0857009..000000000 --- a/module/plugins/hooks/ExternalScripts.py +++ /dev/null @@ -1,217 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import subprocess - -from module.plugins.Hook import Hook -from module.utils import fs_encode, save_join - - -class ExternalScripts(Hook): -    __name__    = "ExternalScripts" -    __type__    = "hook" -    __version__ = "0.39" - -    __config__ = [("activated", "bool", "Activated"         , True ), -                  ("waitend"  , "bool", "Wait script ending", False)] - -    __description__ = """Run external scripts""" -    __license__     = "GPLv3" -    __authors__     = [("mkaay"         , "mkaay@mkaay.de"   ), -                       ("RaNaN"         , "ranan@pyload.org" ), -                       ("spoob"         , "spoob@pyload.org" ), -                       ("Walter Purcaro", "vuolter@gmail.com")] - - -    event_list = ["archive_extract_failed", "archive_extracted"     , -                  "package_extract_failed", "package_extracted"     , -                  "all_archives_extracted", "all_archives_processed", -                  "allDownloadsFinished"  , "allDownloadsProcessed" , -                  "packageDeleted"] -    interval   = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info    = {'oldip': None} -        self.scripts = {} - -        folders = ["pyload_start", "pyload_restart", "pyload_stop", -                   "before_reconnect", "after_reconnect", -                   "download_preparing", "download_failed", "download_finished", -                   "archive_extract_failed", "archive_extracted", -                   "package_finished", "package_deleted", "package_extract_failed", "package_extracted", -                   "all_downloads_processed", "all_downloads_finished",  #@TODO: Invert `all_downloads_processed`, `all_downloads_finished` order in 0.4.10 -                   "all_archives_extracted", "all_archives_processed"] - -        for folder in folders: -            self.scripts[folder] = [] -            for dir in (pypath, ''): -                self.initPluginType(folder, os.path.join(dir, 'scripts', folder)) - -        for script_type, names in self.scripts.iteritems(): -            if names: -                self.logInfo(_("Installed scripts for: ") + script_type, ", ".join(map(os.path.basename, names))) - -        self.pyload_start() - - -    def initPluginType(self, name, dir): -        if not os.path.isdir(dir): -            try: -                os.makedirs(dir) - -            except OSError, e: -                self.logDebug(e) -                return - -        for filename in os.listdir(dir): -            file = save_join(dir, filename) - -            if not os.path.isfile(file): -                continue - -            if filename[0] in ("#", "_") or filename.endswith("~") or filename.endswith(".swp"): -                continue - -            if not os.access(file, os.X_OK): -                self.logWarning(_("Script not executable:") + " %s/%s" % (name, filename)) - -            self.scripts[name].append(file) - - -    def callScript(self, script, *args): -        try: -            cmd_args = [fs_encode(str(x) if not isinstance(x, basestring) else x) for x in args] -            cmd      = [script] + cmd_args - -            self.logDebug("Executing: %s" % os.path.abspath(script), "Args: " + ' '.join(cmd_args)) - -            p = subprocess.Popen(cmd, bufsize=-1)  #@NOTE: output goes to pyload -            if self.getConfig('waitend'): -                p.communicate() - -        except Exception, e: -            try: -                self.logError(_("Runtime error: %s") % os.path.abspath(script), e) -            except Exception: -                self.logError(_("Runtime error: %s") % os.path.abspath(script), _("Unknown error")) - - -    def pyload_start(self): -        for script in self.scripts['pyload_start']: -            self.callScript(script) - - -    def coreExiting(self): -        for script in self.scripts['pyload_restart' if self.core.do_restart else 'pyload_stop']: -            self.callScript(script) - - -    def beforeReconnecting(self, ip): -        for script in self.scripts['before_reconnect']: -            self.callScript(script, ip) -        self.info['oldip'] = ip - - -    def afterReconnecting(self, ip): -        for script in self.scripts['after_reconnect']: -            self.callScript(script, ip, self.info['oldip'])  #@TODO: Use built-in oldip in 0.4.10 - - -    def downloadPreparing(self, pyfile): -        for script in self.scripts['download_preparing']: -            self.callScript(script, pyfile.id, pyfile.name, None, pyfile.pluginname, pyfile.url) - - -    def downloadFailed(self, pyfile): -        if self.config['general']['folder_per_package']: -            download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) -        else: -            download_folder = self.config['general']['download_folder'] - -        for script in self.scripts['download_failed']: -            file = save_join(download_folder, pyfile.name) -            self.callScript(script, pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url) - - -    def downloadFinished(self, pyfile): -        if self.config['general']['folder_per_package']: -            download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) -        else: -            download_folder = self.config['general']['download_folder'] - -        for script in self.scripts['download_finished']: -            file = save_join(download_folder, pyfile.name) -            self.callScript(script, pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url) - - -    def archive_extract_failed(self, pyfile, archive): -        for script in self.scripts['archive_extract_failed']: -            self.callScript(script, pyfile.id, pyfile.name, archive.filename, archive.out, archive.files) - - -    def archive_extracted(self, pyfile, archive): -        for script in self.scripts['archive_extracted']: -            self.callScript(script, pyfile.id, pyfile.name, archive.filename, archive.out, archive.files) - - -    def packageFinished(self, pypack): -        if self.config['general']['folder_per_package']: -            download_folder = save_join(self.config['general']['download_folder'], pypack.folder) -        else: -            download_folder = self.config['general']['download_folder'] - -        for script in self.scripts['package_finished']: -            self.callScript(script, pypack.id, pypack.name, download_folder, pypack.password) - - -    def packageDeleted(self, pid): -        pack = self.core.api.getPackageInfo(pid) - -        if self.config['general']['folder_per_package']: -            download_folder = save_join(self.config['general']['download_folder'], pack.folder) -        else: -            download_folder = self.config['general']['download_folder'] - -        for script in self.scripts['package_deleted']: -            self.callScript(script, pack.id, pack.name, download_folder, pack.password) - - -    def package_extract_failed(self, pypack): -        if self.config['general']['folder_per_package']: -            download_folder = save_join(self.config['general']['download_folder'], pypack.folder) -        else: -            download_folder = self.config['general']['download_folder'] - -        for script in self.scripts['package_extract_failed']: -            self.callScript(script, pypack.id, pypack.name, download_folder, pypack.password) - - -    def package_extracted(self, pypack): -        if self.config['general']['folder_per_package']: -            download_folder = save_join(self.config['general']['download_folder'], pypack.folder) -        else: -            download_folder = self.config['general']['download_folder'] - -        for script in self.scripts['package_extracted']: -            self.callScript(script, pypack.id, pypack.name, download_folder) - - -    def allDownloadsFinished(self): -        for script in self.scripts['all_downloads_finished']: -            self.callScript(script) - - -    def allDownloadsProcessed(self): -        for script in self.scripts['all_downloads_processed']: -            self.callScript(script) - - -    def all_archives_extracted(self): -        for script in self.scripts['all_archives_extracted']: -            self.callScript(script) - - -    def all_archives_processed(self): -        for script in self.scripts['all_archives_processed']: -            self.callScript(script) diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py deleted file mode 100644 index 05a1e368a..000000000 --- a/module/plugins/hooks/ExtractArchive.py +++ /dev/null @@ -1,561 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import os -import sys -import traceback - -# monkey patch bug in python 2.6 and lower -# http://bugs.python.org/issue6122 , http://bugs.python.org/issue1236 , http://bugs.python.org/issue1731717 -if sys.version_info < (2, 7) and os.name != "nt": -    import errno -    import subprocess - -    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 - -    subprocess.Popen.wait = wait - -try: -    import send2trash -except ImportError: -    pass - -from copy import copy -if os.name != "nt": -    from grp import getgrnam -    from pwd import getpwnam - -from module.plugins.Hook import Hook, Expose, threaded -from module.plugins.internal.Extractor import ArchiveError, CRCError, PasswordError -from module.plugins.internal.SimpleHoster import replace_patterns -from module.utils import fs_encode, save_join, uniqify - - -class ArchiveQueue(object): - -    def __init__(self, plugin, storage): -        self.plugin  = plugin -        self.storage = storage - - -    def get(self): -        try: -            return [int(pid) for pid in self.plugin.getStorage("ExtractArchive:%s" % self.storage, "").decode('base64').split()] -        except Exception: -            return [] - - -    def set(self, value): -        if isinstance(value, list): -            item = str(value)[1:-1].replace(' ', '').replace(',', ' ') -        else: -            item = str(value).strip() -        return self.plugin.setStorage("ExtractArchive:%s" % self.storage, item.encode('base64')[:-1]) - - -    def delete(self): -        return self.plugin.delStorage("ExtractArchive:%s" % self.storage) - - -    def add(self, item): -        queue = self.get() -        if item not in queue: -            return self.set(queue + [item]) -        else: -            return True - - -    def remove(self, item): -        queue = self.get() -        try: -            queue.remove(item) - -        except ValueError: -            pass - -        if queue == []: -            return self.delete() - -        return self.set(queue) - - -class ExtractArchive(Hook): -    __name__    = "ExtractArchive" -    __type__    = "hook" -    __version__ = "1.42" - -    __config__ = [("activated"      , "bool"              , "Activated"                                 , True                                                                     ), -                  ("fullpath"       , "bool"              , "Extract with full paths"                   , True                                                                     ), -                  ("overwrite"      , "bool"              , "Overwrite files"                           , False                                                                    ), -                  ("keepbroken"     , "bool"              , "Try to extract broken archives"            , False                                                                    ), -                  ("repair"         , "bool"              , "Repair broken archives (RAR required)"     , False                                                                    ), -                  ("test"           , "bool"              , "Test archive before extracting"            , False                                                                    ), -                  ("usepasswordfile", "bool"              , "Use password file"                         , True                                                                     ), -                  ("passwordfile"   , "file"              , "Password file"                             , "archive_password.txt"                                                   ), -                  ("delete"         , "bool"              , "Delete archive after extraction"           , True                                                                     ), -                  ("deltotrash"     , "bool"              , "Move to trash (recycle bin) instead delete", True                                                                     ), -                  ("subfolder"      , "bool"              , "Create subfolder for each package"         , False                                                                    ), -                  ("destination"    , "folder"            , "Extract files to folder"                   , ""                                                                       ), -                  ("extensions"     , "str"               , "Extract archives ending with extension"    , "7z,bz2,bzip2,gz,gzip,lha,lzh,lzma,rar,tar,taz,tbz,tbz2,tgz,xar,xz,z,zip"), -                  ("excludefiles"   , "str"               , "Don't extract the following files"         , "*.nfo,*.DS_Store,index.dat,thumb.db"                                    ), -                  ("recursive"      , "bool"              , "Extract archives in archives"              , True                                                                     ), -                  ("waitall"        , "bool"              , "Run after all downloads was processed"     , False                                                                    ), -                  ("renice"         , "int"               , "CPU priority"                              , 0                                                                        )] - -    __description__ = """Extract different kind of archives""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com"), -                       ("Immenz"        , "immenz@gmx.net"   )] - - -    event_list = ["allDownloadsProcessed","packageDeleted"] - -    NAME_REPLACEMENTS = [(r'\.part\d+\.rar$', ".part.rar")] - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - -        self.queue  = ArchiveQueue(self, "Queue") -        self.failed = ArchiveQueue(self, "Failed") - -        self.interval    = 60 -        self.extracting  = False -        self.lastPackage = False -        self.extractors  = [] -        self.passwords   = [] -        self.repair      = False - - -    def coreReady(self): -        for p in ("UnRar", "SevenZip", "UnZip"): -            try: -                module = self.core.pluginManager.loadModule("internal", p) -                klass  = getattr(module, p) -                if klass.isUsable(): -                    self.extractors.append(klass) -                if klass.REPAIR: -                    self.repair = self.getConfig('repair') - -            except OSError, e: -                if e.errno == 2: -                    self.logWarning(_("No %s installed") % p) -                else: -                    self.logWarning(_("Could not activate: %s") % p, e) -                    if self.core.debug: -                        traceback.print_exc() - -            except Exception, e: -                self.logWarning(_("Could not activate: %s") % p, e) -                if self.core.debug: -                    traceback.print_exc() - -        if self.extractors: -            self.logDebug(*["Found %s %s" % (Extractor.__name__, Extractor.VERSION) for Extractor in self.extractors]) -            self.extractQueued()  #: Resume unfinished extractions -        else: -            self.logInfo(_("No Extract plugins activated")) - - -    @threaded -    def extractQueued(self, thread): -        packages = self.queue.get() -        while packages: -            if self.lastPackage:  #: called from allDownloadsProcessed -                self.lastPackage = False -                if self.extract(packages, thread):  #@NOTE: check only if all gone fine, no failed reporting for now -                    self.manager.dispatchEvent("all_archives_extracted") -                self.manager.dispatchEvent("all_archives_processed") -            else: -                if self.extract(packages, thread):  #@NOTE: check only if all gone fine, no failed reporting for now -                    pass - -            packages = self.queue.get()  #: check for packages added during extraction - - -    @Expose -    def extractPackage(self, *ids): -        """ Extract packages with given id""" -        for id in ids: -            self.queue.add(id) -        if not self.getConfig('waitall') and not self.extracting: -            self.extractQueued() - - -    def packageDeleted(self, pid): -        self.queue.remove(pid) - - -    def packageFinished(self, pypack): -        self.queue.add(pypack.id) -        if not self.getConfig('waitall') and not self.extracting: -            self.extractQueued() - - -    def allDownloadsProcessed(self): -        self.lastPackage = True -        if not self.extracting: -            self.extractQueued() - - -    @Expose -    def extract(self, ids, thread=None):  #@TODO: Use pypack, not pid to improve method usability -        if not ids: -            return False - -        self.extracting = True - -        processed = [] -        extracted = [] -        failed    = [] - -        toList = lambda string: string.replace(' ', '').replace(',', '|').replace(';', '|').split('|') - -        destination = self.getConfig('destination') -        subfolder   = self.getConfig('subfolder') -        fullpath    = self.getConfig('fullpath') -        overwrite   = self.getConfig('overwrite') -        renice      = self.getConfig('renice') -        recursive   = self.getConfig('recursive') -        delete      = self.getConfig('delete') -        keepbroken  = self.getConfig('keepbroken') - -        extensions   = [x.lstrip('.').lower() for x in toList(self.getConfig('extensions'))] -        excludefiles = toList(self.getConfig('excludefiles')) - -        if extensions: -            self.logDebug("Use for extensions: %s" % "|.".join(extensions)) - -        # reload from txt file -        self.reloadPasswords() - -        download_folder = self.config['general']['download_folder'] - -        # iterate packages -> extractors -> targets -        for pid in ids: -            pypack = self.core.files.getPackage(pid) - -            if not pypack: -                self.queue.remove(pid) -                continue - -            self.logInfo(_("Check package: %s") % pypack.name) - -            # determine output folder -            out = save_join(download_folder, pypack.folder, destination, "")  #: force trailing slash - -            if subfolder: -                out = save_join(out, pypack.folder) - -            if not os.path.exists(out): -                os.makedirs(out) - -            matched   = False -            success   = True -            files_ids = dict((pylink['name'],((save_join(download_folder, pypack.folder, pylink['name'])), pylink['id'], out)) for pylink \ -                        in sorted(pypack.getChildren().itervalues(), key=lambda k: k['name'])).values()  #: remove duplicates - -            # check as long there are unseen files -            while files_ids: -                new_files_ids = [] - -                if extensions: -                    files_ids = [(fname, fid, fout) for fname, fid, fout in files_ids \ -                                 if filter(lambda ext: fname.lower().endswith(ext), extensions)] - -                for Extractor in self.extractors: -                    targets = Extractor.getTargets(files_ids) -                    if targets: -                        self.logDebug("Targets for %s: %s" % (Extractor.__name__, targets)) -                        matched = True - -                    for fname, fid, fout in targets: -                        name = os.path.basename(fname) - -                        if not os.path.exists(fname): -                            self.logDebug(name, "File not found") -                            continue - -                        self.logInfo(name, _("Extract to: %s") % fout) -                        try: -                            pyfile  = self.core.files.getFile(fid) -                            archive = Extractor(self, -                                                fname, -                                                fout, -                                                fullpath, -                                                overwrite, -                                                excludefiles, -                                                renice, -                                                delete, -                                                keepbroken, -                                                fid) - -                            thread.addActive(pyfile) -                            archive.init() - -                            try: -                                new_files = self._extract(pyfile, archive, pypack.password) - -                            finally: -                                pyfile.setProgress(100) -                                thread.finishFile(pyfile) - -                        except Exception, e: -                            self.logError(name, e) -                            success = False -                            continue - -                        # remove processed file and related multiparts from list -                        files_ids = [(fname, fid, fout) for fname, fid, fout in files_ids \ -                                    if fname not in archive.getDeleteFiles()] -                        self.logDebug("Extracted files: %s" % new_files) -                        self.setPermissions(new_files) - -                        for filename in new_files: -                            file = fs_encode(save_join(os.path.dirname(archive.filename), filename)) -                            if not os.path.exists(file): -                                self.logDebug("New file %s does not exists" % filename) -                                continue - -                            if recursive and os.path.isfile(file): -                                new_files_ids.append((filename, fid, os.path.dirname(filename)))  #: append as new target - -                        self.manager.dispatchEvent("archive_extracted", pyfile, archive) - -                files_ids = new_files_ids  #: also check extracted files - -            if matched: -                if success: -                    extracted.append(pid) -                    self.manager.dispatchEvent("package_extracted", pypack) - -                else: -                    failed.append(pid) -                    self.manager.dispatchEvent("package_extract_failed", pypack) - -                    self.failed.add(pid) -            else: -                self.logInfo(_("No files found to extract")) - -            if not matched or not success and subfolder: -                try: -                    os.rmdir(out) - -                except OSError: -                    pass - -            self.queue.remove(pid) - -        self.extracting = False -        return True if not failed else False - - -    def _extract(self, pyfile, archive, password): -        name   = os.path.basename(archive.filename) - -        pyfile.setStatus("processing") - -        encrypted = False -        try: -            self.logDebug("Password: %s" % (password or "None provided")) -            passwords = uniqify([password] + self.getPasswords(False)) if self.getConfig('usepasswordfile') else [password] -            for pw in passwords: -                try: -                    if self.getConfig('test') or self.repair: -                        pyfile.setCustomStatus(_("archive testing")) -                        if pw: -                            self.logDebug("Testing with password: %s" % pw) -                        pyfile.setProgress(0) -                        archive.verify(pw) -                        pyfile.setProgress(100) -                    else: -                        archive.check(pw) - -                    self.addPassword(pw) -                    break - -                except PasswordError: -                    if not encrypted: -                        self.logInfo(name, _("Password protected")) -                        encrypted = True - -                except CRCError, e: -                    self.logDebug(name, e) -                    self.logInfo(name, _("CRC Error")) - -                    if self.repair: -                        self.logWarning(name, _("Repairing...")) - -                        pyfile.setCustomStatus(_("archive repairing")) -                        pyfile.setProgress(0) -                        repaired = archive.repair() -                        pyfile.setProgress(100) - -                        if not repaired and not self.getConfig('keepbroken'): -                            raise CRCError("Archive damaged") - -                        self.addPassword(pw) -                        break - -                    raise CRCError("Archive damaged") - -                except ArchiveError, e: -                    raise ArchiveError(e) - -            pyfile.setCustomStatus(_("extracting")) -            pyfile.setProgress(0) - -            if not encrypted or not self.getConfig('usepasswordfile'): -                self.logDebug("Extracting using password: %s" % (password or "None")) -                archive.extract(password) -            else: -                for pw in filter(None, uniqify([password] + self.getPasswords(False))): -                    try: -                        self.logDebug("Extracting using password: %s" % pw) - -                        archive.extract(pw) -                        self.addPassword(pw) -                        break - -                    except PasswordError: -                        self.logDebug("Password was wrong") -                else: -                    raise PasswordError - -            pyfile.setProgress(100) -            pyfile.setStatus("processing") - -            delfiles = archive.getDeleteFiles() -            self.logDebug("Would delete: " + ", ".join(delfiles)) - -            if self.getConfig('delete'): -                self.logInfo(_("Deleting %s files") % len(delfiles)) - -                deltotrash = self.getConfig('deltotrash') -                for f in delfiles: -                    file = fs_encode(f) -                    if not os.path.exists(file): -                        continue - -                    if not deltotrash: -                        os.remove(file) - -                    else: -                        try: -                            send2trash.send2trash(file) - -                        except Exception: -                            self.logWarning(_("Unable to move %s to trash") % os.path.basename(f)) - -            self.logInfo(name, _("Extracting finished")) -            extracted_files = archive.files or archive.list() - -            return extracted_files - -        except PasswordError: -            self.logError(name, _("Wrong password" if password else "No password found")) - -        except CRCError, e: -            self.logError(name, _("CRC mismatch"), e) - -        except ArchiveError, e: -            self.logError(name, _("Archive error"), e) - -        except Exception, e: -            self.logError(name, _("Unknown error"), e) -            if self.core.debug: -                traceback.print_exc() - -        self.manager.dispatchEvent("archive_extract_failed", pyfile, archive) - -        raise Exception(_("Extract failed")) - - -    @Expose -    def getPasswords(self, reload=True): -        """ List of saved passwords """ -        if reload: -            self.reloadPasswords() - -        return self.passwords - - -    def reloadPasswords(self): -        try: -            passwords = [] - -            file = fs_encode(self.getConfig('passwordfile')) -            with open(file) as f: -                for pw in f.read().splitlines(): -                    passwords.append(pw) - -        except IOError, e: -            self.logError(e) - -        else: -            self.passwords = passwords - - -    @Expose -    def addPassword(self, password): -        """  Adds a password to saved list""" -        try: -            self.passwords = uniqify([password] + self.passwords) - -            file = fs_encode(self.getConfig('passwordfile')) -            with open(file, "wb") as f: -                for pw in self.passwords: -                    f.write(pw + '\n') - -        except IOError, e: -            self.logError(e) - - -    def setPermissions(self, files): -        for f in files: -            if not os.path.exists(f): -                continue - -            try: -                if self.config['permission']['change_file']: -                    if os.path.isfile(f): -                        os.chmod(f, int(self.config['permission']['file'], 8)) - -                    elif os.path.isdir(f): -                        os.chmod(f, int(self.config['permission']['folder'], 8)) - -                if self.config['permission']['change_dl'] and os.name != "nt": -                    uid = getpwnam(self.config['permission']['user'])[2] -                    gid = getgrnam(self.config['permission']['group'])[2] -                    os.chown(f, uid, gid) - -            except Exception, e: -                self.logWarning(_("Setting User and Group failed"), e) diff --git a/module/plugins/hooks/FastixRuHook.py b/module/plugins/hooks/FastixRuHook.py deleted file mode 100644 index 16e30e93a..000000000 --- a/module/plugins/hooks/FastixRuHook.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class FastixRuHook(MultiHook): -    __name__    = "FastixRuHook" -    __type__    = "hook" -    __version__ = "0.05" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Fastix.ru hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Massimo Rosamilia", "max@spiritix.eu")] - - -    def getHosters(self): -        html = self.getURL("http://fastix.ru/api_v2", -                      get={'apikey': "5182964c3f8f9a7f0b00000a_kelmFB4n1IrnCDYuIFn2y", -                           'sub'   : "allowed_sources"}) -        host_list = json_loads(html) -        host_list = host_list['allow'] -        return host_list diff --git a/module/plugins/hooks/FreeWayMeHook.py b/module/plugins/hooks/FreeWayMeHook.py deleted file mode 100644 index baea44540..000000000 --- a/module/plugins/hooks/FreeWayMeHook.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class FreeWayMeHook(MultiHook): -    __name__    = "FreeWayMeHook" -    __type__    = "hook" -    __version__ = "0.15" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """FreeWay.me hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Nicolas Giese", "james@free-way.me")] - - -    def getHosters(self): -        # Get account data -        if not self.account or not self.account.canUse(): -           hostis = self.getURL("https://www.free-way.me/ajax/jd.php", get={"id": 3}).replace("\"", "").strip() -        else: -           self.logDebug("AccountInfo available - Get HosterList with User Pass") -           (user, data) = self.account.selectAccount() -           hostis = self.getURL("https://www.free-way.me/ajax/jd.php", get={"id": 3, "user": user, "pass": data['password']}).replace("\"", "").strip() - -        self.logDebug("hosters: %s" % hostis) -        return [x.strip() for x in hostis.split(",") if x.strip()] diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py deleted file mode 100644 index f771cf232..000000000 --- a/module/plugins/hooks/HotFolder.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import os -import time - -from shutil import move - -from module.plugins.Hook import Hook -from module.utils import fs_encode, save_join - - -class HotFolder(Hook): -    __name__    = "HotFolder" -    __type__    = "hook" -    __version__ = "0.14" - -    __config__ = [("folder"    , "str" , "Folder to observe"    , "container"), -                  ("watch_file", "bool", "Observe link file"    , False      ), -                  ("keep"      , "bool", "Keep added containers", True       ), -                  ("file"      , "str" , "Link file"            , "links.txt")] - -    __description__ = """Observe folder and file for changes and add container and links""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN", "RaNaN@pyload.de")] - - -    def setup(self): -        self.info     = {}  #@TODO: Remove in 0.4.10 -        self.interval = 30 - - -    def periodical(self): -        folder = fs_encode(self.getConfig('folder')) -        file   = fs_encode(self.getConfig('file')) - -        try: -            if not os.path.isdir(os.path.join(folder, "finished")): -                os.makedirs(os.path.join(folder, "finished")) - -            if self.getConfig('watch_file'): -                with open(file, "a+") as f: -                    f.seek(0) -                    content = f.read().strip() - -                if content: -                    f = open(file, "wb") -                    f.close() - -                    name = "%s_%s.txt" % (file, time.strftime("%H-%M-%S_%d%b%Y")) - -                    with open(save_join(folder, "finished", name), "wb") as f: -                        f.write(content) - -                    self.core.api.addPackage(f.name, [f.name], 1) - -            for f in os.listdir(folder): -                path = os.path.join(folder, f) - -                if not os.path.isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."): -                    continue - -                newpath = os.path.join(folder, "finished", f if self.getConfig('keep') else "tmp_" + f) -                move(path, newpath) - -                self.logInfo(_("Added %s from HotFolder") % f) -                self.core.api.addPackage(f, [newpath], 1) - -        except (IOError, OSError), e: -            self.logError(e) diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py deleted file mode 100644 index 33fde3d20..000000000 --- a/module/plugins/hooks/IRCInterface.py +++ /dev/null @@ -1,433 +0,0 @@ -# -*- coding: utf-8 -*- - -import pycurl -import re -import socket -import ssl -import time -import traceback - -from select import select -from threading import Thread - -from module.Api import PackageDoesNotExists, FileDoesNotExists -from module.network.RequestFactory import getURL -from module.plugins.Hook import Hook -from module.utils import formatSize - - -class IRCInterface(Thread, Hook): -    __name__    = "IRCInterface" -    __type__    = "hook" -    __version__ = "0.13" - -    __config__ = [("host", "str", "IRC-Server Address", "Enter your server here!"), -                  ("port", "int", "IRC-Server Port", 6667), -                  ("ident", "str", "Clients ident", "pyload-irc"), -                  ("realname", "str", "Realname", "pyload-irc"), -                  ("ssl", "bool", "Use SSL", False), -                  ("nick", "str", "Nickname the Client will take", "pyLoad-IRC"), -                  ("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here!"), -                  ("info_file", "bool", "Inform about every file finished", False), -                  ("info_pack", "bool", "Inform about every package finished", True), -                  ("captcha", "bool", "Send captcha requests", True)] - -    __description__ = """Connect to irc and let owner perform different tasks""" -    __license__     = "GPLv3" -    __authors__     = [("Jeix", "Jeix@hasnomail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def __init__(self, core, manager): -        Thread.__init__(self) -        Hook.__init__(self, core, manager) -        self.setDaemon(True) - - -    def coreReady(self): -        self.abort = False -        self.more = [] -        self.new_package = {} - -        self.start() - - -    def packageFinished(self, pypack): -        try: -            if self.getConfig('info_pack'): -                self.response(_("Package finished: %s") % pypack.name) -        except Exception: -            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 Exception: -            pass - - -    def newCaptchaTask(self, task): -        if self.getConfig('captcha') and task.isTextual(): -            task.handler.append(self) -            task.setWaiting(60) - -            html = getURL("http://www.freeimagehosting.net/upload.php", -                          post={"attached": (pycurl.FORM_FILE, task.captchaFile)}, multipart=True) - -            url = re.search(r"\[img\]([^\[]+)\[/img\]\[/url\]", html).group(1) -            self.response(_("New Captcha Request: %s") % url) -            self.response(_("Answer with 'c %s text on the captcha'") % task.id) - - -    def run(self): -        # connect to IRC etc. -        self.sock = socket.socket() -        host = self.getConfig('host') -        self.sock.connect((host, self.getConfig('port'))) - -        if self.getConfig('ssl'): -            self.sock = ssl.wrap_socket(self.sock, cert_reqs=ssl.CERT_NONE)  #@TODO: support certificate - -        nick = self.getConfig('nick') -        self.sock.send("NICK %s\r\n" % nick) -        self.sock.send("USER %s %s bla :%s\r\n" % (nick, host, nick)) -        for t in self.getConfig('owner').split(): -            if t.strip().startswith("#"): -                self.sock.send("JOIN %s\r\n" % t.strip()) -        self.logInfo(_("Connected to"), host) -        self.logInfo(_("Switching to listening mode!")) -        try: -            self.main_loop() - -        except IRCError, ex: -            self.sock.send("QUIT :byebye\r\n") -            traceback.print_exc() -            self.sock.close() - - -    def main_loop(self): -        readbuffer = "" -        while True: -            time.sleep(1) -            fdset = select([self.sock], [], [], 0) -            if self.sock not in fdset[0]: -                continue - -            if self.abort: -                raise IRCError("quit") - -            readbuffer += self.sock.recv(1024) -            temp = readbuffer.split("\n") -            readbuffer = temp.pop() - -            for line in temp: -                line = line.rstrip() -                first = line.split() - -                if first[0] == "PING": -                    self.sock.send("PONG %s\r\n" % first[1]) - -                if first[0] == "ERROR": -                    raise IRCError(line) - -                msg = line.split(None, 3) -                if len(msg) < 4: -                    continue - -                msg = { -                    "origin": msg[0][1:], -                    "action": msg[1], -                    "target": msg[2], -                    "text": msg[3][1:] -                } - -                self.handle_events(msg) - - -    def handle_events(self, msg): -        if not msg['origin'].split("!", 1)[0] in self.getConfig('owner').split(): -            return - -        if msg['target'].split("!", 1)[0] != self.getConfig('nick'): -            return - -        if msg['action'] != "PRIVMSG": -            return - -        # HANDLE CTCP ANTI FLOOD/BOT PROTECTION -        if msg['text'] == "\x01VERSION\x01": -            self.logDebug("Sending CTCP VERSION") -            self.sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface")) -            return -        elif msg['text'] == "\x01TIME\x01": -            self.logDebug("Sending CTCP TIME") -            self.sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time())) -            return -        elif msg['text'] == "\x01LAG\x01": -            self.logDebug("Received CTCP LAG")  #: don't know how to answer -            return - -        trigger = "pass" -        args = None - -        try: -            temp = msg['text'].split() -            trigger = temp[0] -            if len(temp) > 1: -                args = temp[1:] -        except Exception: -            pass - -        handler = getattr(self, "event_%s" % trigger, self.event_pass) -        try: -            res = handler(args) -            for line in res: -                self.response(line, msg['origin']) -        except Exception, e: -            self.logError(e) - - -    def response(self, msg, origin=""): -        if origin == "": -            for t in self.getConfig('owner').split(): -                self.sock.send("PRIVMSG %s :%s\r\n" % (t.strip(), msg)) -        else: -            self.sock.send("PRIVMSG %s :%s\r\n" % (origin.split("!", 1)[0], msg)) - - -        #### Events - -    def event_pass(self, args): -        return [] - - -    def event_status(self, args): -        downloads = self.core.api.statusDownloads() -        if not downloads: -            return ["INFO: There are no active downloads currently."] - -        temp_progress = "" -        lines = ["ID - Name - Status - Speed - ETA - Progress"] -        for data in downloads: - -            if data.status == 5: -                temp_progress = data.format_wait -            else: -                temp_progress = "%d%% (%s)" % (data.percent, data.format_size) - -            lines.append("#%d - %s - %s - %s - %s - %s" % -                         ( -                             data.fid, -                             data.name, -                             data.statusmsg, -                             "%s/s" % formatSize(data.speed), -                             "%s" % data.format_eta, -                             temp_progress -                         )) -        return lines - - -    def event_queue(self, args): -        ps = self.core.api.getQueueData() - -        if not ps: -            return ["INFO: There are no packages in queue."] - -        lines = [] -        for pack in ps: -            lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.links))) - -        return lines - - -    def event_collector(self, args): -        ps = self.core.api.getCollectorData() -        if not ps: -            return ["INFO: No packages in collector!"] - -        lines = [] -        for pack in ps: -            lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.links))) - -        return lines - - -    def event_info(self, args): -        if not args: -            return ["ERROR: Use info like this: info <id>"] - -        info = None -        try: -            info = self.core.api.getFileData(int(args[0])) - -        except FileDoesNotExists: -            return ["ERROR: Link doesn't exists."] - -        return ['LINK #%s: %s (%s) [%s][%s]' % (info.fid, info.name, info.format_size, info.statusmsg, info.plugin)] - - -    def event_packinfo(self, args): -        if not args: -            return ["ERROR: Use packinfo like this: packinfo <id>"] - -        lines = [] -        pack = None -        try: -            pack = self.core.api.getPackageData(int(args[0])) - -        except PackageDoesNotExists: -            return ["ERROR: Package doesn't exists."] - -        id = args[0] - -        self.more = [] - -        lines.append('PACKAGE #%s: "%s" with %d links' % (id, pack.name, len(pack.links))) -        for pyfile in pack.links: -            self.more.append('LINK #%s: %s (%s) [%s][%s]' % (pyfile.fid, pyfile.name, pyfile.format_size, -                                                             pyfile.statusmsg, pyfile.plugin)) - -        if len(self.more) < 6: -            lines.extend(self.more) -            self.more = [] -        else: -            lines.extend(self.more[:6]) -            self.more = self.more[6:] -            lines.append("%d more links do display." % len(self.more)) - -        return lines - - -    def event_more(self, args): -        if not self.more: -            return ["No more information to display."] - -        lines = self.more[:6] -        self.more = self.more[6:] -        lines.append("%d more links do display." % len(self.more)) - -        return lines - - -    def event_start(self, args): -        self.core.api.unpauseServer() -        return ["INFO: Starting downloads."] - - -    def event_stop(self, args): -        self.core.api.pauseServer() -        return ["INFO: No new downloads will be started."] - - -    def event_add(self, args): -        if len(args) < 2: -            return ['ERROR: Add links like this: "add <packagename|id> links". ', -                    "This will add the link <link> to to the package <package> / the package with id <id>!"] - -        pack = args[0].strip() -        links = [x.strip() for x in args[1:]] - -        count_added = 0 -        count_failed = 0 -        try: -            id = int(pack) -            pack = self.core.api.getPackageData(id) -            if not pack: -                return ["ERROR: Package doesn't exists."] - -            #TODO add links - -            return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack['name'], id)] - -        except Exception: -            # create new package -            id = self.core.api.addPackage(pack, links, 1) -            return ["INFO: Created new Package %s [#%d] with %d links." % (pack, id, len(links))] - - -    def event_del(self, args): -        if len(args) < 2: -            return ["ERROR: Use del command like this: del -p|-l <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] - -        if args[0] == "-p": -            ret = self.core.api.deletePackages(map(int, args[1:])) -            return ["INFO: Deleted %d packages!" % len(args[1:])] - -        elif args[0] == "-l": -            ret = self.core.api.delLinks(map(int, args[1:])) -            return ["INFO: Deleted %d links!" % len(args[1:])] - -        else: -            return ["ERROR: Use del command like this: del <-p|-l> <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] - - -    def event_push(self, args): -        if not args: -            return ["ERROR: Push package to queue like this: push <package id>"] - -        id = int(args[0]) -        try: -            info = self.core.api.getPackageInfo(id) -        except PackageDoesNotExists: -            return ["ERROR: Package #%d does not exist." % id] - -        self.core.api.pushToQueue(id) -        return ["INFO: Pushed package #%d to queue." % id] - - -    def event_pull(self, args): -        if not args: -            return ["ERROR: Pull package from queue like this: pull <package id>."] - -        id = int(args[0]) -        if not self.core.api.getPackageData(id): -            return ["ERROR: Package #%d does not exist." % id] - -        self.core.api.pullFromQueue(id) -        return ["INFO: Pulled package #%d from queue to collector." % id] - - -    def event_c(self, args): -        """ captcha answer """ -        if not args: -            return ["ERROR: Captcha ID missing."] - -        task = self.core.captchaManager.getTaskByID(args[0]) -        if not task: -            return ["ERROR: Captcha Task with ID %s does not exists." % args[0]] - -        task.setResult(" ".join(args[1:])) -        return ["INFO: Result %s saved." % " ".join(args[1:])] - - -    def event_help(self, args): -        lines = ["The following commands are available:", -                 "add <package|packid> <links> [...] Adds link to package. (creates new package if it does not exist)", -                 "queue                       Shows all packages in the queue", -                 "collector                   Shows all packages in collector", -                 "del -p|-l <id> [...]        Deletes all packages|links with the ids specified", -                 "info <id>                   Shows info of the link with id <id>", -                 "packinfo <id>               Shows info of the package with id <id>", -                 "more                        Shows more info when the result was truncated", -                 "start                       Starts all downloads", -                 "stop                        Stops the download (but not abort active downloads)", -                 "push <id>                   Push package to queue", -                 "pull <id>                   Pull package from queue", -                 "status                      Show general download status", -                 "help                        Shows this help message"] -        return lines - - -class IRCError(Exception): - -    def __init__(self, value): -        self.value = value - - -    def __str__(self): -        return repr(self.value) diff --git a/module/plugins/hooks/ImageTyperz.py b/module/plugins/hooks/ImageTyperz.py deleted file mode 100644 index f1fcacb71..000000000 --- a/module/plugins/hooks/ImageTyperz.py +++ /dev/null @@ -1,159 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import pycurl -import re - -from base64 import b64encode - -from module.network.RequestFactory import getURL, getRequest -from module.plugins.Hook import Hook, threaded - - -class ImageTyperzException(Exception): - -    def __init__(self, err): -        self.err = err - - -    def getCode(self): -        return self.err - - -    def __str__(self): -        return "<ImageTyperzException %s>" % self.err - - -    def __repr__(self): -        return "<ImageTyperzException %s>" % self.err - - -class ImageTyperz(Hook): -    __name__    = "ImageTyperz" -    __type__    = "hook" -    __version__ = "0.06" - -    __config__ = [("username", "str", "Username", ""), -                  ("passkey", "password", "Password", ""), -                  ("force", "bool", "Force IT even if client is connected", False)] - -    __description__ = """Send captchas to ImageTyperz.com""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"   , "RaNaN@pyload.org"   ), -                       ("zoidberg", "zoidberg@mujmail.cz")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - -    SUBMIT_URL = "http://captchatypers.com/Forms/UploadFileAndGetTextNEW.ashx" -    RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx" -    GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx" - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def getCredits(self): -        res = getURL(self.GETCREDITS_URL, -                     post={'action': "REQUESTBALANCE", -                           'username': self.getConfig('username'), -                           'password': self.getConfig('passkey')}) - -        if res.startswith('ERROR'): -            raise ImageTyperzException(res) - -        try: -            balance = float(res) -        except Exception: -            raise ImageTyperzException("Invalid response") - -        self.logInfo(_("Account balance: $%s left") % res) -        return balance - - -    def submit(self, captcha, captchaType="file", match=None): -        req = getRequest() -        #raise timeout threshold -        req.c.setopt(pycurl.LOW_SPEED_TIME, 80) - -        try: -            #@NOTE: Workaround multipart-post bug in HTTPRequest.py -            if re.match("^\w*$", self.getConfig('passkey')): -                multipart = True -                data = (pycurl.FORM_FILE, captcha) -            else: -                multipart = False -                with open(captcha, 'rb') as f: -                    data = f.read() -                data = b64encode(data) - -            res = req.load(self.SUBMIT_URL, -                           post={'action': "UPLOADCAPTCHA", -                                 'username': self.getConfig('username'), -                                 'password': self.getConfig('passkey'), "file": data}, -                           multipart=multipart) -        finally: -            req.close() - -        if res.startswith("ERROR"): -            raise ImageTyperzException(res) -        else: -            data = res.split('|') -            if len(data) == 2: -                ticket, result = data -            else: -                raise ImageTyperzException("Unknown response: %s" % res) - -        return ticket, result - - -    def newCaptchaTask(self, task): -        if "service" in task.data: -            return False - -        if not task.isTextual(): -            return False - -        if not self.getConfig('username') or not self.getConfig('passkey'): -            return False - -        if self.core.isClientConnected() and not self.getConfig('force'): -            return False - -        if self.getCredits() > 0: -            task.handler.append(self) -            task.data['service'] = self.__name__ -            task.setWaiting(100) -            self._processCaptcha(task) - -        else: -            self.logInfo(_("Your %s account has not enough credits") % self.__name__) - - -    def captchaInvalid(self, task): -        if task.data['service'] == self.__name__ and "ticket" in task.data: -            res = getURL(self.RESPOND_URL, -                         post={'action': "SETBADIMAGE", -                               'username': self.getConfig('username'), -                               'password': self.getConfig('passkey'), -                               'imageid': task.data['ticket']}) - -            if res == "SUCCESS": -                self.logInfo(_("Bad captcha solution received, requested refund")) -            else: -                self.logError(_("Bad captcha solution received, refund request failed"), res) - - -    @threaded -    def _processCaptcha(self, task): -        c = task.captchaFile -        try: -            ticket, result = self.submit(c) -        except ImageTyperzException, e: -            task.error = e.getCode() -            return - -        task.data['ticket'] = ticket -        task.setResult(result) diff --git a/module/plugins/hooks/JustPremium.py b/module/plugins/hooks/JustPremium.py deleted file mode 100644 index d18afc524..000000000 --- a/module/plugins/hooks/JustPremium.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.Hook import Hook - - -class JustPremium(Hook): -    __name__    = "JustPremium" -    __type__    = "hook" -    __version__ = "0.22" - -    __config__ = [("excluded", "str", "Exclude hosters (comma separated)", ""), -                  ("included", "str", "Include hosters (comma separated)", "")] - -    __description__ = """Remove not-premium links from added urls""" -    __license__     = "GPLv3" -    __authors__     = [("mazleu"        , "mazleica@gmail.com"), -                       ("Walter Purcaro", "vuolter@gmail.com" ), -                       ("immenz"        , "immenz@gmx.net"    )] - - -    event_list = ["linksAdded"] -    interval   = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def linksAdded(self, links, pid): -        hosterdict = self.core.pluginManager.hosterPlugins -        linkdict   = self.core.api.checkURLs(links) - -        premiumplugins = set(account.type for account in self.core.api.getAccounts(False) \ -                             if account.valid and account.premium) -        multihosters   = set(hoster for hoster in self.core.pluginManager.hosterPlugins \ -                             if 'new_name' in hosterdict[hoster] \ -                             and hosterdict[hoster]['new_name'] in premiumplugins) - -        excluded = map(lambda domain: "".join(part.capitalize() for part in re.split(r'(\.|\d+)', domain) if part != '.'), -                       self.getConfig('excluded').replace(' ', '').replace(',', '|').replace(';', '|').split('|')) -        included = map(lambda domain: "".join(part.capitalize() for part in re.split(r'(\.|\d+)', domain) if part != '.'), -                       self.getConfig('included').replace(' ', '').replace(',', '|').replace(';', '|').split('|')) - -        hosterlist = (premiumplugins | multihosters).union(excluded).difference(included) - -        #: Found at least one hoster with account or multihoster -        if not any( True for pluginname in linkdict if pluginname in hosterlist ): -            return - -        for pluginname in set(linkdict.keys()) - hosterlist: -            self.logInfo(_("Remove links of plugin: %s") % pluginname) -            for link in linkdict[pluginname]: -                self.logDebug("Remove link: %s" % link) -                links.remove(link) diff --git a/module/plugins/hooks/LinkdecrypterComHook.py b/module/plugins/hooks/LinkdecrypterComHook.py deleted file mode 100644 index 596a397a4..000000000 --- a/module/plugins/hooks/LinkdecrypterComHook.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.internal.MultiHook import MultiHook - - -class LinkdecrypterComHook(MultiHook): -    __name__    = "LinkdecrypterComHook" -    __type__    = "hook" -    __version__ = "1.04" - -    __config__ = [("activated"     , "bool"               , "Activated"                    , True ), -                  ("pluginmode"    , "all;listed;unlisted", "Use for plugins"              , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)", ""   ), -                  ("reload"        , "bool"               , "Reload plugin list"           , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"     , 12   )] - -    __description__ = """Linkdecrypter.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    def getCrypters(self): -        return re.search(r'>Supported\(\d+\)</b>: <i>(.[\w.\-, ]+)', -                         self.getURL("http://linkdecrypter.com/", decode=True).replace("(g)", "")).group(1).split(', ') diff --git a/module/plugins/hooks/LinksnappyComHook.py b/module/plugins/hooks/LinksnappyComHook.py deleted file mode 100644 index 72282575b..000000000 --- a/module/plugins/hooks/LinksnappyComHook.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class LinksnappyComHook(MultiHook): -    __name__    = "LinksnappyComHook" -    __type__    = "hook" -    __version__ = "0.04" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Linksnappy.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("stickell", "l.stickell@yahoo.it")] - - -    def getHosters(self): -        json_data = self.getURL("http://gen.linksnappy.com/lseAPI.php", get={'act': "FILEHOSTS"}) -        json_data = json_loads(json_data) - -        return json_data['return'].keys() diff --git a/module/plugins/hooks/MegaDebridEuHook.py b/module/plugins/hooks/MegaDebridEuHook.py deleted file mode 100644 index 0de7b4dcf..000000000 --- a/module/plugins/hooks/MegaDebridEuHook.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class MegaDebridEuHook(MultiHook): -    __name__    = "MegaDebridEuHook" -    __type__    = "hook" -    __version__ = "0.05" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Mega-debrid.eu hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("D.Ducatel", "dducatel@je-geek.fr")] - - -    def getHosters(self): -        reponse   = self.getURL("http://www.mega-debrid.eu/api.php", get={'action': "getHosters"}) -        json_data = json_loads(reponse) - -        if json_data['response_code'] == "ok": -            host_list = [element[0] for element in json_data['hosters']] -        else: -            self.logError(_("Unable to retrieve hoster list")) -            host_list = list() - -        return host_list diff --git a/module/plugins/hooks/MegaRapidoNetHook.py b/module/plugins/hooks/MegaRapidoNetHook.py deleted file mode 100644 index e113b305e..000000000 --- a/module/plugins/hooks/MegaRapidoNetHook.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.internal.MultiHook import MultiHook - - -class MegaRapidoNetHook(MultiHook): -    __name__    = "MegaRapidoNetHook" -    __type__    = "hook" -    __version__ = "0.02" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"              , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)", ""   ), -                  ("reload"        , "bool"               , "Reload plugin list"           , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"     , 12   )] - -    __description__ = """MegaRapido.net hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Kagenoshin", "kagenoshin@gmx.ch")] - - -    def getHosters(self): -        hosters = {'1fichier'    : [],#leave it there are so many possible addresses? -                   '1st-files'   : ['1st-files.com'], -                   '2shared'     : ['2shared.com'], -                   '4shared'     : ['4shared.com', '4shared-china.com'], -                   'asfile'      : ['http://asfile.com/'], -                   'bitshare'    : ['bitshare.com'], -                   'brupload'    : ['brupload.net'], -                   'crocko'      : ['crocko.com','easy-share.com'], -                   'dailymotion' : ['dailymotion.com'], -                   'depfile'     : ['depfile.com'], -                   'depositfiles': ['depositfiles.com', 'dfiles.eu'], -                   'dizzcloud'   : ['dizzcloud.com'], -                   'dl.dropbox'  : [], -                   'extabit'     : ['extabit.com'], -                   'extmatrix'   : ['extmatrix.com'], -                   'facebook'    : [], -                   'file4go'     : ['file4go.com'], -                   'filecloud'   : ['filecloud.io','ifile.it','mihd.net'], -                   'filefactory' : ['filefactory.com'], -                   'fileom'      : ['fileom.com'], -                   'fileparadox' : ['fileparadox.in'], -                   'filepost'    : ['filepost.com', 'fp.io'], -                   'filerio'     : ['filerio.in','filerio.com','filekeen.com'], -                   'filesflash'  : ['filesflash.com'], -                   'firedrive'   : ['firedrive.com', 'putlocker.com'], -                   'flashx'      : [], -                   'freakshare'  : ['freakshare.net', 'freakshare.com'], -                   'gigasize'    : ['gigasize.com'], -                   'hipfile'     : ['hipfile.com'], -                   'junocloud'   : ['junocloud.me'], -                   'letitbit'    : ['letitbit.net','shareflare.net'], -                   'mediafire'   : ['mediafire.com'], -                   'mega'        : ['mega.co.nz'], -                   'megashares'  : ['megashares.com'], -                   'metacafe'    : ['metacafe.com'], -                   'netload'     : ['netload.in'], -                   'oboom'       : ['oboom.com'], -                   'rapidgator'  : ['rapidgator.net'], -                   'rapidshare'  : ['rapidshare.com'], -                   'rarefile'    : ['rarefile.net'], -                   'ryushare'    : ['ryushare.com'], -                   'sendspace'   : ['sendspace.com'], -                   'turbobit'    : ['turbobit.net', 'unextfiles.com'], -                   'uploadable'  : ['uploadable.ch'], -                   'uploadbaz'   : ['uploadbaz.com'], -                   'uploaded'    : ['uploaded.to', 'uploaded.net', 'ul.to'], -                   'uploadhero'  : ['uploadhero.com'], -                   'uploading'   : ['uploading.com'], -                   'uptobox'     : ['uptobox.com'], -                   'xvideos'     : ['xvideos.com'], -                   'youtube'     : ['youtube.com']} - -        hoster_list = [] - -        for item in hosters.itervalues(): -            hoster_list.extend(item) - -        return hoster_list diff --git a/module/plugins/hooks/MergeFiles.py b/module/plugins/hooks/MergeFiles.py deleted file mode 100644 index 941938920..000000000 --- a/module/plugins/hooks/MergeFiles.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import os -import re -import traceback - -from module.plugins.Hook import Hook, threaded -from module.utils import save_join - - -class MergeFiles(Hook): -    __name__    = "MergeFiles" -    __type__    = "hook" -    __version__ = "0.14" - -    __config__ = [("activated", "bool", "Activated", True)] - -    __description__ = """Merges parts splitted with hjsplit""" -    __license__     = "GPLv3" -    __authors__     = [("and9000", "me@has-no-mail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - -    BUFFER_SIZE = 4096 - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    @threaded -    def packageFinished(self, pack): -        files = {} -        fid_dict = {} -        for fid, data in pack.getChildren().iteritems(): -            if re.search("\.\d{3}$", data['name']): -                if data['name'][:-4] not in files: -                    files[data['name'][:-4]] = [] -                files[data['name'][:-4]].append(data['name']) -                files[data['name'][:-4]].sort() -                fid_dict[data['name']] = fid - -        download_folder = self.config['general']['download_folder'] - -        if self.config['general']['folder_per_package']: -            download_folder = save_join(download_folder, pack.folder) - -        for name, file_list in files.iteritems(): -            self.logInfo(_("Starting merging of"), name) - -            with open(save_join(download_folder, name), "wb") as final_file: -                for splitted_file in file_list: -                    self.logDebug("Merging part", splitted_file) - -                    pyfile = self.core.files.getFile(fid_dict[splitted_file]) - -                    pyfile.setStatus("processing") - -                    try: -                        with open(save_join(download_folder, splitted_file), "rb") as s_file: -                            size_written = 0 -                            s_file_size = int(os.path.getsize(os.path.join(download_folder, splitted_file))) -                            while True: -                                f_buffer = s_file.read(self.BUFFER_SIZE) -                                if f_buffer: -                                    final_file.write(f_buffer) -                                    size_written += self.BUFFER_SIZE -                                    pyfile.setProgress((size_written * 100) / s_file_size) -                                else: -                                    break -                        self.logDebug("Finished merging part", splitted_file) - -                    except Exception, e: -                        traceback.print_exc() - -                    finally: -                        pyfile.setProgress(100) -                        pyfile.setStatus("finished") -                        pyfile.release() - -            self.logInfo(_("Finished merging of"), name) diff --git a/module/plugins/hooks/MultiHome.py b/module/plugins/hooks/MultiHome.py deleted file mode 100644 index a26d139c0..000000000 --- a/module/plugins/hooks/MultiHome.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- - -import time - -from module.plugins.Hook import Hook - - -class MultiHome(Hook): -    __name__    = "MultiHome" -    __type__    = "hook" -    __version__ = "0.12" - -    __config__ = [("interfaces", "str", "Interfaces", "None")] - -    __description__ = """Ip address changer""" -    __license__     = "GPLv3" -    __authors__     = [("mkaay", "mkaay@mkaay.de")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info       = {}  #@TODO: Remove in 0.4.10 -        self.register   = {} -        self.interfaces = [] - -        self.parseInterfaces(self.getConfig('interfaces').split(";")) - -        if not self.interfaces: -            self.parseInterfaces([self.config['download']['interface']]) -            self.setConfig("interfaces", self.toConfig()) - - -    def toConfig(self): -        return ";".join(i.adress for i in self.interfaces) - - -    def parseInterfaces(self, interfaces): -        for interface in interfaces: -            if not interface or str(interface).lower() == "none": -                continue -            self.interfaces.append(Interface(interface)) - - -    def coreReady(self): -        requestFactory = self.core.requestFactory -        oldGetRequest = requestFactory.getRequest - - -        def getRequest(pluginName, account=None): -            iface = self.bestInterface(pluginName, account) -            if iface: -                iface.useFor(pluginName, account) -                requestFactory.iface = lambda: iface.adress -                self.logDebug("Using address", iface.adress) -            return oldGetRequest(pluginName, account) - -        requestFactory.getRequest = getRequest - - -    def bestInterface(self, pluginName, account): -        best = None -        for interface in self.interfaces: -            if not best or interface.lastPluginAccess(pluginName, account) < best.lastPluginAccess(pluginName, account): -                best = interface -        return best - - -class Interface(object): - -    def __init__(self, adress): -        self.adress = adress -        self.history = {} - - -    def lastPluginAccess(self, pluginName, account): -        if (pluginName, account) in self.history: -            return self.history[(pluginName, account)] -        return 0 - - -    def useFor(self, pluginName, account): -        self.history[(pluginName, account)] = time.time() - - -    def __repr__(self): -        return "<Interface - %s>" % self.adress diff --git a/module/plugins/hooks/MultihostersComHook.py b/module/plugins/hooks/MultihostersComHook.py deleted file mode 100644 index 7b5e49c49..000000000 --- a/module/plugins/hooks/MultihostersComHook.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.hooks.ZeveraComHook import ZeveraComHook - - -class MultihostersComHook(ZeveraComHook): -    __name__    = "MultihostersComHook" -    __type__    = "hook" -    __version__ = "0.02" - -    __config__ = [("mode"        , "all;listed;unlisted", "Use for plugins (if supported)"               , "all"), -                  ("pluginlist"  , "str"                , "Plugin list (comma separated)"                , ""   ), -                  ("revertfailed", "bool"               , "Revert to standard download if download fails", False), -                  ("interval"    , "int"                , "Reload interval in hours (0 to disable)"      , 12   )] - -    __description__ = """Multihosters.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("tjeh", "tjeh@gmx.net")] diff --git a/module/plugins/hooks/MultishareCzHook.py b/module/plugins/hooks/MultishareCzHook.py deleted file mode 100644 index 6052b7673..000000000 --- a/module/plugins/hooks/MultishareCzHook.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.internal.MultiHook import MultiHook - - -class MultishareCzHook(MultiHook): -    __name__    = "MultishareCzHook" -    __type__    = "hook" -    __version__ = "0.07" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """MultiShare.cz hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("zoidberg", "zoidberg@mujmail.cz")] - - -    HOSTER_PATTERN = r'<img class="logo-shareserveru"[^>]*?alt="(.+?)"></td>\s*<td class="stav">[^>]*?alt="OK"' - - -    def getHosters(self): -        html = self.getURL("http://www.multishare.cz/monitoring/") -        return re.findall(self.HOSTER_PATTERN, html) diff --git a/module/plugins/hooks/MyfastfileComHook.py b/module/plugins/hooks/MyfastfileComHook.py deleted file mode 100644 index 20a1cfac2..000000000 --- a/module/plugins/hooks/MyfastfileComHook.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class MyfastfileComHook(MultiHook): -    __name__    = "MyfastfileComHook" -    __type__    = "hook" -    __version__ = "0.05" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Myfastfile.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("stickell", "l.stickell@yahoo.it")] - - -    def getHosters(self): -        json_data = self.getURL("http://myfastfile.com/api.php", get={'hosts': ""}, decode=True) -        self.logDebug("JSON data", json_data) -        json_data = json_loads(json_data) - -        return json_data['hosts'] diff --git a/module/plugins/hooks/NoPremiumPlHook.py b/module/plugins/hooks/NoPremiumPlHook.py deleted file mode 100644 index b5a007ff9..000000000 --- a/module/plugins/hooks/NoPremiumPlHook.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class NoPremiumPlHook(MultiHook): -    __name__    = "NoPremiumPlHook" -    __type__    = "hook" -    __version__ = "0.03" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """NoPremium.pl hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("goddie", "dev@nopremium.pl")] - - -    def getHosters(self): -        hostings         = json_loads(self.getURL("https://www.nopremium.pl/clipboard.php?json=3").strip()) -        hostings_domains = [domain for row in hostings for domain in row["domains"] if row["sdownload"] == "0"] - -        self.logDebug(hostings_domains) - -        return hostings_domains diff --git a/module/plugins/hooks/OverLoadMeHook.py b/module/plugins/hooks/OverLoadMeHook.py deleted file mode 100644 index d608a2ecd..000000000 --- a/module/plugins/hooks/OverLoadMeHook.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class OverLoadMeHook(MultiHook): -    __name__    = "OverLoadMeHook" -    __type__    = "hook" -    __version__ = "0.04" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   ), -                  ("ssl"           , "bool"               , "Use HTTPS"                           , True )] - -    __description__ = """Over-Load.me hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("marley", "marley@over-load.me")] - - -    def getHosters(self): -        https = "https" if self.getConfig('ssl') else "http" -        html = self.getURL(https + "://api.over-load.me/hoster.php", -                      get={'auth': "0001-cb1f24dadb3aa487bda5afd3b76298935329be7700cd7-5329be77-00cf-1ca0135f"}).replace("\"", "").strip() -        self.logDebug("Hosterlist", html) - -        return [x.strip() for x in html.split(",") if x.strip()] diff --git a/module/plugins/hooks/PremiumToHook.py b/module/plugins/hooks/PremiumToHook.py deleted file mode 100644 index ef2a84223..000000000 --- a/module/plugins/hooks/PremiumToHook.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class PremiumToHook(MultiHook): -    __name__    = "PremiumToHook" -    __type__    = "hook" -    __version__ = "0.08" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Premium.to hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN"   , "RaNaN@pyload.org"   ), -                       ("zoidberg", "zoidberg@mujmail.cz"), -                       ("stickell", "l.stickell@yahoo.it")] - - -    def getHosters(self): -        html = self.getURL("http://premium.to/api/hosters.php", -                      get={'username': self.account.username, 'password': self.account.password}) -        return [x.strip() for x in html.replace("\"", "").split(";")] diff --git a/module/plugins/hooks/PremiumizeMeHook.py b/module/plugins/hooks/PremiumizeMeHook.py deleted file mode 100644 index e081fb389..000000000 --- a/module/plugins/hooks/PremiumizeMeHook.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class PremiumizeMeHook(MultiHook): -    __name__    = "PremiumizeMeHook" -    __type__    = "hook" -    __version__ = "0.17" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Premiumize.me hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Florian Franzen", "FlorianFranzen@gmail.com")] - - -    def getHosters(self): -        # 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 = self.getURL("https://api.premiumize.me/pm-api/v1.php", -                        get={'method': "hosterlist", 'params[login]': user, 'params[pass]': data['password']}) -        data = json_loads(answer) - -        # If account is not valid thera are no hosters available -        if data['status'] != 200: -            return [] - -        # Extract hosters from json file -        return data['result']['hosterlist'] diff --git a/module/plugins/hooks/PutdriveComHook.py b/module/plugins/hooks/PutdriveComHook.py deleted file mode 100644 index c3ebf4ff3..000000000 --- a/module/plugins/hooks/PutdriveComHook.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.hooks.ZeveraComHook import ZeveraComHook - - -class PutdriveComHook(ZeveraComHook): -    __name__    = "PutdriveComHook" -    __type__    = "hook" -    __version__ = "0.01" - -    __config__ = [("mode"        , "all;listed;unlisted", "Use for plugins (if supported)"               , "all"), -                  ("pluginlist"  , "str"                , "Plugin list (comma separated)"                , ""   ), -                  ("revertfailed", "bool"               , "Revert to standard download if download fails", False), -                  ("interval"    , "int"                , "Reload interval in hours (0 to disable)"      , 12   )] - -    __description__ = """Putdrive.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] diff --git a/module/plugins/hooks/RPNetBizHook.py b/module/plugins/hooks/RPNetBizHook.py deleted file mode 100644 index 10332948d..000000000 --- a/module/plugins/hooks/RPNetBizHook.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class RPNetBizHook(MultiHook): -    __name__    = "RPNetBizHook" -    __type__    = "hook" -    __version__ = "0.14" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """RPNet.biz hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Dman", "dmanugm@gmail.com")] - - -    def getHosters(self): -        # Get account data -        user, data = self.account.selectAccount() - -        res = self.getURL("https://premium.rpnet.biz/client_api.php", -                     get={'username': user, 'password': data['password'], 'action': "showHosterList"}) -        hoster_list = json_loads(res) - -        # If account is not valid thera are no hosters available -        if 'error' in hoster_list: -            return [] - -        # Extract hosters from json file -        return hoster_list['hosters'] diff --git a/module/plugins/hooks/RapideoPlHook.py b/module/plugins/hooks/RapideoPlHook.py deleted file mode 100644 index 0400f07ba..000000000 --- a/module/plugins/hooks/RapideoPlHook.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class RapideoPlHook(MultiHook): -    __name__    = "RapideoPlHook" -    __type__    = "hook" -    __version__ = "0.03" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Rapideo.pl hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("goddie", "dev@rapideo.pl")] - - -    def getHosters(self): -        hostings         = json_loads(self.getURL("https://www.rapideo.pl/clipboard.php?json=3").strip()) -        hostings_domains = [domain for row in hostings for domain in row["domains"] if row["sdownload"] == "0"] - -        self.logDebug(hostings_domains) - -        return hostings_domains diff --git a/module/plugins/hooks/RealdebridComHook.py b/module/plugins/hooks/RealdebridComHook.py deleted file mode 100644 index aa0c9f640..000000000 --- a/module/plugins/hooks/RealdebridComHook.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class RealdebridComHook(MultiHook): -    __name__    = "RealdebridComHook" -    __type__    = "hook" -    __version__ = "0.46" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   ), -                  ("ssl"           , "bool"               , "Use HTTPS"                           , True )] - -    __description__ = """Real-Debrid.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Devirex Hazzard", "naibaf_11@yahoo.de")] - - -    def getHosters(self): -        https = "https" if self.getConfig('ssl') else "http" -        html = self.getURL(https + "://real-debrid.com/api/hosters.php").replace("\"", "").strip() - -        return [x.strip() for x in html.split(",") if x.strip()] diff --git a/module/plugins/hooks/RehostToHook.py b/module/plugins/hooks/RehostToHook.py deleted file mode 100644 index a2415129a..000000000 --- a/module/plugins/hooks/RehostToHook.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class RehostToHook(MultiHook): -    __name__    = "RehostToHook" -    __type__    = "hook" -    __version__ = "0.50" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Rehost.to hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN", "RaNaN@pyload.org")] - - -    def getHosters(self): -        user, data = self.account.selectAccount() -        html = self.getURL("http://rehost.to/api.php", -                           get={'cmd'     : "get_supported_och_dl", -                                'long_ses': self.account.getAccountInfo(user)['session']}) -        return [x.strip() for x in html.replace("\"", "").split(",")] diff --git a/module/plugins/hooks/RestartFailed.py b/module/plugins/hooks/RestartFailed.py deleted file mode 100644 index cab986d9e..000000000 --- a/module/plugins/hooks/RestartFailed.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.Hook import Hook - - -class RestartFailed(Hook): -    __name__    = "RestartFailed" -    __type__    = "hook" -    __version__ = "1.58" - -    __config__ = [("interval", "int", "Check interval in minutes", 90)] - -    __description__ = """Restart all the failed downloads in queue""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    # event_list = ["pluginConfigChanged"] - -    MIN_CHECK_INTERVAL = 15 * 60  #: 15 minutes - - -    # def pluginConfigChanged(self, plugin, name, value): -        # if name == "interval": -            # interval = value * 60 -            # if self.MIN_CHECK_INTERVAL <= interval != self.interval: -                # self.core.scheduler.removeJob(self.cb) -                # self.interval = interval -                # self.initPeriodical() -            # else: -                # self.logDebug("Invalid interval value, kept current") - - -    def periodical(self): -        self.logDebug(_("Restart failed downloads")) -        self.core.api.restartFailed() - - -    def setup(self): -        self.info     = {}  #@TODO: Remove in 0.4.10 -        self.interval = self.MIN_CHECK_INTERVAL - - -    def coreReady(self): -        # self.pluginConfigChanged(self.__name__, "interval", self.getConfig('interval')) -        self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60) diff --git a/module/plugins/hooks/SimplyPremiumComHook.py b/module/plugins/hooks/SimplyPremiumComHook.py deleted file mode 100644 index 116e3a76e..000000000 --- a/module/plugins/hooks/SimplyPremiumComHook.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class SimplyPremiumComHook(MultiHook): -    __name__    = "SimplyPremiumComHook" -    __type__    = "hook" -    __version__ = "0.05" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Simply-Premium.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("EvolutionClip", "evolutionclip@live.de")] - - -    def getHosters(self): -        json_data = self.getURL("http://www.simply-premium.com/api/hosts.php", get={'format': "json", 'online': 1}) -        json_data = json_loads(json_data) - -        host_list = [element['regex'] for element in json_data['result']] - -        return host_list diff --git a/module/plugins/hooks/SimplydebridComHook.py b/module/plugins/hooks/SimplydebridComHook.py deleted file mode 100644 index 01629df99..000000000 --- a/module/plugins/hooks/SimplydebridComHook.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class SimplydebridComHook(MultiHook): -    __name__    = "SimplydebridComHook" -    __type__    = "hook" -    __version__ = "0.04" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Simply-Debrid.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Kagenoshin", "kagenoshin@gmx.ch")] - - -    def getHosters(self): -        html = self.getURL("http://simply-debrid.com/api.php", get={'list': 1}) -        return [x.strip() for x in html.rstrip(';').replace("\"", "").split(";")] diff --git a/module/plugins/hooks/SkipRev.py b/module/plugins/hooks/SkipRev.py deleted file mode 100644 index 7901ca540..000000000 --- a/module/plugins/hooks/SkipRev.py +++ /dev/null @@ -1,112 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import urllib -import urlparse - -from types import MethodType - -from module.PyFile import PyFile -from module.plugins.Hook import Hook -from module.plugins.Plugin import SkipDownload - - -class SkipRev(Hook): -    __name__    = "SkipRev" -    __type__    = "hook" -    __version__ = "0.29" - -    __config__ = [("mode"     , "Auto;Manual", "Choose recovery archives to skip"               , "Auto"), -                  ("revtokeep", "int"        , "Number of recovery archives to keep for package", 0     )] - -    __description__ = """Skip recovery archives (.rev)""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    @staticmethod -    def _setup(self): -        self.pyfile.plugin._setup() -        if self.pyfile.hasStatus("skipped"): -            raise SkipDownload(self.pyfile.statusname or self.pyfile.pluginname) - - -    def _name(self, pyfile): -        if hasattr(pyfile.pluginmodule, "getInfo"):  #@NOTE: getInfo is deprecated in 0.4.10 -            return pyfile.pluginmodule.getInfo([pyfile.url]).next()[0] -        else: -            self.logWarning("Unable to grab file name") -            return urlparse.urlparse(urllib.unquote(pyfile.url)).path.split('/')[-1] - - -    def _pyfile(self, link): -        return PyFile(self.core.files, -                      link.fid, -                      link.url, -                      link.name, -                      link.size, -                      link.status, -                      link.error, -                      link.plugin, -                      link.packageID, -                      link.order) - - -    def downloadPreparing(self, pyfile): -        name = self._name(pyfile) - -        if pyfile.statusname is _("unskipped") or not name.endswith(".rev") or not ".part" in name: -            return - -        revtokeep = -1 if self.getConfig('mode') == "Auto" else self.getConfig('revtokeep') - -        if revtokeep: -            status_list = (1, 4, 8, 9, 14) if revtokeep < 0 else (1, 3, 4, 8, 9, 14) -            pyname      = re.compile(r'%s\.part\d+\.rev$' % name.rsplit('.', 2)[0].replace('.', '\.')) - -            queued = [True for link in self.core.api.getPackageData(pyfile.package().id).links \ -                      if link.status not in status_list and pyname.match(link.name)].count(True) - -            if not queued or queued < revtokeep:  #: keep one rev at least in auto mode -                return - -        pyfile.setCustomStatus("SkipRev", "skipped") - -        if not hasattr(pyfile.plugin, "_setup"): -            # Work-around: inject status checker inside the preprocessing routine of the plugin -            pyfile.plugin._setup = pyfile.plugin.setup -            pyfile.plugin.setup  = MethodType(self._setup, pyfile.plugin) - - -    def downloadFailed(self, pyfile): -        #: Check if pyfile is still "failed", -        #  maybe might has been restarted in meantime -        if pyfile.status != 8 or pyfile.name.rsplit('.', 1)[-1].strip() not in ("rar", "rev"): -            return - -        revtokeep = -1 if self.getConfig('mode') == "Auto" else self.getConfig('revtokeep') - -        if not revtokeep: -            return - -        pyname = re.compile(r'%s\.part\d+\.rev$' % pyfile.name.rsplit('.', 2)[0].replace('.', '\.')) - -        for link in self.core.api.getPackageData(pyfile.package().id).links: -            if link.status is 4 and pyname.match(link.name): -                pylink = self._pyfile(link) - -                if revtokeep > -1 or pyfile.name.endswith(".rev"): -                    pylink.setStatus("queued") -                else: -                    pylink.setCustomStatus(_("unskipped"), "queued") - -                self.core.files.save() -                pylink.release() -                return diff --git a/module/plugins/hooks/SmoozedComHook.py b/module/plugins/hooks/SmoozedComHook.py deleted file mode 100644 index 24b7c8df0..000000000 --- a/module/plugins/hooks/SmoozedComHook.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class SmoozedComHook(MultiHook): -    __name__    = "SmoozedComHook" -    __type__    = "hook" -    __version__ = "0.03" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Smoozed.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("", "")] - - -    def getHosters(self): -        user, data = self.account.selectAccount() -        return self.account.getAccountInfo(user)["hosters"] diff --git a/module/plugins/hooks/UnSkipOnFail.py b/module/plugins/hooks/UnSkipOnFail.py deleted file mode 100644 index 9059d0350..000000000 --- a/module/plugins/hooks/UnSkipOnFail.py +++ /dev/null @@ -1,97 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.PyFile import PyFile -from module.plugins.Hook import Hook - - -class UnSkipOnFail(Hook): -    __name__    = "UnSkipOnFail" -    __type__    = "hook" -    __version__ = "0.07" - -    __config__ = [("activated", "bool", "Activated", True)] - -    __description__ = """Restart skipped duplicates when download fails""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def downloadFailed(self, pyfile): -        #: Check if pyfile is still "failed", -        #  maybe might has been restarted in meantime -        if pyfile.status != 8: -            return - -        msg = _("Looking for skipped duplicates of: %s (pid:%s)") -        self.logInfo(msg % (pyfile.name, pyfile.package().id)) - -        link = self.findDuplicate(pyfile) -        if link: -            self.logInfo(_("Queue found duplicate: %s (pid:%s)") % (link.name, link.packageID)) - -            #: 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. -            pylink = self._pyfile(link) - -            pylink.setCustomStatus(_("unskipped"), "queued") - -            self.core.files.save() -            pylink.release() - -        else: -            self.logInfo(_("No duplicates found")) - - -    def findDuplicate(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 (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. -        """ -        queue = self.core.api.getQueue()  #: get packages (w/o files, as most file data is useless here) - -        for package in queue: -            #: check if package-folder equals pyfile's package folder -            if package.folder != pyfile.package().folder: -                continue - -            #: now get packaged data w/ files/links -            pdata = self.core.api.getPackageData(package.pid) -            for link in pdata.links: -                #: check if link is "skipped" -                if link.status != 4: -                    continue - -                #: check if link name collides with pdata's name -                #: AND at last check if it is not pyfile itself -                if link.name == pyfile.name and link.fid != pyfile.id: -                    return link - - -    def _pyfile(self, link): -        return PyFile(self.core.files, -                      link.fid, -                      link.url, -                      link.name, -                      link.size, -                      link.status, -                      link.error, -                      link.plugin, -                      link.packageID, -                      link.order) diff --git a/module/plugins/hooks/UnrestrictLiHook.py b/module/plugins/hooks/UnrestrictLiHook.py deleted file mode 100644 index f1ffd1886..000000000 --- a/module/plugins/hooks/UnrestrictLiHook.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.common.json_layer import json_loads -from module.plugins.internal.MultiHook import MultiHook - - -class UnrestrictLiHook(MultiHook): -    __name__    = "UnrestrictLiHook" -    __type__    = "hook" -    __version__ = "0.05" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   ), -                  ("history"       , "bool"               , "Delete History"                      , False)] - -    __description__ = """Unrestrict.li hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("stickell", "l.stickell@yahoo.it")] - - -    def getHosters(self): -        json_data = self.getURL("http://unrestrict.li/api/jdownloader/hosts.php", get={'format': "json"}) -        json_data = json_loads(json_data) - -        return [element['host'] for element in json_data['result']] diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py deleted file mode 100644 index 5779e7c80..000000000 --- a/module/plugins/hooks/UpdateManager.py +++ /dev/null @@ -1,329 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import os -import re -import sys -import time - -from operator import itemgetter - -from module.network.RequestFactory import getURL -from module.plugins.Hook import Expose, Hook, threaded -from module.utils import save_join - - -# Case-sensitive os.path.exists -def exists(path): -    if os.path.exists(path): -        if os.name == 'nt': -            dir, name = os.path.split(path) -            return name in os.listdir(dir) -        else: -            return True -    else: -        return False - - -class UpdateManager(Hook): -    __name__    = "UpdateManager" -    __type__    = "hook" -    __version__ = "0.51" - -    __config__ = [("activated"    , "bool", "Activated"                                , True ), -                  ("checkinterval", "int" , "Check interval in hours"                  , 8    ), -                  ("autorestart"  , "bool", "Auto-restart pyLoad when required"        , True ), -                  ("checkonstart" , "bool", "Check for updates on startup"             , True ), -                  ("checkperiod"  , "bool", "Check for updates periodically"           , True ), -                  ("reloadplugins", "bool", "Monitor plugin code changes in debug mode", True ), -                  ("nodebugupdate", "bool", "Don't update plugins in debug mode"       , False)] - -    __description__ = """ Check for updates """ -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    interval = 0 - -    SERVER_URL         = "http://updatemanager.pyload.org" -    MIN_CHECK_INTERVAL = 3 * 60 * 60  #: 3 hours - -    event_list = ["allDownloadsProcessed"] - - -    def coreReady(self): -        if self.checkonstart: -            self.update() - -        self.initPeriodical() - - -    def setup(self): -        self.interval = 10 -        self.info     = {'pyload': False, 'version': None, 'plugins': False, 'last_check': time.time()} -        self.mtimes   = {}  #: store modification time for each plugin - -        if self.getConfig('checkonstart'): -            self.core.api.pauseServer() -            self.checkonstart = True -        else: -            self.checkonstart = False - -        self.do_restart = False - - -    def allDownloadsProcessed(self): -        if self.do_restart is True: -            self.logWarning(_("Downloads are done, restarting pyLoad to reload the updated plugins")) -            self.core.api.restart() - - -    def periodical(self): -        if self.core.debug: -            if self.getConfig('reloadplugins'): -                self.autoreloadPlugins() - -            if self.getConfig('nodebugupdate'): -                return - -        if self.getConfig('checkperiod') \ -           and time.time() - max(self.MIN_CHECK_INTERVAL, self.getConfig('checkinterval') * 60 * 60) > self.info['last_check']: -            self.update() - - -    @Expose -    def autoreloadPlugins(self): -        """ reload and reindex all modified plugins """ -        modules = filter( -            lambda m: m and (m.__name__.startswith("module.plugins.") or -                             m.__name__.startswith("userplugins.")) and -                             m.__name__.count(".") >= 2, sys.modules.itervalues() -        ) - -        reloads = [] - -        for m in modules: -            root, type, name = m.__name__.rsplit(".", 2) -            id = (type, name) -            if type in self.core.pluginManager.plugins: -                f = m.__file__.replace(".pyc", ".py") -                if not os.path.isfile(f): -                    continue - -                mtime = os.stat(f).st_mtime - -                if id not in self.mtimes: -                    self.mtimes[id] = mtime -                elif self.mtimes[id] < mtime: -                    reloads.append(id) -                    self.mtimes[id] = mtime - -        return True if self.core.pluginManager.reloadPlugins(reloads) else False - - -    def server_response(self): -        try: -            return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines() - -        except Exception: -            self.logWarning(_("Unable to retrieve server to get updates")) - - -    @Expose -    @threaded -    def update(self): -        """ check for updates """ - -        self.core.api.pauseServer() - -        if self._update() is 2 and self.getConfig('autorestart'): -            if not self.core.api.statusDownloads(): -                self.core.api.restart() -            else: -                self.do_restart = True -                self.logWarning(_("Downloads are active, will restart once the download is done")) -        else: -            self.core.api.unpauseServer() - - -    def _update(self): -        data = self.server_response() - -        self.info['last_check'] = time.time() - -        if not data: -            exitcode = 0 - -        elif data[0] == "None": -            self.logInfo(_("No new pyLoad version available")) -            exitcode = self._updatePlugins(data[1:]) - -        elif onlyplugin: -            exitcode = 0 - -        else: -            self.logInfo(_("***  New pyLoad Version %s available  ***") % data[0]) -            self.logInfo(_("***  Get it here: https://github.com/pyload/pyload/releases  ***")) -            self.info['pyload']  = True -            self.info['version'] = data[0] -            exitcode = 3 - -        # Exit codes: -        # -1 = No plugin updated, new pyLoad version available -        #  0 = No plugin updated -        #  1 = Plugins updated -        #  2 = Plugins updated, but restart required -        return exitcode - - -    def _updatePlugins(self, data): -        """ check for plugin updates """ - -        exitcode = 0 -        updated  = [] - -        url    = data[0] -        schema = data[1].split('|') - -        VERSION = re.compile(r'__version__.*=.*("|\')([\d.]+)') - -        if "BLACKLIST" in data: -            blacklist  = data[data.index('BLACKLIST') + 1:] -            updatelist = data[2:data.index('BLACKLIST')] -        else: -            blacklist  = [] -            updatelist = data[2:] - -        updatelist = [dict(zip(schema, x.split('|'))) for x in updatelist] -        blacklist  = [dict(zip(schema, x.split('|'))) for x in blacklist] - -        if blacklist: -            type_plugins = [(plugin['type'], plugin['name'].rsplit('.', 1)[0]) for plugin in blacklist] - -            # Protect UpdateManager from self-removing -            try: -                type_plugins.remove(("hook", "UpdateManager")) -            except ValueError: -                pass - -            for t, n in type_plugins: -                for idx, plugin in enumerate(updatelist): -                    if n == plugin['name'] and t == plugin['type']: -                        updatelist.pop(idx) -                        break - -            for t, n in self.removePlugins(sorted(type_plugins)): -                self.logInfo(_("Removed blacklisted plugin: [%(type)s] %(name)s") % { -                    'type': t, -                    'name': n, -                }) - -        for plugin in sorted(updatelist, key=itemgetter("type", "name")): -            filename = plugin['name'] -            prefix   = plugin['type'] -            version  = plugin['version'] - -            if filename.endswith(".pyc"): -                name = filename[:filename.find("_")] -            else: -                name = filename.replace(".py", "") - -            #@TODO: Remove in 0.4.10 -            if prefix.endswith("s"): -                type = prefix[:-1] -            else: -                type = prefix - -            plugins = getattr(self.core.pluginManager, "%sPlugins" % type) - -            oldver = float(plugins[name]['v']) if name in plugins else None -            newver = float(version) - -            if not oldver: -                msg = "New plugin: [%(type)s] %(name)s (v%(newver).2f)" -            elif newver > oldver: -                msg = "New version of plugin: [%(type)s] %(name)s (v%(oldver).2f -> v%(newver).2f)" -            else: -                continue - -            self.logInfo(_(msg) % {'type'  : type, -                                   'name'  : name, -                                   'oldver': oldver, -                                   'newver': newver}) -            try: -                content = getURL(url % plugin) -                m = VERSION.search(content) - -                if m and m.group(2) == version: -                    with open(save_join("userplugins", prefix, filename), "wb") as f: -                        f.write(content) - -                    updated.append((prefix, name)) -                else: -                    raise Exception, _("Version mismatch") - -            except Exception, e: -                self.logError(_("Error updating plugin: %s") % filename, e) - -        if updated: -            self.logInfo(_("*** Plugins updated ***")) - -            if self.core.pluginManager.reloadPlugins(updated): -                exitcode = 1 -            else: -                self.logWarning(_("pyLoad restart required to reload the updated plugins")) -                self.info['plugins'] = True -                exitcode = 2 - -            self.manager.dispatchEvent("plugin_updated", updated) -        else: -            self.logInfo(_("No plugin updates available")) - -        # Exit codes: -        # 0 = No plugin updated -        # 1 = Plugins updated -        # 2 = Plugins updated, but restart required -        return exitcode - - -    @Expose -    def removePlugins(self, type_plugins): -        """ delete plugins from disk """ - -        if not type_plugins: -            return - -        removed = set() - -        self.logDebug("Requested deletion of plugins: %s" % type_plugins) - -        for type, name in type_plugins: -            rootplugins = os.path.join(pypath, "module", "plugins") - -            for dir in ("userplugins", rootplugins): -                py_filename  = save_join(dir, type, name + ".py") -                pyc_filename = py_filename + "c" - -                if type == "hook": -                    try: -                        self.manager.deactivateHook(name) - -                    except Exception, e: -                        self.logDebug(e) - -                for filename in (py_filename, pyc_filename): -                    if not exists(filename): -                        continue - -                    try: -                        os.remove(filename) - -                    except OSError, e: -                        self.logError(_("Error removing: %s") % filename, e) - -                    else: -                        id = (type, name) -                        removed.add(id) - -        return list(removed)  #: return a list of the plugins successfully removed diff --git a/module/plugins/hooks/UserAgentSwitcher.py b/module/plugins/hooks/UserAgentSwitcher.py deleted file mode 100644 index 912c2ef09..000000000 --- a/module/plugins/hooks/UserAgentSwitcher.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -import os -import pycurl -import random - -from module.plugins.Hook import Hook -from module.utils import fs_encode - - -class UserAgentSwitcher(Hook): -    __name__    = "UserAgentSwitcher" -    __type__    = "hook" -    __version__ = "0.04" - -    __config__ = [("activated", "bool", "Activated"               , True                                                                      ), -                  ("uaf"      , "file", "Random user-agents file" , ""                                                                        ), -                  ("uar"      , "bool", "Random user-agent"       , False                                                                     ), -                  ("uas"      , "str" , "Custom user-agent string", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0")] - -    __description__ = """Custom user-agent""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    interval = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def downloadPreparing(self, pyfile): -        uar = self.getConfig('uar') -        uaf = fs_encode(self.getConfig('uaf')) - -        if uar and os.path.isfile(uaf): -            with open(uaf) as f: -                uas = random.choice([ua for ua in f.read().splitlines()]) -        else: -            uas = self.getConfig('uas') - -        if uas: -            self.logDebug("Use custom user-agent string: " + uas) -            pyfile.plugin.req.http.c.setopt(pycurl.USERAGENT, uas.encode('utf-8')) diff --git a/module/plugins/hooks/WindowsPhoneNotify.py b/module/plugins/hooks/WindowsPhoneNotify.py deleted file mode 100644 index e61057f9f..000000000 --- a/module/plugins/hooks/WindowsPhoneNotify.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- - -import httplib -import time - -from module.plugins.Hook import Hook, Expose - - -class WindowsPhoneNotify(Hook): -    __name__    = "WindowsPhoneNotify" -    __type__    = "hook" -    __version__ = "0.09" - -    __config__ = [("id"             , "str" , "Push ID"                                  , ""   ), -                  ("url"            , "str" , "Push url"                                 , ""   ), -                  ("notifycaptcha"  , "bool", "Notify captcha request"                   , True ), -                  ("notifypackage"  , "bool", "Notify package finished"                  , True ), -                  ("notifyprocessed", "bool", "Notify packages processed"                , True ), -                  ("notifyupdate"   , "bool", "Notify plugin updates"                    , True ), -                  ("notifyexit"     , "bool", "Notify pyLoad shutdown"                   , True ), -                  ("sendtimewait"   , "int" , "Timewait in seconds between notifications", 5    ), -                  ("sendpermin"     , "int" , "Max notifications per minute"             , 12   ), -                  ("ignoreclient"   , "bool", "Send notifications if client is connected", False)] - -    __description__ = """Send push notifications to Windows Phone""" -    __license__     = "GPLv3" -    __authors__     = [("Andy Voigt"    , "phone-support@hotmail.de"), -                       ("Walter Purcaro", "vuolter@gmail.com"       )] - - -    event_list = ["allDownloadsProcessed", "plugin_updated"] -    interval   = 0  #@TODO: Remove in 0.4.10 - - -    def setup(self): -        self.info          = {}  #@TODO: Remove in 0.4.10 -        self.last_notify   = 0 -        self.notifications = 0 - - -    def plugin_updated(self, type_plugins): -        if not self.getConfig('notifyupdate'): -            return - -        self.notify(_("Plugins updated"), str(type_plugins)) - - -    def coreExiting(self): -        if not self.getConfig('notifyexit'): -            return - -        if self.core.do_restart: -            self.notify(_("Restarting pyLoad")) -        else: -            self.notify(_("Exiting pyLoad")) - - -    def newCaptchaTask(self, task): -        if not self.getConfig('notifycaptcha'): -            return - -        self.notify(_("Captcha"), _("New request waiting user input")) - - -    def packageFinished(self, pypack): -        if self.getConfig('notifypackage'): -            self.notify(_("Package finished"), pypack.name) - - -    def allDownloadsProcessed(self): -        if not self.getConfig('notifyprocessed'): -            return - -        if any(True for pdata in self.core.api.getQueue() if pdata.linksdone < pdata.linkstotal): -            self.notify(_("Package failed"), _("One or more packages was not completed successfully")) -        else: -            self.notify(_("All packages finished")) - - -    def getXmlData(self, msg): -        return ("<?xml version='1.0' encoding='utf-8'?> <wp:Notification xmlns:wp='WPNotification'> " -                "<wp:Toast> <wp:Text1>pyLoad</wp:Text1> <wp:Text2>%s</wp:Text2> " -                "</wp:Toast> </wp:Notification>" % msg) - - -    @Expose -    def notify(self, -               event, -               msg="", -               key=(self.getConfig('id'), self.getConfig('url'))): - -        id, url = key - -        if not id or not url: -            return - -        if self.core.isClientConnected() and not self.getConfig('ignoreclient'): -            return - -        elapsed_time = time.time() - self.last_notify - -        if elapsed_time < self.getConf("sendtimewait"): -            return - -        if elapsed_time > 60: -            self.notifications = 0 - -        elif self.notifications >= self.getConf("sendpermin"): -            return - - -        request    = self.getXmlData("%s: %s" % (event, msg) if msg else event) -        webservice = httplib.HTTP(url) - -        webservice.putrequest("POST", id) -        webservice.putheader("Host", url) -        webservice.putheader("Content-type", "text/xml") -        webservice.putheader("X-NotificationClass", "2") -        webservice.putheader("X-WindowsPhone-Target", "toast") -        webservice.putheader("Content-length", "%d" % len(request)) -        webservice.endheaders() -        webservice.send(request) -        webservice.close() - -        self.last_notify    = time.time() -        self.notifications += 1 diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py deleted file mode 100644 index d80515a22..000000000 --- a/module/plugins/hooks/XFileSharingPro.py +++ /dev/null @@ -1,132 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.Hook import Hook - - -class XFileSharingPro(Hook): -    __name__    = "XFileSharingPro" -    __type__    = "hook" -    __version__ = "0.37" - -    __config__ = [("activated"       , "bool", "Activated"                     , True ), -                  ("use_hoster_list" , "bool", "Load listed hosters only"      , False), -                  ("use_crypter_list", "bool", "Load listed crypters only"     , False), -                  ("use_builtin_list", "bool", "Load built-in plugin list"     , True ), -                  ("hoster_list"     , "str" , "Hoster list (comma separated)" , ""   ), -                  ("crypter_list"    , "str" , "Crypter list (comma separated)", ""   )] - -    __description__ = """Load XFileSharingPro based hosters and crypter which don't need a own plugin to run""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    # event_list = ["pluginConfigChanged"] -    interval   = 0  #@TODO: Remove in 0.4.10 -    regexp     = {'hoster' : (r'https?://(?:www\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', -                              r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:embed-)?\w+'), -                  'crypter': (r'https?://(?:www\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:user|folder)s?/\w+', -                              r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:user|folder)s?/\w+')} - -    HOSTER_BUILTIN  = [#WORKING HOSTERS: -                       "backin.net", "eyesfile.ca", "file4safe.com", "fileband.com", "filedwon.com", "fileparadox.in", -                       "filevice.com", "hostingbulk.com", "junkyvideo.com", "linestorage.com", "ravishare.com", "ryushare.com", -                       "salefiles.com", "sendmyway.com", "sharesix.com", "thefile.me", "verzend.be", "xvidstage.com", -                       #NOT TESTED: -                       "101shared.com", "4upfiles.com", "filemaze.ws", "filenuke.com", "linkzhost.com", "mightyupload.com", -                       "rockdizfile.com", "sharebeast.com", "sharerepo.com", "shareswift.com", "uploadbaz.com", "uploadc.com", -                       "vidbull.com", "worldbytez.com", "zalaa.com", "zomgupload.com", -                       #NOT WORKING: -                       "amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", "laoupload.com", "rd-fs.com"] -    CRYPTER_BUILTIN = ["junocloud.me", "rapidfileshare.net"] - - -    # def pluginConfigChanged(self, plugin, name, value): -        # self.loadPattern() - - -    def setup(self): -        self.info = {}  #@TODO: Remove in 0.4.10 - - -    def coreReady(self): -        self.loadPattern() - - -    def loadPattern(self): -        use_builtin_list = self.getConfig('use_builtin_list') - -        for type, plugin in (("hoster",  "XFileSharingPro"), -                             ("crypter", "XFileSharingProFolder")): -            every_plugin = not self.getConfig("use_%s_list" % type) - -            if every_plugin: -                self.logInfo(_("Handling any %s I can!") % type) -                pattern = self.regexp[type][0] -            else: -                plugins    = self.getConfig('%s_list' % type) -                plugin_set = set(plugins.replace(' ', '').replace('\\', '').replace('|', ',').replace(';', ',').lower().split(',')) - -                if use_builtin_list: -                    plugin_set |= set(x.lower() for x in getattr(self, "%s_BUILTIN" % type.upper())) - -                plugin_set -= set(('', u'')) - -                if not plugin_set: -                    self.logInfo(_("No %s to handle") % type) -                    self._unload(type, plugin) -                    return - -                match_list = '|'.join(sorted(plugin_set)) - -                len_match_list = len(plugin_set) -                self.logInfo(_("Handling %d %s%s: %s") % (len_match_list, -                                                          type, -                                                          "" if len_match_list == 1 else "s", -                                                          match_list.replace('|', ', '))) - -                pattern = self.regexp[type][1] % match_list.replace('.', '\.') - -            dict = self.core.pluginManager.plugins[type][plugin] -            dict['pattern'] = pattern -            dict['re'] = re.compile(pattern) - -            self.logDebug("Loaded %s pattern: %s" % (type, pattern)) - - -    def _unload(self, type, plugin): -        dict = self.core.pluginManager.plugins[type][plugin] -        dict['pattern'] = r'^unmatchable$' -        dict['re'] = re.compile(dict['pattern']) - - -    def unload(self): -        # self.unloadHoster("BasePlugin") -        for type, plugin in (("hoster",  "XFileSharingPro"), -                             ("crypter", "XFileSharingProFolder")): -            self._unload(type, plugin) - - -    def unloadHoster(self, hoster): -        hdict = self.core.pluginManager.hosterPlugins[hoster] -        if "new_name" in hdict and hdict['new_name'] == "XFileSharingPro": -            if "module" in hdict: -                hdict.pop('module', None) - -            if "new_module" in hdict: -                hdict.pop('new_module', None) -                hdict.pop('new_name', None) - -            return True -        else: -            return False - - -    # def downloadFailed(self, pyfile): -        # if pyfile.pluginname == "BasePlugin" \ -           # and pyfile.hasStatus("failed") \ -           # and not self.getConfig('use_hoster_list') \ -           # and self.unloadHoster("BasePlugin"): -            # self.logDebug("Unloaded XFileSharingPro from BasePlugin") -            # pyfile.setStatus("queued") diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py deleted file mode 100644 index b61428392..000000000 --- a/module/plugins/hooks/XMPPInterface.py +++ /dev/null @@ -1,252 +0,0 @@ -# -*- coding: utf-8 -*- - -from pyxmpp import streamtls -from pyxmpp.all import JID, Message -from pyxmpp.interface import implements -from pyxmpp.interfaces import * -from pyxmpp.jabber.client import JabberClient - -from module.plugins.hooks.IRCInterface import IRCInterface - - -class XMPPInterface(IRCInterface, JabberClient): -    __name__    = "XMPPInterface" -    __type__    = "hook" -    __version__ = "0.11" - -    __config__ = [("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"), -                  ("pw", "str", "Password", ""), -                  ("tls", "bool", "Use TLS", False), -                  ("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"), -                  ("info_file", "bool", "Inform about every file finished", False), -                  ("info_pack", "bool", "Inform about every package finished", True), -                  ("captcha", "bool", "Send captcha requests", True)] - -    __description__ = """Connect to jabber and let owner perform different tasks""" -    __license__     = "GPLv3" -    __authors__     = [("RaNaN", "RaNaN@pyload.org")] - - -    implements(IMessageHandlersProvider) - - -    def __init__(self, core, manager): -        IRCInterface.__init__(self, core, manager) - -        self.jid = JID(self.getConfig('jid')) -        password = self.getConfig('pw') - -        # if bare JID is provided add a resource -- it is required -        if not self.jid.resource: -            self.jid = JID(self.jid.node, self.jid.domain, "pyLoad") - -        if self.getConfig('tls'): -            tls_settings = streamtls.TLSSettings(require=True, verify_peer=False) -            auth = ("sasl:PLAIN", "sasl:DIGEST-MD5") -        else: -            tls_settings = None -            auth = ("sasl:DIGEST-MD5", "digest") - -        # setup client with provided connection information -        # and identity data -        JabberClient.__init__(self, self.jid, password, -                              disco_name="pyLoad XMPP Client", disco_type="bot", -                              tls_settings=tls_settings, auth_methods=auth) - -        self.interface_providers = [ -            VersionHandler(self), -            self, -        ] - - -    def coreReady(self): -        self.new_package = {} - -        self.start() - - -    def packageFinished(self, pypack): -        try: -            if self.getConfig('info_pack'): -                self.announce(_("Package finished: %s") % pypack.name) -        except Exception: -            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 Exception: -            pass - - -    def run(self): -        # connect to IRC etc. -        self.connect() -        try: -            self.loop() -        except Exception, ex: -            self.logError(ex) - - -    def stream_state_changed(self, state, arg): -        """This one is called when the state of stream connecting the component -        to a server changes. This will usually be used to let the user -        know what is going on.""" -        self.logDebug("*** State changed: %s %r ***" % (state, arg)) - - -    def disconnected(self): -        self.logDebug("Client was disconnected") - - -    def stream_closed(self, stream): -        self.logDebug("Stream was closed", stream) - - -    def stream_error(self, err): -        self.logDebug("Stream Error", err) - - -    def get_message_handlers(self): -        """Return list of (message_type, message_handler) tuples. - -        The handlers returned will be called when matching message is received -        in a client session.""" -        return [("normal", self.message)] - - -    def message(self, stanza): -        """Message handler for the component.""" -        subject = stanza.get_subject() -        body = stanza.get_body() -        t = stanza.get_type() -        self.logDebug("Message from %s received." % unicode(stanza.get_from())) -        self.logDebug("Body: %s Subject: %s Type: %s" % (body, subject, t)) - -        if t == "headline": -            # 'headline' messages should never be replied to -            return True -        if subject: -            subject = u"Re: " + subject - -        to_jid = stanza.get_from() -        from_jid = stanza.get_to() - -        #j = JID() -        to_name = to_jid.as_utf8() -        from_name = from_jid.as_utf8() - -        names = self.getConfig('owners').split(";") - -        if to_name in names or to_jid.node + "@" + to_jid.domain in names: -            messages = [] - -            trigger = "pass" -            args = None - -            try: -                temp = body.split() -                trigger = temp[0] -                if len(temp) > 1: -                    args = temp[1:] -            except Exception: -                pass - -            handler = getattr(self, "event_%s" % trigger, self.event_pass) -            try: -                res = handler(args) -                for line in res: -                    m = Message( -                        to_jid=to_jid, -                        from_jid=from_jid, -                        stanza_type=stanza.get_type(), -                        subject=subject, -                        body=line) - -                    messages.append(m) -            except Exception, e: -                self.logError(e) - -            return messages - -        else: -            return True - - -    def response(self, msg, origin=""): -        return self.announce(msg) - - -    def announce(self, message): -        """ send message to all owners""" -        for user in self.getConfig('owners').split(";"): -            self.logDebug("Send message to", user) - -            to_jid = JID(user) - -            m = Message(from_jid=self.jid, -                        to_jid=to_jid, -                        stanza_type="chat", -                        body=message) - -            stream = self.get_stream() -            if not stream: -                self.connect() -                stream = self.get_stream() - -            stream.send(m) - - -    def beforeReconnecting(self, ip): -        self.disconnect() - - -    def afterReconnecting(self, ip): -        self.connect() - - -class VersionHandler(object): -    """Provides handler for a version query. - -    This class will answer version query and announce 'jabber:iq:version' namespace -    in the client's disco#info results.""" - -    implements(IIqHandlersProvider, IFeaturesProvider) - - -    def __init__(self, client): -        """Just remember who created this.""" -        self.client = client - - -    def get_features(self): -        """Return namespace which should the client include in its reply to a -        disco#info query.""" -        return ["jabber:iq:version"] - - -    def get_iq_get_handlers(self): -        """Return list of tuples (element_name, namespace, handler) describing -        handlers of <iq type='get'/> stanzas""" -        return [("query", "jabber:iq:version", self.get_version)] - - -    def get_iq_set_handlers(self): -        """Return empty list, as this class provides no <iq type='set'/> stanza handler.""" -        return [] - - -    def get_version(self, iq): -        """Handler for jabber:iq:version queries. - -        jabber:iq:version queries are not supported directly by PyXMPP, so the -        XML node is accessed directly through the libxml2 API.  This should be -        used very carefully!""" -        iq = iq.make_result_response() -        q = iq.new_query("jabber:iq:version") -        q.newTextChild(q.ns(), "name", "Echo component") -        q.newTextChild(q.ns(), "version", "1.0") -        return iq diff --git a/module/plugins/hooks/ZeveraComHook.py b/module/plugins/hooks/ZeveraComHook.py deleted file mode 100644 index 21c1741d2..000000000 --- a/module/plugins/hooks/ZeveraComHook.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.MultiHook import MultiHook - - -class ZeveraComHook(MultiHook): -    __name__    = "ZeveraComHook" -    __type__    = "hook" -    __version__ = "0.05" - -    __config__ = [("pluginmode"    , "all;listed;unlisted", "Use for plugins"                     , "all"), -                  ("pluginlist"    , "str"                , "Plugin list (comma separated)"       , ""   ), -                  ("revertfailed"  , "bool"               , "Revert to standard download if fails", True ), -                  ("reload"        , "bool"               , "Reload plugin list"                  , True ), -                  ("reloadinterval", "int"                , "Reload interval in hours"            , 12   )] - -    __description__ = """Zevera.com hook plugin""" -    __license__     = "GPLv3" -    __authors__     = [("zoidberg"      , "zoidberg@mujmail.cz"), -                       ("Walter Purcaro", "vuolter@gmail.com"  )] - - -    def getHosters(self): -        html = self.account.api_response(pyreq.getHTTPRequest(timeout=120), cmd="gethosters") -        return [x.strip() for x in html.split(",")] diff --git a/module/plugins/hooks/__init__.py b/module/plugins/hooks/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/module/plugins/hooks/__init__.py +++ /dev/null | 
