diff options
Diffstat (limited to 'module/plugins/internal/SimpleCrypter.py')
-rw-r--r-- | module/plugins/internal/SimpleCrypter.py | 294 |
1 files changed, 252 insertions, 42 deletions
diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index ba4235072..1457c6fe5 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -2,21 +2,22 @@ import re -from module.plugins.internal.Crypter import Crypter -from module.plugins.internal.Plugin import replace_patterns, set_cookie, set_cookies -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.internal.Crypter import Crypter, create_getInfo, parse_fileInfo +from module.plugins.internal.utils import replace_patterns, set_cookie, set_cookies -class SimpleCrypter(Crypter, SimpleHoster): +class SimpleCrypter(Crypter): __name__ = "SimpleCrypter" __type__ = "crypter" - __version__ = "0.67" + __version__ = "0.71" __status__ = "testing" __pattern__ = r'^unmatchable$' - __config__ = [("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)] + __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), + ("max_wait" , "int" , "Reconnect if waiting time is greater than minutes", 10 )] __description__ = """Simple decrypter plugin""" __license__ = "GPLv3" @@ -59,14 +60,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,68 +80,170 @@ 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 in (404, 410): + 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): - for i in xrange(self.get_config("maxredirs", plugin="UserAgentSwitcher")): - redirect = self.link or pyfile.url - self.log_debug("Redirect #%d to: %s" % (i, redirect)) + link = None + maxredirs = self.get_config("maxredirs", default=10, plugin="UserAgentSwitcher") - header = self.load(redirect, just_header=True) - if header.get('location'): - self.link = header.get('location') - else: - break + for i in xrange(maxredirs): + url = link or pyfile.url + self.log_debug("Redirect #%d to: %s" % (i, url)) + + header = self.load(url, just_header=True) + location = header.get('location') + + if location: + link = location + + elif link: + self.urls.append(link) + return else: - self.log_error(_("Too many redirects")) + self.log_warning(_("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.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): self.prepare() - self.check_info() #@TODO: Remove in 0.4.10 if self.direct_dl: - self.log_debug(_("Looking for direct download link...")) + self.log_info(_("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")) + if self.urls or self.packages: + 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): + if not self.urls and not self.packages: self.preload() - self.links = self.get_links() or list() + self.urls.extend(self.get_links()) if self.PAGES_PATTERN: self.handle_pages(pyfile) - if self.link: - self.urls.append(self.link) - if self.links: - name = folder = pyfile.name - self.packages.append((name, self.links, folder)) + def handle_free(self, pyfile): + if not self.LINK_FREE_PATTERN: + self.log_warning(_("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.urls.extend(links) + + + def handle_premium(self, pyfile): + if not self.LINK_PREMIUM_PATTERN: + self.log_warning(_("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.urls.extend(links) def get_links(self): @@ -148,7 +251,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.urls def load_page(self, number): @@ -164,4 +275,103 @@ class SimpleCrypter(Crypter, SimpleHoster): for p in xrange(2, pages + 1): self.html = self.load_page(p) - self.links += self.get_links() + self.urls.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 > self.get_config("max_wait", 10) * 60) + 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 > self.get_config("max_wait", 10) * 60) + 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 > self.get_config("max_wait", 10) * 60) + + self.info.pop('error', None) |