summaryrefslogtreecommitdiffstats
path: root/module/plugins/internal/SimpleCrypter.py
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/internal/SimpleCrypter.py')
-rw-r--r--module/plugins/internal/SimpleCrypter.py316
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)