diff options
Diffstat (limited to 'module/plugins/hoster/UploadedTo.py')
-rw-r--r-- | module/plugins/hoster/UploadedTo.py | 268 |
1 files changed, 80 insertions, 188 deletions
diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py index e41ae2e34..9aef13cde 100644 --- a/module/plugins/hoster/UploadedTo.py +++ b/module/plugins/hoster/UploadedTo.py @@ -1,236 +1,128 @@ # -*- coding: utf-8 -*- - -# Test links (random.bin): +# +# Test links: # http://ul.to/044yug9o # http://ul.to/gzfhd0xs import re -from time import sleep -from module.utils import html_unescape, parseFileSize +from time import sleep -from module.plugins.Hoster import Hoster from module.network.RequestFactory import getURL -from module.plugins.Plugin import chunks from module.plugins.internal.CaptchaService import ReCaptcha +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo -key = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=".decode('base64') - - -def getID(url): - """ returns id from file url""" - m = re.match(UploadedTo.__pattern__, url) - return m.group('ID') +class UploadedTo(SimpleHoster): + __name__ = "UploadedTo" + __type__ = "hoster" + __version__ = "0.78" -def getAPIData(urls): - post = {"apikey": key} + __pattern__ = r'https?://(?:www\.)?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)' - idMap = {} + __description__ = """Uploaded.net hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - for i, url in enumerate(urls): - id = getID(url) - post["id_%s" % i] = id - idMap[id] = url - for _ in xrange(5): - api = unicode(getURL("http://uploaded.net/api/filemultiple", post=post, decode=False), 'iso-8859-1') - if api != "can't find request": - break - else: - sleep(3) + API_KEY = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=" #@NOTE: base64 encoded - result = {} + URL_REPLACEMENTS = [(__pattern__ + ".*", r'http://uploaded.net/file/\g<ID>')] - if api: - for line in api.splitlines(): - data = line.split(",", 4) - if data[1] in idMap: - result[data[1]] = (data[0], data[2], data[4], data[3], idMap[data[1]]) + INFO_PATTERN = r'<a href="file/(?P<ID>\w+)" id="filename">(?P<N>[^<]+)</a> \s*<small[^>]*>(?P<S>[^<]+)</small>' + OFFLINE_PATTERN = r'<small class="cL">Error: 404' - return result + LINK_PREMIUM_PATTERN = r'<div class="tfree".*\s*<form method="post" action="(.+?)"' + DL_LIMIT_ERROR = r'You have reached the max. number of possible free downloads for this hour' -def parseFileInfo(self, url='', html=''): - if not html and hasattr(self, "html"): - html = self.html - name = url - size = 0 - fileid = None + @classmethod + def apiInfo(cls, url="", get={}, post={}): + info = super(UploadedTo, cls).apiInfo(url) - if re.search(self.OFFLINE_PATTERN, html): - # File offline - status = 1 - else: - m = re.search(self.FILE_INFO_PATTERN, html) - if m: - name, fileid = html_unescape(m.group('N')), m.group('ID') - size = parseFileSize(m.group('S')) - status = 2 - else: - status = 3 + for _i in xrange(5): + api = getURL("http://uploaded.net/api/filemultiple", + post={"apikey": cls.API_KEY.decode('base64'), 'id_0': re.match(cls.__pattern__, url).group('ID')}, + decode=True) + if api != "can't find request": + api = api.splitlines()[0].split(",", 4) - return name, size, status, fileid + if api[0] == "online": + info.update({'name': api[4], 'size': api[2], 'status': 2}) + elif api[0] == "offline": + info['status'] = 1 -def getInfo(urls): - for chunk in chunks(urls, 80): - result = [] + break + else: + sleep(3) - api = getAPIData(chunk) + return info - for data in api.itervalues(): - if data[0] == "online": - result.append((html_unescape(data[2]), data[1], 2, data[4])) - elif data[0] == "offline": - result.append((data[4], 0, 1, data[4])) + def setup(self): + self.multiDL = self.resumeDownload = self.premium + self.chunkLimit = 1 # critical problems with more chunks + self.load("http://uploaded.net/language/en", just_header=True) - yield result + def checkErrors(self): + if 'var free_enabled = false;' in self.html: + self.logError(_("Free-download capacities exhausted")) + self.retry(24, 5 * 60) -class UploadedTo(Hoster): - __name__ = "UploadedTo" - __type__ = "hoster" - __pattern__ = r'https?://(?:www\.)?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)' - __version__ = "0.73" - __description__ = """Uploaded.net hoster plugin""" - __author_name__ = ("spoob", "mkaay", "zoidberg", "netpok", "stickell") - __author_mail__ = ("spoob@pyload.org", "mkaay@mkaay.de", "zoidberg@mujmail.cz", - "netpok@gmail.com", "l.stickell@yahoo.it") + m = re.search(r"Current waiting period: <span>(\d+)</span> seconds", self.html) + if m: + self.wait(m.group(1)) + else: + self.fail(_("File not downloadable for free users")) - FILE_INFO_PATTERN = r'<a href="file/(?P<ID>\w+)" id="filename">(?P<N>[^<]+)</a> \s*<small[^>]*>(?P<S>[^<]+)</small>' - OFFLINE_PATTERN = r'<small class="cL">Error: 404</small>' - DL_LIMIT_PATTERN = r'You have reached the max. number of possible free downloads for this hour' + if "limit-size" in self.html: + self.fail(_("File too big for free download")) - def setup(self): - self.multiDL = self.resumeDownload = self.premium - self.chunkLimit = 1 # critical problems with more chunks + elif "limit-slot" in self.html: # Temporary restriction so just wait a bit + self.wait(30 * 60, True) + self.retry() - self.fileID = getID(self.pyfile.url) - self.pyfile.url = "http://uploaded.net/file/%s" % self.fileID + elif "limit-parallel" in self.html: + self.fail(_("Cannot download in parallel")) - def process(self, pyfile): - self.load("http://uploaded.net/language/en", just_header=True) + elif "limit-dl" in self.html or self.DL_LIMIT_ERROR in self.html: # limit-dl + self.wait(3 * 60 * 60, True) + self.retry() - api = getAPIData([pyfile.url]) + elif '"err":"captcha"' in self.html: + self.invalidCaptcha() - # TODO: fallback to parse from site, because api sometimes delivers wrong status codes - if not api: - self.logWarning("No response for API call") + def handleFree(self, pyfile): + self.html = self.load("http://uploaded.net/js/download.js", decode=True) - self.html = unicode(self.load(pyfile.url, decode=False), 'iso-8859-1') - name, size, status, self.fileID = parseFileInfo(self) - self.logDebug(name, size, status, self.fileID) - if status == 1: - self.offline() - elif status == 2: - pyfile.name, pyfile.size = name, size - else: - self.fail('Parse error - file info') - elif api == 'Access denied': - self.fail(_("API key invalid")) + recaptcha = ReCaptcha(self) + response, challenge = recaptcha.challenge() - else: - if self.fileID not in api: - self.offline() + self.html = self.load("http://uploaded.net/io/ticket/captcha/%s" % self.info['pattern']['ID'], + post={'recaptcha_challenge_field': challenge, + 'recaptcha_response_field' : response}) - self.data = api[self.fileID] - if self.data[0] != "online": - self.offline() + if "type:'download'" in self.html: + self.correctCaptcha() + try: + self.link = re.search("url:'([^']+)", self.html).group(1) - pyfile.name = html_unescape(self.data[2]) + except Exception: + pass - # pyfile.name = self.get_file_name() + self.checkErrors() - if self.premium: - self.handlePremium() - else: - self.handleFree() - - def handlePremium(self): - info = self.account.getAccountInfo(self.user, True) - self.logDebug("%(name)s: Use Premium Account (%(left)sGB left)" % {"name": self.__name__, - "left": info['trafficleft'] / 1024 / 1024}) - if int(self.data[1]) / 1024 > info['trafficleft']: - self.logInfo(_("%s: Not enough traffic left" % self.__name__)) - self.account.empty(self.user) - self.resetAccount() - self.fail(_("Traffic exceeded")) - - header = self.load("http://uploaded.net/file/%s" % self.fileID, just_header=True) - if "location" in header: - #Direct download - print "Direct Download: " + header['location'] - self.download(header['location']) - else: - #Indirect download - self.html = self.load("http://uploaded.net/file/%s" % self.fileID) - m = re.search(r'<div class="tfree".*\s*<form method="post" action="(.*?)"', self.html) - if m is None: - self.fail("Download URL not m. Try to enable direct downloads.") - url = m.group(1) - print "Premium URL: " + url - self.download(url, post={}) - - def handleFree(self): - self.html = self.load(self.pyfile.url, decode=True) - if 'var free_enabled = false;' in self.html: - self.logError("Free-download capacities exhausted.") - self.retry(max_tries=24, wait_time=5 * 60) + def checkFile(self): + if self.checkDownload({'limit-dl': self.DL_LIMIT_ERROR}): + self.wait(3 * 60 * 60, True) + self.retry() - m = re.search(r"Current waiting period: <span>(\d+)</span> seconds", self.html) - if m is None: - self.fail("File not downloadable for free users") - self.setWait(int(m.group(1))) - - js = self.load("http://uploaded.net/js/download.js", decode=True) - - challengeId = re.search(r'Recaptcha\.create\("([^"]+)', js) - - url = "http://uploaded.net/io/ticket/captcha/%s" % self.fileID - downloadURL = "" - - for _ in xrange(5): - re_captcha = ReCaptcha(self) - challenge, result = re_captcha.challenge(challengeId.group(1)) - options = {"recaptcha_challenge_field": challenge, "recaptcha_response_field": result} - self.wait() - - result = self.load(url, post=options) - self.logDebug("result: %s" % result) - - if "limit-size" in result: - self.fail("File too big for free download") - elif "limit-slot" in result: # Temporary restriction so just wait a bit - self.setWait(30 * 60, True) - self.wait() - self.retry() - elif "limit-parallel" in result: - self.fail("Cannot download in parallel") - elif self.DL_LIMIT_PATTERN in result: # limit-dl - self.setWait(3 * 60 * 60, True) - self.wait() - self.retry() - elif '"err":"captcha"' in result: - self.logError("ul.net captcha is disabled") - self.invalidCaptcha() - elif "type:'download'" in result: - self.correctCaptcha() - downloadURL = re.search("url:'([^']+)", result).group(1) - break - else: - self.fail("Unknown error '%s'" % result) + return super(UploadedTo, self).checkFile() - if not downloadURL: - self.fail("No Download url retrieved/all captcha attempts failed") - self.download(downloadURL, disposition=True) - check = self.checkDownload({"limit-dl": self.DL_LIMIT_PATTERN}) - if check == "limit-dl": - self.setWait(3 * 60 * 60, True) - self.wait() - self.retry() +getInfo = create_getInfo(UploadedTo) |