summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/plugins/crypter/LinkdecrypterCom.py62
-rw-r--r--module/plugins/hoster/HellshareCz.py76
-rw-r--r--module/plugins/internal/SimpleHoster.py75
3 files changed, 78 insertions, 135 deletions
diff --git a/module/plugins/crypter/LinkdecrypterCom.py b/module/plugins/crypter/LinkdecrypterCom.py
index ff21916ef..69d2f8192 100644
--- a/module/plugins/crypter/LinkdecrypterCom.py
+++ b/module/plugins/crypter/LinkdecrypterCom.py
@@ -22,79 +22,79 @@ from module.plugins.Crypter import Crypter
class LinkdecrypterCom(Crypter):
__name__ = "LinkdecrypterCom"
__type__ = "crypter"
- __version__ = "0.26"
+ __version__ = "0.27"
__description__ = """linkdecrypter.com"""
__author_name__ = ("zoidberg", "flowlee")
-
+
TEXTAREA_PATTERN = r'<textarea name="links" wrap="off" readonly="1" class="caja_des">(.+)</textarea>'
PASSWORD_PATTERN = r'<input type="text" name="password"'
CAPTCHA_PATTERN = r'<img class="captcha" src="(.+?)"(.*?)>'
REDIR_PATTERN = r'<i>(Click <a href="./">here</a> if your browser does not redirect you).</i>'
-
+
def decrypt(self, pyfile):
self.passwords = self.getPassword().splitlines()
-
+
# API not working anymore
- new_links = self.decryptHTML()
+ new_links = self.decryptHTML()
if new_links:
self.core.files.addLinks(new_links, self.pyfile.package().id)
else:
- self.fail('Could not extract any links')
+ self.fail('Could not extract any links')
def decryptAPI(self):
-
- get_dict = { "t": "link", "url": self.pyfile.url, "lcache": "1" }
+
+ get_dict = { "t": "link", "url": self.pyfile.url, "lcache": "1" }
self.html = self.load('http://linkdecrypter.com/api', get = get_dict)
if self.html.startswith('http://'): return self.html.splitlines()
-
+
if self.html == 'INTERRUPTION(PASSWORD)':
for get_dict['pass'] in self.passwords:
self.html = self.load('http://linkdecrypter.com/api', get= get_dict)
- if self.html.startswith('http://'): return self.html.splitlines()
-
+ if self.html.startswith('http://'): return self.html.splitlines()
+
self.logError('API', self.html)
if self.html == 'INTERRUPTION(PASSWORD)':
self.fail("No or incorrect password")
-
- return None
-
+
+ return None
+
def decryptHTML(self):
retries = 5
-
- post_dict = { "link_cache": "on", "pro_links": self.pyfile.url, "modo_links": "text" }
- self.html = self.load('http://linkdecrypter.com/', post = post_dict, cookies = True)
-
- while self.passwords or retries:
- found = re.search(self.TEXTAREA_PATTERN, self.html, flags=re.DOTALL)
+
+ post_dict = { "link_cache": "on", "pro_links": self.pyfile.url, "modo_links": "text" }
+ self.html = self.load('http://linkdecrypter.com/', post=post_dict, cookies=True, decode=True)
+
+ while self.passwords or retries:
+ found = re.search(self.TEXTAREA_PATTERN, self.html, flags=re.DOTALL)
if found: return [ x for x in found.group(1).splitlines() if '[LINK-ERROR]' not in x ]
-
+
found = re.search(self.CAPTCHA_PATTERN, self.html)
if found:
captcha_url = 'http://linkdecrypter.com/' + found.group(1)
result_type = "positional" if "getPos" in found.group(2) else "textual"
-
+
found = re.search(r"<p><i><b>([^<]+)</b></i></p>", self.html)
msg = found.group(1) if found else ""
self.logInfo("Captcha protected link", result_type, msg)
-
+
captcha = self.decryptCaptcha(captcha_url, result_type = result_type)
if result_type == "positional":
captcha = "%d|%d" % captcha
- self.html = self.load('http://linkdecrypter.com/', post={ "captcha": captcha })
+ self.html = self.load('http://linkdecrypter.com/', post={ "captcha": captcha }, decode=True)
retries -= 1
-
+
elif self.PASSWORD_PATTERN in self.html:
if self.passwords:
password = self.passwords.pop(0)
self.logInfo("Password protected link, trying " + password)
- self.html = self.load('http://linkdecrypter.com/', post= {'password': password})
+ self.html = self.load('http://linkdecrypter.com/', post={'password': password}, decode=True)
else:
self.fail("No or incorrect password")
-
+
else:
- retries -= 1
- self.html = self.load('http://linkdecrypter.com/', cookies = True)
-
- return None \ No newline at end of file
+ retries -= 1
+ self.html = self.load('http://linkdecrypter.com/', cookies=True, decode=True)
+
+ return None
diff --git a/module/plugins/hoster/HellshareCz.py b/module/plugins/hoster/HellshareCz.py
index 15d00be70..fd9f2ac32 100644
--- a/module/plugins/hoster/HellshareCz.py
+++ b/module/plugins/hoster/HellshareCz.py
@@ -17,25 +17,22 @@
"""
import re
-import datetime
from math import ceil
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.network.RequestFactory import getURL
+
class HellshareCz(SimpleHoster):
__name__ = "HellshareCz"
__type__ = "hoster"
__pattern__ = r"(http://(?:.*\.)*hellshare\.(?:cz|com|sk|hu|pl)/[^?]*/\d+).*"
- __version__ = "0.80"
- __description__ = """Hellshare.cz"""
+ __version__ = "0.81"
+ __description__ = """Hellshare.cz - premium only"""
__author_name__ = ("zoidberg")
- FREE_URL_PATTERN = r'<form[^>]*action="(http://free\d*\.helldata[^"]*)"'
PREMIUM_URL_PATTERN = r"launchFullDownload\('([^']*)'\);"
FILE_NAME_PATTERN = r'<h1 id="filename"[^>]*>(?P<N>[^<]+)</h1>'
FILE_SIZE_PATTERN = r'<strong id="FileSize_master">(?P<S>[0-9.]*)&nbsp;(?P<U>[kKMG])i?B</strong>'
FILE_OFFLINE_PATTERN = r'<h1>File not found.</h1>'
- CAPTCHA_PATTERN = r'<img class="left" id="captcha-img"src="([^"]*)" />'
#FILE_CREDITS_PATTERN = r'<strong class="filesize">(\d+) MB</strong>'
CREDIT_LEFT_PATTERN = r'<th>(\d+)</th><td>credits'
DOWNLOAD_AGAIN_PATTERN = r'<p>This file you downloaded already and re-download is for free. </p>'
@@ -46,65 +43,15 @@ class HellshareCz(SimpleHoster):
self.chunkLimit = 1
def process(self, pyfile):
+ if not self.account: self.fail("User not logged in")
pyfile.url = re.search(self.__pattern__, pyfile.url).group(1)
self.html = self.load(pyfile.url, decode = True)
self.getFileInfo()
-
+
found = re.search(self.SHOW_WINDOW_PATTERN, self.html)
if not found: self.parseError('SHOW WINDOW')
- self.url = "http://www.hellshare.com" + found.group(1)
- self.logDebug("SHOW WINDOW: " + self.url)
- self.html = self.load(self.url, decode=True)
-
- if self.account:
- self.handlePremium()
- else:
- self.handleFree()
-
- def handleFree(self):
- # hellshare is very generous
- if "You exceeded your today's limit for free download. You can download only 1 files per 24 hours." in self.html:
- t = datetime.datetime.today().replace(hour=1, minute=0, second=0) + datetime.timedelta(
- days=1) - datetime.datetime.today()
- self.setWait(t.seconds, True)
- self.wait()
- self.retry()
-
- while "Server load: 100%" in self.html:
- self.setWait(60)
- self.wait()
- self.html = self.load(self.url, decode=True)
-
- # parse free download url
- found = re.search(self.FREE_URL_PATTERN, self.html)
- if found is None: self.parseError("Free URL)")
- parsed_url = found.group(1)
- self.logDebug("Free URL: %s" % parsed_url)
-
- # decrypt captcha
- found = re.search(self.CAPTCHA_PATTERN, self.html)
- if found is None: self.parseError("Captcha")
- captcha_url = found.group(1)
-
- captcha = self.decryptCaptcha(captcha_url)
- self.logDebug('CAPTCHA_URL:' + captcha_url + ' CAPTCHA:' + captcha)
-
- self.download(parsed_url, post = {"captcha" : captcha, "submit" : "Download"})
-
- # check download
- check = self.checkDownload({
- "wrong_captcha": re.compile(self.FREE_URL_PATTERN)
- })
-
- if check == "wrong_captcha":
- self.invalidCaptcha()
- self.retry()
-
- def handlePremium(self):
- # get premium download url
- found = re.search(self.PREMIUM_URL_PATTERN, self.html)
- if found is None: self.fail("Parse error (URL)")
- download_url = found.group(1)
+ self.url = "http://www.hellshare.com" + found.group(1)
+ self.logDebug("DOWNLOAD URL: " + self.url)
# check credit
if self.DOWNLOAD_AGAIN_PATTERN in self.html:
@@ -113,13 +60,12 @@ class HellshareCz(SimpleHoster):
found = re.search(self.CREDIT_LEFT_PATTERN, self.html)
credits_left = int(found.group(1)) if found else (self.account.getAccountInfo(self.user, True)["trafficleft"] / 1024)
file_credits = ceil(self.pyfile.size / float(1024 ** 2))
-
+
if credits_left < file_credits:
- self.logError("Not enough credit left for user %s: %d (%d needed). Downloading as free user." % (self.user, credits_left, file_credits))
- self.resetAccount()
+ self.fail("Not enough credit left for user %s: %d (%d needed)." % (self.user, credits_left, file_credits))
else:
self.logInfo("Downloading file for %d credits, %d credits left" % (file_credits, credits_left))
- self.download(download_url)
+ self.download(self.url)
-getInfo = create_getInfo(HellshareCz) \ No newline at end of file
+getInfo = create_getInfo(HellshareCz)
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index a4a7c5efa..cfc9f2b43 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -31,17 +31,17 @@ def replace_patterns(string, ruleslist):
string = re.sub(rf, rt, string)
#self.logDebug(rf, rt, string)
return string
-
+
def set_cookies(cj, cookies):
for cookie in cookies:
if isinstance(cookie, tuple) and len(cookie) == 3:
domain, name, value = cookie
cj.setCookie(domain, name, value)
-
+
def parseHtmlTagAttrValue(attr_name, tag):
- m = re.search(r"%s\s*=\s*([\"']?)((?<=\")[^\"]+|(?<=')[^']+|[^>\s\"'][^>\s]*)\1" % attr_name, tag, re.I)
+ m = re.search(r"%s\s*=\s*([\"']?)((?<=\")[^\"]+|(?<=')[^']+|[^>\s\"'][^>\s]*)\1" % attr_name, tag, re.I)
return m.group(2) if m else None
-
+
def parseHtmlForm(attr_str, html, input_names=None):
for form in re.finditer(r"(?P<tag><form[^>]*%s[^>]*>)(?P<content>.*?)</?(form|body|html)[^>]*>" % attr_str, html, re.S | re.I):
inputs = {}
@@ -54,50 +54,42 @@ def parseHtmlForm(attr_str, html, input_names=None):
inputs[name] = inputtag.group(3) or ''
else:
inputs[name] = value
-
+
if isinstance(input_names, dict):
# check input attributes
for key, val in input_names.items():
if key in inputs:
if isinstance(val, basestring) and inputs[key] == val:
- print "MATCH STRING", val, inputs[key]
- continue
+ continue
elif isinstance(val, tuple) and inputs[key] in val:
- print "MATCH TUPLE", val, inputs[key]
continue
elif hasattr(val, "search") and re.match(val, inputs[key]):
- print "MATCH REGEXP", val, inputs[key]
continue
- print "NO MATCH", inputs, input_names
break # attibute value does not match
else:
- print "NO KEY", inputs, input_names
break # attibute name does not match
- else:
- print "ALL MATCH", inputs, input_names
- return action, inputs # passed attribute check
+ else:
+ return action, inputs # passed attribute check
else:
- # no attribute check
- print "NOCHECK", inputs, input_names, type(input_names)
- return action, inputs
-
- print "NONE", inputs
+ # no attribute check
+ return action, inputs
+
return {}, None # no matching form found
-def parseFileInfo(self, url = '', html = ''):
+def parseFileInfo(self, url = '', html = ''):
info = {"name" : url, "size" : 0, "status" : 3}
-
- if hasattr(self, "pyfile"):
- url = self.pyfile.url
+
+ if hasattr(self, "pyfile"):
+ url = self.pyfile.url
if hasattr(self, "req") and self.req.http.code == '404':
info['status'] = 1
else:
if not html and hasattr(self, "html"): html = self.html
- if isinstance(self.SH_BROKEN_ENCODING, (str, unicode)):
+ if isinstance(self.SH_BROKEN_ENCODING, (str, unicode)):
html = unicode(html, self.SH_BROKEN_ENCODING)
if hasattr(self, "html"): self.html = html
-
+
if hasattr(self, "FILE_OFFLINE_PATTERN") and re.search(self.FILE_OFFLINE_PATTERN, html):
# File offline
info['status'] = 1
@@ -107,7 +99,7 @@ def parseFileInfo(self, url = '', html = ''):
info.update(re.match(self.__pattern__, url).groupdict())
except:
pass
-
+
for pattern in ("FILE_INFO_PATTERN", "FILE_NAME_PATTERN", "FILE_SIZE_PATTERN"):
try:
info.update(re.search(getattr(self, pattern), html).groupdict())
@@ -154,7 +146,7 @@ class PluginParseError(Exception):
class SimpleHoster(Hoster):
__name__ = "SimpleHoster"
- __version__ = "0.27"
+ __version__ = "0.28"
__pattern__ = None
__type__ = "hoster"
__description__ = """Base hoster plugin"""
@@ -172,13 +164,13 @@ class SimpleHoster(Hoster):
FILE_SIZE_REPLACEMENTS = []
FILE_NAME_REPLACEMENTS = [("&#?\w+;", fixup)]
FILE_URL_REPLACEMENTS = []
-
+
SH_BROKEN_ENCODING = False # Set to True or encoding name if encoding in http header is not correct
SH_COOKIES = True # or False or list of tuples [(domain, name, value)]
SH_CHECK_TRAFFIC = False # True = force check traffic left for a premium account
-
+
def init(self):
- self.file_info = {}
+ self.file_info = {}
def setup(self):
self.resumeDownload = self.multiDL = True if self.premium else False
@@ -186,6 +178,7 @@ class SimpleHoster(Hoster):
def process(self, pyfile):
pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS)
+ self.req.setOption("timeout", 120)
self.html = self.load(pyfile.url, decode = not self.SH_BROKEN_ENCODING, cookies = self.SH_COOKIES)
self.getFileInfo()
if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()):
@@ -193,13 +186,17 @@ class SimpleHoster(Hoster):
else:
self.handleFree()
+ def load(self, url, get={}, post={}, ref=True, cookies=True, just_header=False, decode=False):
+ if type(url) == unicode: url = url.encode('utf8')
+ return Hoster.load(self, url=url, get=get, post=post, ref=ref, cookies=cookies, just_header=just_header, decode=decode)
+
def getFileInfo(self):
self.logDebug("URL: %s" % self.pyfile.url)
if hasattr(self, "TEMP_OFFLINE_PATTERN") and re.search(self.TEMP_OFFLINE_PATTERN, self.html):
self.tempOffline()
name, size, status = parseFileInfo(self)[:3]
-
+
if status == 1:
self.offline()
elif status != 2:
@@ -227,28 +224,28 @@ class SimpleHoster(Hoster):
def parseError(self, msg):
raise PluginParseError(msg)
-
+
def longWait(self, wait_time = None, max_tries = 3):
if wait_time and isinstance(wait_time, (int, long, float)):
time_str = "%dh %dm" % divmod(wait_time / 60, 60)
else:
wait_time = 900
time_str = "(unknown time)"
- max_tries = 100
-
+ max_tries = 100
+
self.logInfo("Download limit reached, reconnect or wait %s" % time_str)
-
+
self.setWait(wait_time, True)
self.wait()
- self.retry(max_tries = max_tries, reason="Download limit reached")
+ self.retry(max_tries = max_tries, reason="Download limit reached")
def parseHtmlForm(self, attr_str='', input_names=None):
return parseHtmlForm(attr_str, self.html, input_names)
-
- def checkTrafficLeft(self):
+
+ def checkTrafficLeft(self):
traffic = self.account.getAccountInfo(self.user, True)["trafficleft"]
if traffic == -1:
return True
size = self.pyfile.size / 1024
- self.logInfo("Filesize: %i KiB, Traffic left for user %s: %i KiB" % (size, self.user, traffic))
+ self.logInfo("Filesize: %i KiB, Traffic left for user %s: %i KiB" % (size, self.user, traffic))
return size <= traffic \ No newline at end of file