diff options
| -rw-r--r-- | module/plugins/internal/SimpleCrypter.py | 316 | 
1 files changed, 292 insertions, 24 deletions
| diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index ba4235072..79b5670df 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -2,19 +2,19 @@  import re -from module.plugins.internal.Crypter import Crypter +from module.plugins.internal.Crypter import Crypter, create_getInfo, parse_fileInfo  from module.plugins.internal.Plugin import replace_patterns, set_cookie, set_cookies -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo -class SimpleCrypter(Crypter, SimpleHoster): +class SimpleCrypter(Crypter):      __name__    = "SimpleCrypter"      __type__    = "crypter" -    __version__ = "0.67" +    __version__ = "0.70"      __status__  = "testing"      __pattern__ = r'^unmatchable$' -    __config__  = [("use_premium"          , "bool", "Use premium account if available"   , True), +    __config__  = [("activated"            , "bool", "Activated"                          , True), +                   ("use_premium"          , "bool", "Use premium account if available"   , True),                     ("use_subfolder"        , "bool", "Save package to subfolder"          , True),                     ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] @@ -59,14 +59,14 @@ class SimpleCrypter(Crypter, SimpleHoster):      DIRECT_LINK          = True   #: Set to True to looking for direct link (as defined in handle_direct method), set to None to do it if self.account is True else False      LOGIN_ACCOUNT        = False  #: Set to True to require account login      LOGIN_PREMIUM        = False  #: Set to True to require premium account login -    # LEECH_HOSTER         = False  #: Set to True to leech other hoster link (as defined in handle_multi method)      TEXT_ENCODING        = True   #: Set to encoding name if encoding value in http header is not correct -    PAGES_PATTERN        = None      LINK_PATTERN         = None +    LINK_FREE_PATTERN    = None +    LINK_PREMIUM_PATTERN = None +    PAGES_PATTERN        = None      NAME_PATTERN         = None -    HASHSUM_PATTERN      = None      OFFLINE_PATTERN      = None      TEMP_OFFLINE_PATTERN = None @@ -79,20 +79,72 @@ class SimpleCrypter(Crypter, SimpleHoster):      ERROR_PATTERN        = None +     @classmethod +    def api_info(cls, url): +        return {} + + +    @classmethod +    def get_info(cls, url="", html=""): +        info = super(SimpleHoster, cls).get_info(url) + +        info.update(cls.api_info(url)) + +        if not html and info['status'] is not 2: +            if not url: +                info['error']  = "missing url" +                info['status'] = 1 + +            elif info['status'] is 3: +                try: +                    html = get_url(url, cookies=cls.COOKIES, decode=cls.TEXT_ENCODING) + +                except BadHeader, e: +                    info['error'] = "%d: %s" % (e.code, e.content) + +                    if e.code is 404: +                        info['status'] = 1 + +                    elif e.code is 503: +                        info['status'] = 6 + +                except Exception: +                    pass + +        if html: +            if cls.OFFLINE_PATTERN and re.search(cls.OFFLINE_PATTERN, html) is not None: +                info['status'] = 1 + +            elif cls.TEMP_OFFLINE_PATTERN and re.search(cls.TEMP_OFFLINE_PATTERN, html) is not None: +                info['status'] = 6 + +            elif cls.NAME_PATTERN: +                m = re.search(cls.NAME_PATTERN, html): +                if m is not None: +                    info['status'] = 2 +                    info['pattern'].update(m.groupdict()) + +        if 'N' in info['pattern']: +            name = replace_patterns(info['pattern']['N'], cls.NAME_REPLACEMENTS) +            info['name'] = parse_name(name) + +        return info + +      #@TODO: Remove in 0.4.10      def _setup(self): -        orig_name = self.__name__ -        self.__name__ = re.sub(r'Folder$', "", self.__name__) +        orig_name     = self.classname +        self.classname = orig_name.rstrip("Folder")          super(SimpleCrypter, self)._setup() -        self.__name__ = orig_name +        self.classname = orig_name      #@TODO: Remove in 0.4.10      def load_account(self): -        orig_name = self.__name__ -        self.__name__ = re.sub(r'Folder$', "", self.__name__) +        orig_name     = self.classname +        self.classname = orig_name.rstrip("Folder")          super(SimpleCrypter, self).load_account() -        self.__name__ = orig_name +        self.classname = orig_name      def handle_direct(self, pyfile): @@ -109,9 +161,39 @@ class SimpleCrypter(Crypter, SimpleHoster):              self.log_error(_("Too many redirects")) +    def preload(self): +        self.html = self.load(self.pyfile.url, +                              cookies=self.COOKIES, +                              ref=False, +                              decode=self.TEXT_ENCODING) + +      def prepare(self): -        self.links = [] -        return super(SimpleCrypter, self).prepare() +        self.link      = "" +        self.links     = [] +        self.direct_dl = False + +        if self.LOGIN_PREMIUM and not self.premium: +            self.fail(_("Required premium account not found")) + +        if self.LOGIN_ACCOUNT and not self.account: +            self.fail(_("Required account not found")) + +        self.req.setOption("timeout", 120) + +        if self.LINK_PATTERN: +            if self.LINK_FREE_PATTERN is None: +                self.LINK_FREE_PATTERN = self.LINK_PATTERN + +            if self.LINK_PREMIUM_PATTERN is None: +                self.LINK_PREMIUM_PATTERN = self.LINK_PATTERN + +        if self.DIRECT_LINK is None: +            self.direct_dl = bool(self.account) +        else: +            self.direct_dl = self.DIRECT_LINK + +        self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS)      def decrypt(self, pyfile): @@ -119,18 +201,18 @@ class SimpleCrypter(Crypter, SimpleHoster):          self.check_info()  #@TODO: Remove in 0.4.10          if self.direct_dl: -            self.log_debug(_("Looking for direct download link...")) +            self.log_debug(_("Looking for direct link..."))              self.handle_direct(pyfile)              if self.link or self.links or self.urls or self.packages: -                self.log_info(_("Direct download link detected")) +                self.log_info(_("Direct link detected"))              else: -                self.log_info(_("Direct download link not found")) +                self.log_info(_("Direct link not found"))          if not (self.link or self.links or self.urls or self.packages):              self.preload() -            self.links = self.get_links() or list() +            self.links.extend(self.get_links())              if self.PAGES_PATTERN:                  self.handle_pages(pyfile) @@ -139,8 +221,30 @@ class SimpleCrypter(Crypter, SimpleHoster):              self.urls.append(self.link)          if self.links: -            name = folder = pyfile.name -            self.packages.append((name, self.links, folder)) +            self.packages.append((pyfile.name, self.links, pyfile.name)) + + +    def handle_free(self, pyfile): +        if not self.LINK_FREE_PATTERN: +            self.log_error(_("Free decrypting not implemented")) + +        links = re.findall(self.LINK_FREE_PATTERN, self.html) +        if not links: +            self.error(_("Free decrypted link not found")) +        else: +            self.links.extend(links) + + +    def handle_premium(self, pyfile): +        if not self.LINK_PREMIUM_PATTERN: +            self.log_error(_("Premium decrypting not implemented")) +            self.restart(premium=False) + +        links = re.findall(self.LINK_PREMIUM_PATTERN, self.html) +        if not links: +            self.error(_("Premium decrypted link found")) +        else: +            self.links.extend(links)      def get_links(self): @@ -148,7 +252,15 @@ class SimpleCrypter(Crypter, SimpleHoster):          Returns the links extracted from self.html          You should override this only if it's impossible to extract links using only the LINK_PATTERN.          """ -        return re.findall(self.LINK_PATTERN, self.html) +        if self.premium: +            self.log_info(_("Decrypting as premium link...")) +            self.handle_premium(pyfile) + +        elif not self.LOGIN_ACCOUNT: +            self.log_info(_("Decrypting as free link...")) +            self.handle_free(pyfile) + +        return self.links      def load_page(self, number): @@ -164,4 +276,160 @@ class SimpleCrypter(Crypter, SimpleHoster):          for p in xrange(2, pages + 1):              self.html = self.load_page(p) -            self.links += self.get_links() +            self.links.append(self.get_links()) + + +    def check_errors(self): +        if not self.html: +            self.log_warning(_("No html code to check")) +            return + +        if self.IP_BLOCKED_PATTERN and re.search(self.IP_BLOCKED_PATTERN, self.html): +            self.fail(_("Connection from your current IP address is not allowed")) + +        elif not self.premium: +            if self.PREMIUM_ONLY_PATTERN and re.search(self.PREMIUM_ONLY_PATTERN, self.html): +                self.fail(_("Link can be decrypted by premium users only")) + +            elif self.SIZE_LIMIT_PATTERN and re.search(self.SIZE_LIMIT_PATTERN, self.html): +                self.fail(_("Link list too large for free decrypt")) + +            elif self.DL_LIMIT_PATTERN and re.search(self.DL_LIMIT_PATTERN, self.html): +                m = re.search(self.DL_LIMIT_PATTERN, self.html) +                try: +                    errmsg = m.group(1).strip() + +                except (AttributeError, IndexError): +                    errmsg = m.group(0).strip() + +                finally: +                    errmsg = re.sub(r'<.*?>', " ", errmsg) + +                self.info['error'] = errmsg +                self.log_warning(errmsg) + +                wait_time = parse_time(errmsg) +                self.wait(wait_time, reconnect=wait_time > 300) +                self.restart(_("Download limit exceeded")) + +        if self.HAPPY_HOUR_PATTERN and re.search(self.HAPPY_HOUR_PATTERN, self.html): +            self.multiDL = True + +        if self.ERROR_PATTERN: +            m = re.search(self.ERROR_PATTERN, self.html) +            if m is not None: +                try: +                    errmsg = m.group(1) + +                except (AttributeError, IndexError): +                    errmsg = m.group(0) + +                finally: +                    errmsg = re.sub(r'<.*?>', " ", errmsg.strip()) + +                self.info['error'] = errmsg +                self.log_warning(errmsg) + +                if re.search('limit|wait|slot', errmsg, re.I): +                    wait_time = parse_time(errmsg) +                    self.wait(wait_time, reconnect=wait_time > 300) +                    self.restart(_("Download limit exceeded")) + +                elif re.search('country|ip|region|nation', errmsg, re.I): +                    self.fail(_("Connection from your current IP address is not allowed")) + +                elif re.search('captcha|code', errmsg, re.I): +                    self.retry_captcha() + +                elif re.search('countdown|expired', errmsg, re.I): +                    self.retry(10, 60, _("Link expired")) + +                elif re.search('maint(e|ai)nance|temp', errmsg, re.I): +                    self.temp_offline() + +                elif re.search('up to|size', errmsg, re.I): +                    self.fail(_("Link list too large for free decrypt")) + +                elif re.search('offline|delet|remov|not? (found|(longer)? available)', errmsg, re.I): +                    self.offline() + +                elif re.search('filename', errmsg, re.I): +                    self.fail(_("Invalid url")) + +                elif re.search('premium', errmsg, re.I): +                    self.fail(_("Link can be decrypted by premium users only")) + +                else: +                    self.wait(60, reconnect=True) +                    self.restart(errmsg) + +        elif self.WAIT_PATTERN: +            m = re.search(self.WAIT_PATTERN, self.html) +            if m is not None: +                try: +                    waitmsg = m.group(1).strip() + +                except (AttributeError, IndexError): +                    waitmsg = m.group(0).strip() + +                wait_time = parse_time(waitmsg) +                self.wait(wait_time, reconnect=wait_time > 300) + +        self.info.pop('error', None) + + +    def check_status(self, getinfo=True): +        if not self.info or getinfo: +            self.log_info(_("Updating file info...")) +            old_info = self.info.copy() +            self.info.update(self.get_info(self.pyfile.url, self.html)) +            self.log_debug("File info: %s" % self.info) +            self.log_debug("Previous file info: %s" % old_info) + +        try: +            status = self.info['status'] or 14 + +            if status is 1: +                self.offline() + +            elif status is 6: +                self.temp_offline() + +            elif status is 8: +                self.fail() + +        finally: +            self.log_info(_("File status: ") + self.pyfile.getStatusName()) + + +    def check_name_folder(self, getinfo=True): +        if not self.info or getinfo: +            self.log_info(_("Updating file info...")) +            old_info = self.info.copy() +            self.info.update(self.get_info(self.pyfile.url, self.html)) +            self.log_debug("File info: %s" % self.info) +            self.log_debug("Previous file info: %s" % old_info) + +        name   = self.info.get('name') +        folder = self.info.get('folder') + +        if name and name is not self.info.get('url'): +            self.pyfile.name = name +        else: +            name = self.pyfile.name + +        self.info['folder'] = folder else self.pyfile.name + +        self.log_info(_("File name: ") + name) +        self.log_info(_("File folder: ") + folder) + + +    #@TODO: Rewrite in 0.4.10 +    def check_info(self): +        self.check_name_folder() + +        if self.html: +            self.check_errors() +            self.check_name_folder() + +        self.check_status(getinfo=False) | 
