diff options
Diffstat (limited to 'module')
142 files changed, 1355 insertions, 1350 deletions
diff --git a/module/plugins/accounts/AlldebridCom.py b/module/plugins/accounts/AlldebridCom.py index 32113c890..12d0582a8 100644 --- a/module/plugins/accounts/AlldebridCom.py +++ b/module/plugins/accounts/AlldebridCom.py @@ -26,8 +26,8 @@ class AlldebridCom(Account): def grab_hosters(self, user, password, data): html = self.load("https://www.alldebrid.com/api.php", - get={'action': "get_host"}).replace("\"", "").strip() - return [x.strip() for x in html.split(",") if x.strip()] + get={'action': "get_host"}) + return [x for x in map(str.strip, html.replace("\"", "").split(",")) if x] def grab_info(self, user, password, data): diff --git a/module/plugins/accounts/DebridItaliaCom.py b/module/plugins/accounts/DebridItaliaCom.py index 3e9a5e283..50d849a98 100644 --- a/module/plugins/accounts/DebridItaliaCom.py +++ b/module/plugins/accounts/DebridItaliaCom.py @@ -35,7 +35,7 @@ class DebridItaliaCom(Account): if 'Account premium not activated' not in html: m = re.search(self.WALID_UNTIL_PATTERN, html) - if m: + if m is not None: validuntil = time.mktime(time.strptime(m.group(1), "%d/%m/%Y %H:%M")) info = {'premium': True, 'validuntil': validuntil, 'trafficleft': -1} else: diff --git a/module/plugins/accounts/FastshareCz.py b/module/plugins/accounts/FastshareCz.py index a6a2e2ac6..68c65bd3f 100644 --- a/module/plugins/accounts/FastshareCz.py +++ b/module/plugins/accounts/FastshareCz.py @@ -29,7 +29,7 @@ class FastshareCz(Account): html = self.load("http://www.fastshare.cz/user") m = re.search(self.CREDIT_PATTERN, html) - if m: + if m is not None: trafficleft = self.parse_traffic(m.group(1)) premium = bool(trafficleft) diff --git a/module/plugins/accounts/FilefactoryCom.py b/module/plugins/accounts/FilefactoryCom.py index 0bb814039..0f8f709c6 100644 --- a/module/plugins/accounts/FilefactoryCom.py +++ b/module/plugins/accounts/FilefactoryCom.py @@ -26,7 +26,7 @@ class FilefactoryCom(Account): html = self.load("http://www.filefactory.com/account/") m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: premium = True validuntil = re.sub(self.VALID_UNTIL_PATTERN, '\g<D> \g<M> \g<Y>', m.group(0)) validuntil = time.mktime(time.strptime(validuntil, "%d %b %Y")) diff --git a/module/plugins/accounts/FilejungleCom.py b/module/plugins/accounts/FilejungleCom.py index a7a1c3f56..230aa9939 100644 --- a/module/plugins/accounts/FilejungleCom.py +++ b/module/plugins/accounts/FilejungleCom.py @@ -28,7 +28,7 @@ class FilejungleCom(Account): def grab_info(self, user, password, data): html = self.load(self.URL + "dashboard.php") m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: + if m is not None: premium = True validuntil = time.mktime(time.strptime(m.group(1), "%d %b %Y")) else: diff --git a/module/plugins/accounts/FreakshareCom.py b/module/plugins/accounts/FreakshareCom.py index 42551b732..a319096db 100644 --- a/module/plugins/accounts/FreakshareCom.py +++ b/module/plugins/accounts/FreakshareCom.py @@ -26,7 +26,7 @@ class FreakshareCom(Account): try: m = re.search(r'ltig bis:</td>\s*<td><b>([\d.:-]+)</b></td>', html, re.M) - validuntil = time.mktime(time.strptime(m.group(1).strip(), "%d.%m.%Y - %H:%M")) + validuntil = time.mktime(time.strptime(m.group(1), "%d.%m.%Y - %H:%M")) except Exception: pass diff --git a/module/plugins/accounts/FreeWayMe.py b/module/plugins/accounts/FreeWayMe.py index 536280acc..b554f592a 100644 --- a/module/plugins/accounts/FreeWayMe.py +++ b/module/plugins/accounts/FreeWayMe.py @@ -20,11 +20,9 @@ class FreeWayMe(Account): def grab_hosters(self, user, password, data): - hostis = self.load("http://www.free-way.bz/ajax/jd.php", - get={'id' : 3, - 'user': user, - 'pass': password}).replace("\"", "") #@TODO: Revert to `https` in 0.4.10 - return [x.strip() for x in hostis.split(",") if x.strip()] + html = self.load("http://www.free-way.bz/ajax/jd.php", + get={'id' : 3, 'user': user, 'pass': password}) #@TODO: Revert to `https` in 0.4.10 + return [x for x in map(str.strip, html.replace("\"", "").split(",")) if x] def grab_info(self, user, password, data): diff --git a/module/plugins/accounts/FshareVn.py b/module/plugins/accounts/FshareVn.py index 4e078ccc9..24a858274 100644 --- a/module/plugins/accounts/FshareVn.py +++ b/module/plugins/accounts/FshareVn.py @@ -33,7 +33,7 @@ class FshareVn(Account): return {'validuntil': -1, 'trafficleft': trafficleft, 'premium': True} m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: premium = True validuntil = time.mktime(time.strptime(m.group(1), '%I:%M:%S %p %d-%m-%Y')) trafficleft = self.get_traffic_left() diff --git a/module/plugins/accounts/Keep2ShareCc.py b/module/plugins/accounts/Keep2ShareCc.py index e76ec212c..32bccc2e4 100644 --- a/module/plugins/accounts/Keep2ShareCc.py +++ b/module/plugins/accounts/Keep2ShareCc.py @@ -33,7 +33,7 @@ class Keep2ShareCc(Account): html = self.load("http://keep2share.cc/site/profile.html") m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: expiredate = m.group(1).strip() self.log_debug("Expire date: " + expiredate) @@ -51,7 +51,7 @@ class Keep2ShareCc(Account): premium = True if validuntil > time.mktime(time.gmtime()) else False m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: + if m is not None: try: trafficleft = self.parse_traffic(m.group(1)) diff --git a/module/plugins/accounts/MegaRapidCz.py b/module/plugins/accounts/MegaRapidCz.py index 00ffcb742..050e3e4c6 100644 --- a/module/plugins/accounts/MegaRapidCz.py +++ b/module/plugins/accounts/MegaRapidCz.py @@ -29,16 +29,16 @@ class MegaRapidCz(Account): htmll = self.load("http://megarapid.cz/mujucet/") m = re.search(self.LIMITDL_PATTERN, htmll) - if m: + if m is not None: data['options']['limitDL'] = [int(m.group(1))] m = re.search(self.VALID_UNTIL_PATTERN, htmll) - if m: + if m is not None: validuntil = time.mktime(time.strptime(m.group(1), "%d.%m.%Y - %H:%M")) return {'premium': True, 'trafficleft': -1, 'validuntil': validuntil} m = re.search(self.TRAFFIC_LEFT_PATTERN, htmll) - if m: + if m is not None: trafficleft = float(m.group(1)) * (1 << 20) return {'premium': True, 'trafficleft': trafficleft, 'validuntil': -1} diff --git a/module/plugins/accounts/MegaRapidoNet.py b/module/plugins/accounts/MegaRapidoNet.py index 44b154344..d8291e0e2 100644 --- a/module/plugins/accounts/MegaRapidoNet.py +++ b/module/plugins/accounts/MegaRapidoNet.py @@ -117,7 +117,7 @@ class MegaRapidoNet(Account): self.fail_login() else: m = re.search(self.USER_ID_PATTERN, html) - if m: + if m is not None: data['uid'] = m.group(1) else: self.fail_login("Couldn't find the user ID") diff --git a/module/plugins/accounts/MyfastfileCom.py b/module/plugins/accounts/MyfastfileCom.py index 75fd9fda9..eff112a2f 100644 --- a/module/plugins/accounts/MyfastfileCom.py +++ b/module/plugins/accounts/MyfastfileCom.py @@ -46,5 +46,4 @@ class MyfastfileCom(Account): self.json_data = json_loads(html) if self.json_data['status'] != 'ok': - self.log_error(_('Invalid login. The password to use is the API-Password you find in your "My Account" page')) - self.fail_login() + self.fail_login(_("Invalid username or password")) diff --git a/module/plugins/accounts/NitroflareCom.py b/module/plugins/accounts/NitroflareCom.py index 11a3a43e7..70804d4e9 100644 --- a/module/plugins/accounts/NitroflareCom.py +++ b/module/plugins/accounts/NitroflareCom.py @@ -33,7 +33,7 @@ class NitroflareCom(Account): get={'s': "premium"}) m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: expiredate = m.group(1).strip() self.log_debug("Time Left: " + expiredate) @@ -54,7 +54,7 @@ class NitroflareCom(Account): validuntil = -1 m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: + if m is not None: try: trafficleft = self.parse_traffic(str(max(0, 50 - float(m.group(1)))) + " GB") diff --git a/module/plugins/accounts/NowVideoSx.py b/module/plugins/accounts/NowVideoSx.py index 3d8484b8b..36d26930a 100644 --- a/module/plugins/accounts/NowVideoSx.py +++ b/module/plugins/accounts/NowVideoSx.py @@ -28,7 +28,7 @@ class NowVideoSx(Account): html = self.load("http://www.nowvideo.sx/premium.php") m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: expiredate = m.group(1).strip() self.log_debug("Expire date: " + expiredate) diff --git a/module/plugins/accounts/OneFichierCom.py b/module/plugins/accounts/OneFichierCom.py index 9be982bee..0249f2b93 100644 --- a/module/plugins/accounts/OneFichierCom.py +++ b/module/plugins/accounts/OneFichierCom.py @@ -30,7 +30,7 @@ class OneFichierCom(Account): html = self.load("https://1fichier.com/console/abo.pl") m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: expiredate = m.group(1) self.log_debug("Expire date: " + expiredate) diff --git a/module/plugins/accounts/OverLoadMe.py b/module/plugins/accounts/OverLoadMe.py index 60dddeb5a..02d0d2649 100644 --- a/module/plugins/accounts/OverLoadMe.py +++ b/module/plugins/accounts/OverLoadMe.py @@ -21,8 +21,8 @@ class OverLoadMe(Account): def grab_hosters(self, user, password, data): html = self.load("https://api.over-load.me/hoster.php", - get={'auth': "0001-cb1f24dadb3aa487bda5afd3b76298935329be7700cd7-5329be77-00cf-1ca0135f"}).replace("\"", "").strip() - return [x.strip() for x in html.split(",") if x.strip()] + get={'auth': "0001-cb1f24dadb3aa487bda5afd3b76298935329be7700cd7-5329be77-00cf-1ca0135f"}) + return [x for x in map(str.strip, html.replace("\"", "").split(",")) if x] def grab_info(self, user, password, data): diff --git a/module/plugins/accounts/PremiumTo.py b/module/plugins/accounts/PremiumTo.py index 96f81d075..74859d8a5 100644 --- a/module/plugins/accounts/PremiumTo.py +++ b/module/plugins/accounts/PremiumTo.py @@ -22,9 +22,8 @@ class PremiumTo(Account): def grab_hosters(self, user, password, data): html = self.load("http://premium.to/api/hosters.php", - get={'username': user, - 'password': password}) - return [x.strip() for x in html.replace("\"", "").split(";")] + get={'username': user, 'password': password}) + return [x for x in map(str.strip, html.replace("\"", "").split(",")) if x] def grab_info(self, user, password, data): diff --git a/module/plugins/accounts/QuickshareCz.py b/module/plugins/accounts/QuickshareCz.py index 74377a052..19cde51c4 100644 --- a/module/plugins/accounts/QuickshareCz.py +++ b/module/plugins/accounts/QuickshareCz.py @@ -23,7 +23,7 @@ class QuickshareCz(Account): html = self.load("http://www.quickshare.cz/premium") m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: + if m is not None: trafficleft = self.parse_traffic(m.group(1)) premium = True if trafficleft else False else: diff --git a/module/plugins/accounts/RapiduNet.py b/module/plugins/accounts/RapiduNet.py index 2566aacf6..c11eb9214 100644 --- a/module/plugins/accounts/RapiduNet.py +++ b/module/plugins/accounts/RapiduNet.py @@ -37,11 +37,11 @@ class RapiduNet(Account): premium = True m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: validuntil = time.time() + (86400 * int(m.group(1))) m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: + if m is not None: trafficleft = self.parse_traffic(m.group(1)) return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium} diff --git a/module/plugins/accounts/RealdebridCom.py b/module/plugins/accounts/RealdebridCom.py index c8e020bd6..63ef62da0 100644 --- a/module/plugins/accounts/RealdebridCom.py +++ b/module/plugins/accounts/RealdebridCom.py @@ -21,8 +21,8 @@ class RealdebridCom(Account): def grab_hosters(self, user, password, data): - html = self.load("https://real-debrid.com/api/hosters.php").replace("\"", "").strip() - return [x.strip() for x in html.split(",") if x.strip()] + html = self.load("https://real-debrid.com/api/hosters.php") + return [x for x in map(str.strip, html.replace("\"", "").split(",")) if x] def grab_info(self, user, password, data): diff --git a/module/plugins/accounts/RehostTo.py b/module/plugins/accounts/RehostTo.py index a9f2746c2..2ad4cdceb 100644 --- a/module/plugins/accounts/RehostTo.py +++ b/module/plugins/accounts/RehostTo.py @@ -22,7 +22,7 @@ class RehostTo(Account): html = self.load("http://rehost.to/api.php", get={'cmd' : "get_supported_och_dl", 'long_ses': data['session']}) - return [x.strip() for x in html.replace("\"", "").split(",")] + return [x for x in map(str.strip, html.replace("\"", "").split(",")) if x] def grab_info(self, user, password, data): diff --git a/module/plugins/accounts/ShareonlineBiz.py b/module/plugins/accounts/ShareonlineBiz.py index d7eb14bd6..f5d213ecd 100644 --- a/module/plugins/accounts/ShareonlineBiz.py +++ b/module/plugins/accounts/ShareonlineBiz.py @@ -30,7 +30,7 @@ class ShareonlineBiz(Account): api = dict(line.split("=") for line in res.splitlines() if "=" in line) if not 'a' in api: - self.fail_login(res.strip('*').strip()) + self.fail_login(res.strip('*')) if api['a'].lower() == "not_available": self.fail_login(_("No info available")) diff --git a/module/plugins/accounts/SimplydebridCom.py b/module/plugins/accounts/SimplydebridCom.py index d09ae36ad..bd56dd5ec 100644 --- a/module/plugins/accounts/SimplydebridCom.py +++ b/module/plugins/accounts/SimplydebridCom.py @@ -22,7 +22,7 @@ class SimplydebridCom(Account): def grab_hosters(self, user, password, data): html = self.load("http://simply-debrid.com/api.php", get={'list': 1}) - return [x.strip() for x in html.rstrip(';').replace("\"", "").split(";")] + return [x for x in map(str.strip, html.rstrip(';').replace("\"", "").split(";")) if x] def grab_info(self, user, password, data): diff --git a/module/plugins/accounts/SmoozedCom.py b/module/plugins/accounts/SmoozedCom.py index 16b4fe7fc..1c3da5269 100644 --- a/module/plugins/accounts/SmoozedCom.py +++ b/module/plugins/accounts/SmoozedCom.py @@ -35,7 +35,7 @@ class SmoozedCom(Account): __description__ = """Smoozed.com account plugin""" __license__ = "GPLv3" - __authors__ = [("", "")] + __authors__ = [(None, None)] def grab_hosters(self, user, password, data): diff --git a/module/plugins/accounts/TurbobitNet.py b/module/plugins/accounts/TurbobitNet.py index b73f95fa5..c3edd0c09 100644 --- a/module/plugins/accounts/TurbobitNet.py +++ b/module/plugins/accounts/TurbobitNet.py @@ -22,7 +22,7 @@ class TurbobitNet(Account): html = self.load("http://turbobit.net") m = re.search(r'<u>Turbo Access</u> to ([\d.]+)', html) - if m: + if m is not None: premium = True validuntil = time.mktime(time.strptime(m.group(1), "%d.%m.%Y")) else: diff --git a/module/plugins/accounts/UploadedTo.py b/module/plugins/accounts/UploadedTo.py index c5cd9dd9f..9c3369bd8 100644 --- a/module/plugins/accounts/UploadedTo.py +++ b/module/plugins/accounts/UploadedTo.py @@ -34,20 +34,20 @@ class UploadedTo(Account): premium = True if re.search(self.PREMIUM_PATTERN, html) else False m = re.search(self.VALID_UNTIL_PATTERN, html, re.M) - if m: + if m is not None: expiredate = m.group(1).lower().strip() if expiredate == "unlimited": validuntil = -1 else: m = re.findall(r'(\d+) (week|day|hour)', expiredate) - if m: + if m is not None: validuntil = time.time() for n, u in m: validuntil += float(n) * 60 * 60 * {'week': 168, 'day': 24, 'hour': 1}[u] m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: + if m is not None: traffic = m.groupdict() size = traffic['S'].replace('.', '') unit = traffic['U'].lower() @@ -56,7 +56,7 @@ class UploadedTo(Account): trafficleft = float(size.replace(',', '.')) / 1024 trafficleft *= 1 << 40 else: - trafficleft = self.parse_traffic(size + unit) + trafficleft = self.parse_traffic(size, unit) return {'validuntil' : validuntil, 'trafficleft': trafficleft, diff --git a/module/plugins/accounts/UploadingCom.py b/module/plugins/accounts/UploadingCom.py index cacc8df14..c038d1ebc 100644 --- a/module/plugins/accounts/UploadingCom.py +++ b/module/plugins/accounts/UploadingCom.py @@ -32,7 +32,7 @@ class UploadingCom(Account): premium = False if re.search(self.PREMIUM_PATTERN, html) else True m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: expiredate = m.group(1).strip() self.log_debug("Expire date: " + expiredate) diff --git a/module/plugins/captcha/AdYouLike.py b/module/plugins/captcha/AdYouLike.py index f91b5805c..cac73774a 100644 --- a/module/plugins/captcha/AdYouLike.py +++ b/module/plugins/captcha/AdYouLike.py @@ -76,7 +76,7 @@ class AdYouLike(CaptchaService): try: instructions_visual = challenge['translations'][server['all']['lang']]['instructions_visual'] - result = re.search(u'«(.+?)»', instructions_visual).group(1).strip() + response = re.search(u'«(.+?)»', instructions_visual).group(1).strip() except AttributeError: self.fail(_("AdYouLike result not found")) @@ -87,6 +87,6 @@ class AdYouLike(CaptchaService): '_ayl_token_challenge': challenge['token'], '_ayl_response' : response} - self.log_debug("Result: %s" % result) + self.log_debug("Result: %s" % response) return result diff --git a/module/plugins/captcha/ReCaptcha.py b/module/plugins/captcha/ReCaptcha.py index 5931159c5..a3ac52cb1 100644 --- a/module/plugins/captcha/ReCaptcha.py +++ b/module/plugins/captcha/ReCaptcha.py @@ -31,7 +31,7 @@ class ReCaptcha(CaptchaService): html = data or self.retrieve_data() m = re.search(self.KEY_V2_PATTERN, html) or re.search(self.KEY_V1_PATTERN, html) - if m: + if m is not None: self.key = m.group(1).strip() self.log_debug("Key: %s" % self.key) return self.key diff --git a/module/plugins/captcha/SolveMedia.py b/module/plugins/captcha/SolveMedia.py index 870b5fc10..a5a49b68e 100644 --- a/module/plugins/captcha/SolveMedia.py +++ b/module/plugins/captcha/SolveMedia.py @@ -24,7 +24,7 @@ class SolveMedia(CaptchaService): html = data or self.retrieve_data() m = re.search(self.KEY_PATTERN, html) - if m: + if m is not None: self.key = m.group(1).strip() self.log_debug("Key: %s" % self.key) return self.key diff --git a/module/plugins/crypter/CloudzillaToFolder.py b/module/plugins/crypter/CloudzillaToFolder.py index 6c8ce5917..dc0cdfef2 100644 --- a/module/plugins/crypter/CloudzillaToFolder.py +++ b/module/plugins/crypter/CloudzillaToFolder.py @@ -28,7 +28,7 @@ class CloudzillaToFolder(SimpleHoster): def check_errors(self): m = re.search(self.PASSWORD_PATTERN, self.html) - if m: + if m is not None: self.html = self.load(self.pyfile.url, get={'key': self.get_password()}) if re.search(self.PASSWORD_PATTERN, self.html): diff --git a/module/plugins/crypter/Dereferer.py b/module/plugins/crypter/Dereferer.py index d7dfe52d7..8ecc635ec 100644 --- a/module/plugins/crypter/Dereferer.py +++ b/module/plugins/crypter/Dereferer.py @@ -38,4 +38,4 @@ class Dereferer(SimpleCrypter): def get_links(self): - return [re.match(self.__pattern__, self.pyfile.url).group('LINK').strip()] + return [re.match(self.__pattern__, self.pyfile.url).group('LINK')] diff --git a/module/plugins/crypter/DlProtectCom.py b/module/plugins/crypter/DlProtectCom.py index 0c776ac61..ac45ee4c3 100644 --- a/module/plugins/crypter/DlProtectCom.py +++ b/module/plugins/crypter/DlProtectCom.py @@ -53,7 +53,7 @@ class DlProtectCom(SimpleCrypter): if "Security Code" in self.html: m = re.search(r'/captcha\.php\?key=(.+?)"', self.html) - if m: + if m is not None: captcha_code = self.captcha.decrypt("http://www.dl-protect.com/captcha.php?key=" + m.group(1), input_type="gif") post_req['secure'] = captcha_code diff --git a/module/plugins/crypter/EmbeduploadCom.py b/module/plugins/crypter/EmbeduploadCom.py index 341b3e315..e4a9387ae 100644 --- a/module/plugins/crypter/EmbeduploadCom.py +++ b/module/plugins/crypter/EmbeduploadCom.py @@ -30,7 +30,7 @@ class EmbeduploadCom(Crypter): tmp_links = [] m = re.findall(self.LINK_PATTERN, self.html) - if m: + if m is not None: prefered_set = set(self.get_config('preferedHoster').split('|')) prefered_set = map(lambda s: s.lower().split('.')[0], prefered_set) diff --git a/module/plugins/crypter/FilecryptCc.py b/module/plugins/crypter/FilecryptCc.py index fcabd5ebf..bb9aee1d7 100644 --- a/module/plugins/crypter/FilecryptCc.py +++ b/module/plugins/crypter/FilecryptCc.py @@ -24,8 +24,8 @@ class FilecryptCc(Crypter): __description__ = """Filecrypt.cc decrypter plugin""" __license__ = "GPLv3" - __authors__ = [("zapp-brannigan", "" ), - ("GammaC0de" , None)] + __authors__ = [("zapp-brannigan", "fuerst.reinje@web.de"), + ("GammaC0de" , None )] # URL_REPLACEMENTS = [(r'.html$', ""), (r'$', ".html")] #@TODO: Extend SimpleCrypter @@ -138,9 +138,9 @@ class FilecryptCc(Crypter): if captcha_key: try: response, challenge = recaptcha.challenge(captcha_key) + except Exception: - self.captcha.invalid() - self.retry() + self.retry_captcha() self.site_with_links = self.load(self.pyfile.url, post={'g-recaptcha-response': response}) @@ -149,8 +149,7 @@ class FilecryptCc(Crypter): self.retry() if re.search(self.CAPTCHA_PATTERN, self.site_with_links): - self.captcha.invalid() - self.retry() + self.retry_captcha() else: self.log_info(_("No captcha found")) diff --git a/module/plugins/crypter/FreakhareComFolder.py b/module/plugins/crypter/FreakhareComFolder.py index f7f1946f4..e939fe467 100644 --- a/module/plugins/crypter/FreakhareComFolder.py +++ b/module/plugins/crypter/FreakhareComFolder.py @@ -29,7 +29,7 @@ class FreakhareComFolder(SimpleCrypter): def load_page(self, page_n): if not hasattr(self, 'f_id') and not hasattr(self, 'f_md5'): m = re.search(r'http://freakshare.com/\?x=folder&f_id=(\d+)&f_md5=(\w+)', self.html) - if m: + if m is not None: self.f_id = m.group(1) self.f_md5 = m.group(2) return self.load('http://freakshare.com/', get={'x': 'folder', diff --git a/module/plugins/crypter/LinkCryptWs.py b/module/plugins/crypter/LinkCryptWs.py index 0d8590860..d61c9d3dd 100644 --- a/module/plugins/crypter/LinkCryptWs.py +++ b/module/plugins/crypter/LinkCryptWs.py @@ -160,13 +160,12 @@ class LinkCryptWs(Crypter): def handle_errors(self): if self.is_password_protected(): - self.fail(_("Incorrect password")) + self.fail(_("Wrong password")) def handle_captcha_errors(self): - if "Your choice was wrong!" in self.html: - self.captcha.invalid() - self.retry() + if "Your choice was wrong" in self.html: + self.retry_captcha() else: self.captcha.correct() @@ -244,7 +243,7 @@ class LinkCryptWs(Crypter): if not clink: continue - self.log_debug("clink avaible") + self.log_debug("clink found") package_name, folder_name = self.get_package_info() self.log_debug("Added package with name %s.%s and container link %s" %( package_name, type, clink.group(1))) @@ -266,7 +265,7 @@ class LinkCryptWs(Crypter): break if cnl_line: - self.log_debug("cnl_line gefunden") + self.log_debug("cnl_line found") try: cnl_section = self.handle_javascript(cnl_line) diff --git a/module/plugins/crypter/LinkdecrypterCom.py b/module/plugins/crypter/LinkdecrypterCom.py index 0f0c3e7a9..c16ec0b6e 100644 --- a/module/plugins/crypter/LinkdecrypterCom.py +++ b/module/plugins/crypter/LinkdecrypterCom.py @@ -39,11 +39,11 @@ class LinkdecrypterCom(MultiCrypter): while retries: m = re.search(self.TEXTAREA_PATTERN, self.html, re.S) - if m: + if m is not None: self.urls = [x for x in m.group(1).splitlines() if '[LINK-ERROR]' not in x] m = re.search(self.CAPTCHA_PATTERN, self.html) - if m: + if m is not None: captcha_url = 'http://linkdecrypter.com/' + m.group(1) result_type = "positional" if "getPos" in m.group(2) else "textual" diff --git a/module/plugins/crypter/LixIn.py b/module/plugins/crypter/LixIn.py index 2d26564e8..ecc92a8d3 100644 --- a/module/plugins/crypter/LixIn.py +++ b/module/plugins/crypter/LixIn.py @@ -43,16 +43,13 @@ class LixIn(Crypter): self.error(_("Link doesn't seem valid")) m = re.search(self.CAPTCHA_PATTERN, self.html) - if m: - for _i in xrange(5): - m = re.search(self.CAPTCHA_PATTERN, self.html) - if m: - self.log_debug("Trying captcha") - captcharesult = self.captcha.decrypt(urlparse.urljoin("http://lix.in/", m.group(1))) - self.html = self.load(url, - post={'capt': captcharesult, 'submit': "submit", 'tiny': id}) - else: - self.log_debug("No captcha/captcha solved") + if m is not None: + captcharesult = self.captcha.decrypt(urlparse.urljoin("http://lix.in/", m.group(1))) + self.html = self.load(url, post={'capt': captcharesult, 'submit': "submit", 'tiny': id}) + + if re.search(self.CAPTCHA_PATTERN, self.html): + self.fail(_("No captcha solved")) + else: self.html = self.load(url, post={'submit': "submit", 'tiny': id}) diff --git a/module/plugins/crypter/MediafireComFolder.py b/module/plugins/crypter/MediafireComFolder.py index 81d880725..f90bc04ea 100644 --- a/module/plugins/crypter/MediafireComFolder.py +++ b/module/plugins/crypter/MediafireComFolder.py @@ -33,13 +33,13 @@ class MediafireComFolder(Crypter): #: Load and parse html html = self.load(pyfile.url) m = re.search(self.LINK_PATTERN, html) - if m: + if m is not None: #: File page self.urls.append("http://www.mediafire.com/file/%s" % m.group(1)) else: #: Folder page m = re.search(self.FOLDER_KEY_PATTERN, html) - if m: + if m is not None: folder_key = m.group(1) self.log_debug("FOLDER KEY: %s" % folder_key) diff --git a/module/plugins/crypter/MultiloadCz.py b/module/plugins/crypter/MultiloadCz.py index d9b6236be..72e9b3a8b 100644 --- a/module/plugins/crypter/MultiloadCz.py +++ b/module/plugins/crypter/MultiloadCz.py @@ -30,11 +30,11 @@ class MultiloadCz(Crypter): if re.match(self.__pattern__, pyfile.url).group(1) == "slozka": m = re.search(self.FOLDER_PATTERN, self.html) - if m: + if m is not None: self.urls.extend(m.group(1).split()) else: m = re.findall(self.LINK_PATTERN, self.html) - if m: + if m is not None: prefered_set = set(self.get_config('usedHoster').split('|')) self.urls.extend(x[1] for x in m if x[0] in prefered_set) diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py index 32c9283f7..dddffbbf2 100644 --- a/module/plugins/crypter/NCryptIn.py +++ b/module/plugins/crypter/NCryptIn.py @@ -121,7 +121,7 @@ class NCryptIn(Crypter): def get_package_info(self): m = re.search(self.NAME_PATTERN, self.html) - if m: + if m is not None: name = folder = m.group('N').strip() self.log_debug("Found name [%s] and folder [%s] in package info" % (name, folder)) else: @@ -177,13 +177,11 @@ class NCryptIn(Crypter): def handle_errors(self): if self.protection_type == "password": if "This password is invalid!" in self.cleaned_html: - self.log_debug("Incorrect password, please set right password on 'Edit package' form and retry") - self.fail(_("Incorrect password, please set right password on 'Edit package' form and retry")) + self.fail(_("Wrong password")) if self.protection_type == "captcha": - if "The securitycheck was wrong!" in self.cleaned_html: - self.captcha.invalid() - self.retry() + if "The securitycheck was wrong" in self.cleaned_html: + self.retry_captcha() else: self.captcha.correct() diff --git a/module/plugins/crypter/RelinkUs.py b/module/plugins/crypter/RelinkUs.py index 641353865..6d8383fee 100644 --- a/module/plugins/crypter/RelinkUs.py +++ b/module/plugins/crypter/RelinkUs.py @@ -154,7 +154,7 @@ class RelinkUs(Crypter): #: Try to get info from web m = re.search(self.FILE_TITLE_REGEX, self.html) - if m: + if m is not None: title = m.group(1).strip() if not self.FILE_NOTITLE in title: name = folder = title @@ -172,14 +172,11 @@ class RelinkUs(Crypter): def handle_errors(self): if self.PASSWORD_ERROR_ROKEN in self.html: - msg = "Incorrect password, please set right password on 'Edit package' form and retry" - self.log_debug(msg) - self.fail(_(msg)) + self.fail(_("Wrong password")) if self.captcha: if self.CAPTCHA_ERROR_ROKEN in self.html: - self.captcha.invalid() - self.retry() + self.retry_captcha() else: self.captcha.correct() @@ -199,7 +196,7 @@ class RelinkUs(Crypter): self.log_debug("Search for CNL2 links") package_links = [] m = re.search(self.CNL2_FORM_REGEX, self.html, re.S) - if m: + if m is not None: cnl2_form = m.group(1) try: (vcrypted, vjk) = self._get_cipher_params(cnl2_form) @@ -216,7 +213,7 @@ class RelinkUs(Crypter): self.log_debug("Search for DLC links") package_links = [] m = re.search(self.DLC_LINK_REGEX, self.html) - if m: + if m is not None: container_url = self.DLC_DOWNLOAD_URL + "?id=%s&dlc=1" % self.fileid self.log_debug("Downloading DLC container link [%s]" % container_url) try: diff --git a/module/plugins/crypter/SafelinkingNet.py b/module/plugins/crypter/SafelinkingNet.py index e2b8471ab..29e1cce4f 100644 --- a/module/plugins/crypter/SafelinkingNet.py +++ b/module/plugins/crypter/SafelinkingNet.py @@ -47,24 +47,25 @@ class SafelinkingNet(Crypter): postData['link-password'] = self.get_password() if "altcaptcha" in self.html: - for _i in xrange(5): - m = re.search(self.SOLVEMEDIA_PATTERN, self.html) - if m: - captchaKey = m.group(1) - captcha = SolveMedia(self) - captchaProvider = "Solvemedia" - else: - self.fail(_("Error parsing captcha")) + m = re.search(self.SOLVEMEDIA_PATTERN, self.html) + if m is not None: + captchaKey = m.group(1) + captcha = SolveMedia(self) + captchaProvider = "Solvemedia" + else: + self.fail(_("Error parsing captcha")) + + response, challenge = captcha.challenge(captchaKey) + postData['adcopy_challenge'] = challenge + postData['adcopy_response'] = response + + self.html = self.load(url, post=postData) - response, challenge = captcha.challenge(captchaKey) - postData['adcopy_challenge'] = challenge - postData['adcopy_response'] = response + if "The CAPTCHA code you entered was wrong" in self.html: + self.retry_captcha() - self.html = self.load(url, post=postData) - if "The password you entered was incorrect" in self.html: - self.fail(_("Incorrect Password")) - if not "The CAPTCHA code you entered was wrong" in self.html: - break + if "The password you entered was incorrect" in self.html: + self.fail(_("Wrong password")) pyfile.package().password = "" soup = BeautifulSoup.BeautifulSoup(self.html) @@ -73,7 +74,7 @@ class SafelinkingNet(Crypter): if "d_links" in s.text: break m = re.search('d_links":(\[.*?\])', s.text) - if m: + if m is not None: linkDict = json_loads(m.group(1)) for link in linkDict: if not "http://" in link['full']: diff --git a/module/plugins/crypter/ShareLinksBiz.py b/module/plugins/crypter/ShareLinksBiz.py index 3316aea56..e372d7c6a 100644 --- a/module/plugins/crypter/ShareLinksBiz.py +++ b/module/plugins/crypter/ShareLinksBiz.py @@ -66,14 +66,18 @@ class ShareLinksBiz(Crypter): def init_file(self, pyfile): url = pyfile.url + if 's2l.biz' in url: url = self.load(url, just_header=True)['location'] + if re.match(self.__pattern__, url): self.base_url = "http://www.%s.biz" % re.match(self.__pattern__, url).group(1) self.file_id = re.match(self.__pattern__, url).group('ID') + else: self.log_debug("Could not initialize, URL [%s] does not match pattern [%s]" % (url, self.__pattern__)) - self.fail("Unsupported download link") + self.fail(_("Unsupported download link")) + self.package = pyfile.package() @@ -81,7 +85,8 @@ class ShareLinksBiz(Crypter): if "No usable content was found" in self.html: self.log_debug("File not found") return False - return True + else: + return True def is_password_protected(self): @@ -121,7 +126,8 @@ class ShareLinksBiz(Crypter): m = re.search(r'<img src="/captcha.gif\?d=(.+?)&PHPSESSID=(.+?)&legend=1"', self.html) if not m: self.log_debug("Captcha url data not found, maybe plugin out of date?") - self.fail("Captcha url data not found") + self.fail(_("Captcha url data not found")) + captchaUrl = self.base_url + '/captcha.gif?d=%s&PHPSESSID=%s' % (m.group(1), m.group(2)) self.log_debug("Waiting user for correct position") coords = self.captcha.decrypt(captchaUrl, input_type="gif", output_type='positional') @@ -130,8 +136,8 @@ class ShareLinksBiz(Crypter): #: Resolve captcha href = self._resolve_coords(coords, captchaMap) if href is None: - self.captcha.invalid() - self.retry(delay=5) + self.retry_captcha(wait=5) + url = self.base_url + href self.html = self.load(url) @@ -155,13 +161,11 @@ class ShareLinksBiz(Crypter): def handle_errors(self): if "The inserted password was wrong" in self.html: - self.log_debug("Incorrect password, please set right password on 'Edit package' form and retry") - self.fail(_("Incorrect password, please set right password on 'Edit package' form and retry")) + self.fail(_("Wrong password")) if self.captcha: if "Your choice was wrong" in self.html: - self.captcha.invalid() - self.retry(delay=5) + self.retry_captcha(wait=5) else: self.captcha.correct() @@ -172,7 +176,7 @@ class ShareLinksBiz(Crypter): #: Extract from web package header title_re = r'<h2><img.*?/>(.*)</h2>' m = re.search(title_re, self.html, re.S) - if m: + if m is not None: title = m.group(1).strip() if 'unnamed' not in title: name = folder = title diff --git a/module/plugins/crypter/UlozToFolder.py b/module/plugins/crypter/UlozToFolder.py index 19569ef31..f2d0e7c17 100644 --- a/module/plugins/crypter/UlozToFolder.py +++ b/module/plugins/crypter/UlozToFolder.py @@ -36,7 +36,7 @@ class UlozToFolder(Crypter): new_links.extend(re.findall(self.LINK_PATTERN, m.group(1))) m = re.search(self.NEXT_PAGE_PATTERN, html) - if m: + if m is not None: html = self.load("http://ulozto.net/" + m.group(1)) else: break diff --git a/module/plugins/hooks/AntiVirus.py b/module/plugins/hooks/AntiVirus.py index b58d0b61d..d7ec69031 100644 --- a/module/plugins/hooks/AntiVirus.py +++ b/module/plugins/hooks/AntiVirus.py @@ -10,23 +10,25 @@ except ImportError: pass from module.plugins.internal.Addon import Addon, Expose, threaded +from module.plugins.internal.Plugin import exists from module.utils import fs_encode, save_join as fs_join class AntiVirus(Addon): __name__ = "AntiVirus" __type__ = "hook" - __version__ = "0.12" + __version__ = "0.13" __status__ = "testing" #@TODO: add trash option (use Send2Trash lib) - __config__ = [("action" , "Antivirus default;Delete;Quarantine", "Manage infected files" , "Antivirus default"), - ("quardir" , "folder" , "Quarantine folder" , "" ), - ("deltotrash", "bool" , "Move to trash (recycle bin) instead delete", True ), - ("scanfailed", "bool" , "Scan incompleted files (failed downloads)" , False ), - ("cmdfile" , "file" , "Antivirus executable" , "" ), - ("cmdargs" , "str" , "Scan options" , "" ), - ("ignore-err", "bool" , "Ignore scan errors" , False )] + __config__ = [("action" , "Antivirus default;Delete;Quarantine", "Manage infected files" , "Antivirus default"), + ("quardir" , "folder" , "Quarantine folder" , "" ), + ("deltotrash", "bool" , "Move to trash instead delete", True ), + ("scanfailed", "bool" , "Scan failed downloads" , False ), + ("avfile" , "file" , "Antivirus executable" , "" ), + ("avargs" , "str" , "Executable arguments" , "" ), + ("avtarget" , "file;folder" , "Scan target" , "file" ), + ("ignore-err", "bool" , "Ignore scan errors" , False )] __description__ = """Scan downloaded files with antivirus program""" __license__ = "GPLv3" @@ -36,12 +38,24 @@ class AntiVirus(Addon): @Expose @threaded def scan(self, pyfile, thread): - file = fs_encode(pyfile.plugin.last_download) - filename = os.path.basename(pyfile.plugin.last_download) - cmdfile = fs_encode(self.get_config('cmdfile')) - cmdargs = fs_encode(self.get_config('cmdargs').strip()) + avfile = fs_encode(self.get_config('avfile')) + avargs = fs_encode(self.get_config('avargs').strip()) - if not os.path.isfile(file) or not os.path.isfile(cmdfile): + if not os.path.isfile(avfile): + self.fail(_("Antivirus executable not found")) + + scanfolder = self.get_config('avtarget') is "folder" + + if scanfolder: + download_folder = self.pyload.config.get("general", "download_folder") + package_folder = pyfile.package().folder if self.pyload.config.get("general", "folder_per_package") else "" + target = fs_join(download_folder, package_folder, pyfile.name) + target_repr = "Folder: " + package_folder or download_folder + else: + target = fs_encode(pyfile.plugin.last_download) + target_repr = "File: " + os.path.basename(pyfile.plugin.last_download) + + if not exists(target): return thread.addActive(pyfile) @@ -49,24 +63,34 @@ class AntiVirus(Addon): pyfile.setProgress(0) try: - p = subprocess.Popen([cmdfile, cmdargs, file], bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p = subprocess.Popen([avfile, avargs, target], + bufsize=-1, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) out, err = map(str.strip, p.communicate()) if out: - self.log_info(filename, out) + self.log_info(target_repr, out) if err: - self.log_warning(filename, err) + self.log_warning(target_repr, err) if not self.get_config('ignore-err'): - self.log_debug("Delete/Quarantine task is aborted") + self.log_debug("Delete/Quarantine task aborted due scan error") return if p.returncode: - pyfile.error = _("Infected file") action = self.get_config('action') + + if scanfolder: + if action is "Antivirus default": + self.log_warning(_("Delete/Quarantine task skipped in folder scan mode") + return + + pyfile.error = _("Infected file") + try: - if action == "Delete": + if action is "Delete": if not self.get_config('deltotrash'): os.remove(file) @@ -87,15 +111,15 @@ class AntiVirus(Addon): else: self.log_debug("Successfully moved file to trash") - elif action == "Quarantine": + elif action is "Quarantine": pyfile.setCustomStatus(_("file moving")) shutil.move(file, self.get_config('quardir')) except (IOError, shutil.Error), e: - self.log_error(filename, action + " action failed!", e) + self.log_error(target_repr, action + " action failed!", e) - elif not out and not err: - self.log_debug(filename, "No infected file found") + elif not err: + self.log_debug(target_repr, "No infected file found") finally: pyfile.setProgress(100) @@ -108,5 +132,5 @@ class AntiVirus(Addon): def download_failed(self, pyfile): #: Check if pyfile is still "failed", maybe might has been restarted in meantime - if pyfile.status == 8 and self.get_config('scanfailed'): + if pyfile.status is 8 and self.get_config('scanfailed'): return self.scan(pyfile) diff --git a/module/plugins/hooks/Captcha9Kw.py b/module/plugins/hooks/Captcha9Kw.py index 2e2685978..656497dd6 100644 --- a/module/plugins/hooks/Captcha9Kw.py +++ b/module/plugins/hooks/Captcha9Kw.py @@ -78,7 +78,6 @@ class Captcha9Kw(Hook): 'cpm' : self.get_config('captchapermin')} for opt in str(self.get_config('hoster_options').split('|')): - details = map(str.strip, opt.split(':')) if not details or details[0].lower() is not pluginname.lower(): @@ -149,6 +148,7 @@ class Captcha9Kw(Hook): time.sleep(5) else: break + else: self.log_debug("Could not send request: %s" % res) result = None @@ -184,6 +184,7 @@ class Captcha9Kw(Hook): break time.sleep(10) + else: self.fail(_("Too many captchas in queue")) @@ -196,9 +197,9 @@ class Captcha9Kw(Hook): for d in details: hosteroption = d.split("=") - if len(hosteroption) > 1 \ - and hosteroption[0].lower() == "timeout" \ - and hosteroption[1].isdigit(): + if len(hosteroption) > 1 and \ + hosteroption[0].lower() == "timeout" and \ + hosteroption[1].isdigit(): timeout = int(hosteroption[1]) break diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py index ba03129e6..591be8b59 100644 --- a/module/plugins/hooks/ClickAndLoad.py +++ b/module/plugins/hooks/ClickAndLoad.py @@ -84,7 +84,7 @@ class ClickAndLoad(Addon): server_socket = ssl.wrap_socket(server_socket) except NameError: - self.log_error(_("pyLoad's webinterface is configured to use HTTPS, Please install python's ssl lib or disable HTTPS")) + self.log_error(_("Missing SSL lib"), _("Please disable HTTPS in pyLoad settings")) client_socket.close() #: Reset the connection. continue diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index 19d8bef94..b5a714533 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -110,22 +110,22 @@ class ExtractArchive(Addon): __version__ = "1.51" __status__ = "testing" - __config__ = [("activated" , "bool" , "Activated" , True ), - ("fullpath" , "bool" , "Extract with full paths" , True ), - ("overwrite" , "bool" , "Overwrite files" , False ), - ("keepbroken" , "bool" , "Try to extract broken archives" , False ), - ("repair" , "bool" , "Repair broken archives (RAR required)" , False ), - ("usepasswordfile", "bool" , "Use password file" , True ), - ("passwordfile" , "file" , "Password file" , "passwords.txt" ), - ("delete" , "bool" , "Delete archive after extraction" , True ), - ("deltotrash" , "bool" , "Move to trash (recycle bin) instead delete", True ), - ("subfolder" , "bool" , "Create subfolder for each package" , False ), - ("destination" , "folder" , "Extract files to folder" , "" ), - ("extensions" , "str" , "Extract archives ending with extension" , "7z,bz2,bzip2,gz,gzip,lha,lzh,lzma,rar,tar,taz,tbz,tbz2,tgz,xar,xz,z,zip"), - ("excludefiles" , "str" , "Don't extract the following files" , "*.nfo,*.DS_Store,index.dat,thumb.db" ), - ("recursive" , "bool" , "Extract archives in archives" , True ), - ("waitall" , "bool" , "Run after all downloads was processed" , False ), - ("renice" , "int" , "CPU priority" , 0 )] + __config__ = [("activated" , "bool" , "Activated" , True ), + ("fullpath" , "bool" , "Extract with full paths" , True ), + ("overwrite" , "bool" , "Overwrite files" , False ), + ("keepbroken" , "bool" , "Try to extract broken archives" , False ), + ("repair" , "bool" , "Repair broken archives (RAR required)" , False ), + ("usepasswordfile", "bool" , "Use password file" , True ), + ("passwordfile" , "file" , "Password file" , "passwords.txt" ), + ("delete" , "bool" , "Delete archive after extraction" , True ), + ("deltotrash" , "bool" , "Move to trash instead delete" , True ), + ("subfolder" , "bool" , "Create subfolder for each package" , False ), + ("destination" , "folder", "Extract files to folder" , "" ), + ("extensions" , "str" , "Extract archives ending with extension", "7z,bz2,bzip2,gz,gzip,lha,lzh,lzma,rar,tar,taz,tbz,tbz2,tgz,xar,xz,z,zip"), + ("excludefiles" , "str" , "Don't extract the following files" , "*.nfo,*.DS_Store,index.dat,thumb.db" ), + ("recursive" , "bool" , "Extract archives in archives" , True ), + ("waitall" , "bool" , "Run after all downloads was processed" , False ), + ("renice" , "int" , "CPU priority" , 0 )] __description__ = """Extract different kind of archives""" __license__ = "GPLv3" diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index ec262e672..312355675 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -79,8 +79,8 @@ class UpdateManager(Addon): if self.get_config('nodebugupdate'): return - if self.get_config('checkperiod') \ - and time.time() - max(self.MIN_CHECK_INTERVAL, self.get_config('checkinterval') * 60 * 60) > self.info['last_check']: + if self.get_config('checkperiod') and \ + time.time() - max(self.MIN_CHECK_INTERVAL, self.get_config('checkinterval') * 60 * 60) > self.info['last_check']: self.update() @@ -275,7 +275,7 @@ class UpdateManager(Addon): if self.pyload.pluginManager.reloadPlugins(updated): exitcode = 1 else: - self.log_warning(_("pyLoad restart required to reload the updated plugins")) + self.log_warning(_("You have to restart pyLoad to reload the updated plugins")) self.info['plugins'] = True exitcode = 2 diff --git a/module/plugins/hoster/AndroidfilehostCom.py b/module/plugins/hoster/AndroidfilehostCom.py index 3fb77f83e..38f3b8392 100644 --- a/module/plugins/hoster/AndroidfilehostCom.py +++ b/module/plugins/hoster/AndroidfilehostCom.py @@ -42,7 +42,7 @@ class AndroidfilehostCom(SimpleHoster): self.log_debug("Waiting time: %s seconds" % wait.group(1)) fid = re.search(r'id="fid" value="(\d+)" />', self.html).group(1) - self.log_debug("fid: %s" % fid) + self.log_debug("FID: %s" % fid) html = self.load("https://www.androidfilehost.com/libs/otf/mirrors.otf.php", post={'submit': 'submit', diff --git a/module/plugins/hoster/BezvadataCz.py b/module/plugins/hoster/BezvadataCz.py index 547be68fb..204c981c6 100644 --- a/module/plugins/hoster/BezvadataCz.py +++ b/module/plugins/hoster/BezvadataCz.py @@ -39,24 +39,16 @@ class BezvadataCz(SimpleHoster): #: Captcha form self.html = self.load(url) self.check_errors() - for _i in xrange(5): - action, inputs = self.parse_html_form('frm-stahnoutFreeForm') - if not inputs: - self.error(_("FreeForm")) - - m = re.search(r'<img src="data:image/png;base64,(.*?)"', self.html) - if m is None: - self.error(_("Wrong captcha image")) - - inputs['captcha'] = self.captcha.decrypt_image(m.group(1).decode('base64'), input_type='png') - - if '<img src="data:image/png;base64' in self.html: - self.captcha.invalid() - else: - self.captcha.correct() - break - else: - self.fail(_("No valid captcha code entered")) + + action, inputs = self.parse_html_form('frm-stahnoutFreeForm') + if not inputs: + self.error(_("FreeForm")) + + m = re.search(r'<img src="data:image/png;base64,(.*?)"', self.html) + if m is None: + self.retry_captcha() + + inputs['captcha'] = self.captcha.decrypt_image(m.group(1).decode('base64'), input_type='png') #: Download url self.html = self.load("http://bezvadata.cz%s" % action, post=inputs) diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py index cea78088e..e426de092 100644 --- a/module/plugins/hoster/BitshareCom.py +++ b/module/plugins/hoster/BitshareCom.py @@ -114,16 +114,14 @@ class BitshareCom(SimpleHoster): self.log_debug("File is captcha protected") recaptcha = ReCaptcha(self) - #: Try up to 3 times - for i in xrange(3): - response, challenge = recaptcha.challenge() - res = self.load("http://bitshare.com/files-ajax/" + self.file_id + "/request.html", - post={'request' : "validateCaptcha", - 'ajaxid' : self.ajaxid, - 'recaptcha_challenge_field': challenge, - 'recaptcha_response_field' : response}) - if self.handle_captcha_errors(res): - break + response, challenge = recaptcha.challenge() + res = self.load("http://bitshare.com/files-ajax/" + self.file_id + "/request.html", + post={'request' : "validateCaptcha", + 'ajaxid' : self.ajaxid, + 'recaptcha_challenge_field': challenge, + 'recaptcha_response_field' : response}) + + self.handle_captcha_errors(res) #: Get download URL self.log_debug("Getting download url") @@ -141,6 +139,7 @@ class BitshareCom(SimpleHoster): self.log_debug("Checking response [%s]" % res) if "ERROR:Session timed out" in res: self.retry() + elif "ERROR" in res: msg = res.split(separator)[-1] self.fail(msg) @@ -150,11 +149,12 @@ class BitshareCom(SimpleHoster): self.log_debug("Result of captcha resolving [%s]" % res) if "SUCCESS" in res: self.captcha.correct() - return True + elif "ERROR:SESSION ERROR" in res: self.retry() - self.captcha.invalid() + else: + self.retry_captcha() getInfo = create_getInfo(BitshareCom) diff --git a/module/plugins/hoster/CatShareNet.py b/module/plugins/hoster/CatShareNet.py index 5b7d61e05..c2b8d9257 100644 --- a/module/plugins/hoster/CatShareNet.py +++ b/module/plugins/hoster/CatShareNet.py @@ -46,7 +46,7 @@ class CatShareNet(SimpleHoster): 'recaptcha_response_field' : response}) m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: + if m is not None: self.link = m.group(1) diff --git a/module/plugins/hoster/CrockoCom.py b/module/plugins/hoster/CrockoCom.py index 2ed140b9c..70f2be6fb 100644 --- a/module/plugins/hoster/CrockoCom.py +++ b/module/plugins/hoster/CrockoCom.py @@ -39,7 +39,7 @@ class CrockoCom(SimpleHoster): for _i in xrange(5): m = re.search(self.CAPTCHA_PATTERN, self.html) - if m: + if m is not None: url = urlparse.urljoin("http://crocko.com/", m.group(1)) self.wait(m.group(2)) self.html = self.load(url) @@ -54,16 +54,11 @@ class CrockoCom(SimpleHoster): inputs = dict(re.findall(self.FORM_INPUT_PATTERN, form)) recaptcha = ReCaptcha(self) - for _i in xrange(5): - inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge() - self.download(action, post=inputs) + inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge() + self.download(action, post=inputs) - if self.check_file({'captcha': recaptcha.KEY_AJAX_PATTERN}): - self.captcha.invalid() - else: - break - else: - self.fail(_("No valid captcha solution received")) + if self.check_file({'captcha': recaptcha.KEY_AJAX_PATTERN}): + self.retry_captcha() getInfo = create_getInfo(CrockoCom) diff --git a/module/plugins/hoster/CzshareCom.py b/module/plugins/hoster/CzshareCom.py index eeba9d86d..d678f25fa 100644 --- a/module/plugins/hoster/CzshareCom.py +++ b/module/plugins/hoster/CzshareCom.py @@ -12,7 +12,7 @@ from module.utils import parseFileSize as parse_size class CzshareCom(SimpleHoster): __name__ = "CzshareCom" __type__ = "hoster" - __version__ = "1.03" + __version__ = "1.04" __status__ = "testing" __pattern__ = r'http://(?:www\.)?(czshare|sdilej)\.(com|cz)/(\d+/|download\.php\?).+' @@ -67,14 +67,13 @@ class CzshareCom(SimpleHoster): def handle_premium(self, pyfile): - #: Parse download link try: form = re.search(self.PREMIUM_FORM_PATTERN, self.html, re.S).group(1) inputs = dict(re.findall(self.FORM_INPUT_PATTERN, form)) except Exception, e: self.log_error(e) - self.restart(nopremium=True) + self.restart() #: Download the file, destination is determined by pyLoad self.download("http://sdilej.cz/profi_down.php", post=inputs, disposition=True) @@ -106,21 +105,17 @@ class CzshareCom(SimpleHoster): #: Get and decrypt captcha captcha_url = 'http://sdilej.cz/captcha.php' - for _i in xrange(5): - inputs['captchastring2'] = self.captcha.decrypt(captcha_url) - self.html = self.load(parsed_url, post=inputs) + inputs['captchastring2'] = self.captcha.decrypt(captcha_url) + self.html = self.load(parsed_url, post=inputs) - if u"<li>ZadanÃœ ovÄÅovacà kód nesouhlasÃ!</li>" in self.html: - self.captcha.invalid() + if u"<li>ZadanÃœ ovÄÅovacà kód nesouhlasÃ!</li>" in self.html: + self.retry_captcha() - elif re.search(self.MULTIDL_PATTERN, self.html): - self.wait(5 * 60, 12, _("Download limit reached")) + elif re.search(self.MULTIDL_PATTERN, self.html): + self.wait(5 * 60, 12, _("Download limit reached")) - else: - self.captcha.correct() - break else: - self.fail(_("No valid captcha code entered")) + self.captcha.correct() m = re.search("countdown_number = (\d+);", self.html) self.set_wait(int(m.group(1)) if m else 50) @@ -150,14 +145,13 @@ class CzshareCom(SimpleHoster): self.fail(_("File not available - try later")) elif check == "credit": - self.restart(nopremium=True) + self.restart() elif check == "multi-dl": self.wait(5 * 60, 12, _("Download limit reached")) elif check == "captcha": - self.captcha.invalid() - self.retry() + self.retry_captcha() return super(CzshareCom, self).check_download() diff --git a/module/plugins/hoster/DataportCz.py b/module/plugins/hoster/DataportCz.py index 2b30df059..fe304fdea 100644 --- a/module/plugins/hoster/DataportCz.py +++ b/module/plugins/hoster/DataportCz.py @@ -28,32 +28,26 @@ class DataportCz(SimpleHoster): def handle_free(self, pyfile): captchas = {'1': "jkeG", '2': "hMJQ", '3': "vmEK", '4': "ePQM", '5': "blBd"} - for _i in xrange(60): - action, inputs = self.parse_html_form('free_download_form') - self.log_debug(action, inputs) - if not action or not inputs: - self.error(_("free_download_form")) - - if "captchaId" in inputs and inputs['captchaId'] in captchas: - inputs['captchaCode'] = captchas[inputs['captchaId']] - else: - self.error(_("captcha")) - - self.download("http://www.dataport.cz%s" % action, post=inputs) - - check = self.check_file({'captcha': 'alert("\u0160patn\u011b opsan\u00fd k\u00f3d z obr\u00e1zu");', - 'slot' : 'alert("Je n\u00e1m l\u00edto, ale moment\u00e1ln\u011b nejsou'}) - if check == "captcha": - self.error(_("invalid captcha")) - - elif check == "slot": - self.log_debug("No free slots - wait 60s and retry") - self.wait(60, False) - self.html = self.load(pyfile.url) - continue - - else: - break + action, inputs = self.parse_html_form('free_download_form') + self.log_debug(action, inputs) + if not action or not inputs: + self.error(_("free_download_form")) + + if "captchaId" in inputs and inputs['captchaId'] in captchas: + inputs['captchaCode'] = captchas[inputs['captchaId']] + else: + self.error(_("Captcha not found")) + + self.download("http://www.dataport.cz%s" % action, post=inputs) + + check = self.check_file({'captcha': 'alert("\u0160patn\u011b opsan\u00fd k\u00f3d z obr\u00e1zu");', + 'slot' : 'alert("Je n\u00e1m l\u00edto, ale moment\u00e1ln\u011b nejsou'}) + if check == "captcha": + self.retry_captcha() + + elif check == "slot": + self.log_debug("No free slots - wait 60s and retry") + self.retry(wait=60) getInfo = create_getInfo(DataportCz) diff --git a/module/plugins/hoster/DateiTo.py b/module/plugins/hoster/DateiTo.py index d90fc5864..42aed2c77 100644 --- a/module/plugins/hoster/DateiTo.py +++ b/module/plugins/hoster/DateiTo.py @@ -49,7 +49,8 @@ class DateiTo(SimpleHoster): m = re.search(self.DATA_PATTERN, self.html) if m is None: - self.error(_("data")) + self.error(_("Data pattern not found")) + url = 'http://datei.to/' + m.group(1) data = dict(x.split('=') for x in m.group(2).split('&')) diff --git a/module/plugins/hoster/DebridItaliaCom.py b/module/plugins/hoster/DebridItaliaCom.py index 7cf7c4663..ca6603a87 100644 --- a/module/plugins/hoster/DebridItaliaCom.py +++ b/module/plugins/hoster/DebridItaliaCom.py @@ -29,7 +29,7 @@ class DebridItaliaCom(MultiHoster): get={'generate': "on", 'link': pyfile.url, 'p': self.get_password()}) if "ERROR:" not in self.html: - self.link = self.html.strip() + self.link = self.html else: self.info['error'] = re.search(r'ERROR:(.*)', self.html).group(1).strip() diff --git a/module/plugins/hoster/DepositfilesCom.py b/module/plugins/hoster/DepositfilesCom.py index cb9ab5572..b3854f581 100644 --- a/module/plugins/hoster/DepositfilesCom.py +++ b/module/plugins/hoster/DepositfilesCom.py @@ -48,7 +48,7 @@ class DepositfilesCom(SimpleHoster): m = re.search(r"var fid = '(\w+)';", self.html) if m is None: - self.retry(delay=5) + self.retry(wait=5) params = {'fid': m.group(1)} self.log_debug("FID: %s" % params['fid']) @@ -66,7 +66,7 @@ class DepositfilesCom(SimpleHoster): self.html = self.load("https://dfiles.eu/get_file.php", get=params) m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: + if m is not None: self.link = urllib.unquote(m.group(1)) diff --git a/module/plugins/hoster/DlFreeFr.py b/module/plugins/hoster/DlFreeFr.py index f9d427c1b..f77b9596a 100644 --- a/module/plugins/hoster/DlFreeFr.py +++ b/module/plugins/hoster/DlFreeFr.py @@ -100,15 +100,16 @@ class DlFreeFr(SimpleHoster): if headers.get("code") == 302 and "set-cookie" in headers and "location" in headers: m = re.search("(.*?)=(.*?); path=(.*?); domain=(.*)", headers.get("set-cookie")) cj = CookieJar(self.__name__) - if m: + if m is not None: cj.setCookie(m.group(4), m.group(1), m.group(2), m.group(3)) else: self.fail(_("Cookie error")) self.link = headers.get("location") self.req.setCookieJar(cj) + else: - self.fail(_("Invalid response")) + self.fail(_("Bad header")) def get_last_headers(self): diff --git a/module/plugins/hoster/ExashareCom.py b/module/plugins/hoster/ExashareCom.py index 19cd1b46c..c3a4b43dc 100644 --- a/module/plugins/hoster/ExashareCom.py +++ b/module/plugins/hoster/ExashareCom.py @@ -28,11 +28,7 @@ class ExashareCom(XFSHoster): def handle_free(self, pyfile): - m = re.search(self.LINK_FREE_PATTERN, self.html) - if m is None: - self.error(_("Free download link not found")) - else: - self.link = m.group(1) + return super(XFSHoster, self).handle_free(pyfile) getInfo = create_getInfo(ExashareCom) diff --git a/module/plugins/hoster/ExtabitCom.py b/module/plugins/hoster/ExtabitCom.py index 0d5533539..b21db38bb 100644 --- a/module/plugins/hoster/ExtabitCom.py +++ b/module/plugins/hoster/ExtabitCom.py @@ -35,7 +35,7 @@ class ExtabitCom(SimpleHoster): self.fail(_("Only premium users can download this file")) m = re.search(r"Next free download from your ip will be available in <b>(\d+)\s*minutes", self.html) - if m: + if m is not None: self.wait(int(m.group(1)) * 60, True) elif "The daily downloads limit from your IP is exceeded" in self.html: self.log_warning(_("You have reached your daily downloads limit for today")) @@ -46,21 +46,19 @@ class ExtabitCom(SimpleHoster): fileID = m.group('ID') if m else self.info['pattern']['ID'] m = re.search(r'recaptcha/api/challenge\?k=(\w+)', self.html) - if m: + if m is not None: recaptcha = ReCaptcha(self) captcha_key = m.group(1) - for _i in xrange(5): - get_data = {'type': "recaptcha"} - get_data['capture'], get_data['challenge'] = recaptcha.challenge(captcha_key) - res = json_loads(self.load("http://extabit.com/file/%s/" % fileID, get=get_data)) - if "ok" in res: - self.captcha.correct() - break - else: - self.captcha.invalid() + get_data = {'type': "recaptcha"} + get_data['capture'], get_data['challenge'] = recaptcha.challenge(captcha_key) + + res = json_loads(self.load("http://extabit.com/file/%s/" % fileID, get=get_data)) + + if "ok" in res: + self.captcha.correct() else: - self.fail(_("Invalid captcha")) + self.retry_captcha() else: self.error(_("Captcha")) diff --git a/module/plugins/hoster/FastshareCz.py b/module/plugins/hoster/FastshareCz.py index 985faaa93..b05edfb27 100644 --- a/module/plugins/hoster/FastshareCz.py +++ b/module/plugins/hoster/FastshareCz.py @@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class FastshareCz(SimpleHoster): __name__ = "FastshareCz" __type__ = "hoster" - __version__ = "0.34" + __version__ = "0.35" __status__ = "testing" __pattern__ = r'http://(?:www\.)?fastshare\.cz/\d+/.+' @@ -42,14 +42,14 @@ class FastshareCz(SimpleHoster): if self.CREDIT_ERROR in self.html: errmsg = self.info['error'] = _("Not enough traffic left") self.log_warning(errmsg) - self.restart(nopremium=True) + self.restart() self.info.pop('error', None) def handle_free(self, pyfile): m = re.search(self.FREE_URL_PATTERN, self.html) - if m: + if m is not None: action, captcha_src = m.groups() else: self.error(_("FREE_URL_PATTERN not found")) @@ -70,10 +70,10 @@ class FastshareCz(SimpleHoster): self.retry(6, 10 * 60, _("Paralell download")) elif check == "wrong captcha": - self.retry(attemps=5, msg=_("Wrong captcha")) + self.retry_captcha() elif check == "credit": - self.restart(nopremium=True) + self.restart() return super(FastshareCz, self).check_download() diff --git a/module/plugins/hoster/FileSharkPl.py b/module/plugins/hoster/FileSharkPl.py index 080e35438..23aa7ea61 100644 --- a/module/plugins/hoster/FileSharkPl.py +++ b/module/plugins/hoster/FileSharkPl.py @@ -50,12 +50,12 @@ class FileSharkPl(SimpleHoster): def check_errors(self): #: Check if file is now available for download (-> file name can be found in html body) m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: errmsg = self.info['error'] = _("Another download already run") self.retry(15, int(m.group(1)), errmsg) m = re.search(self.ERROR_PATTERN, self.html) - if m: + if m is not None: alert = m.group(1) if re.match(self.IP_ERROR_PATTERN, alert): @@ -83,7 +83,7 @@ class FileSharkPl(SimpleHoster): self.html = self.load(link) m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: seconds = int(m.group(1)) self.log_debug("Wait %s seconds" % seconds) self.wait(seconds) diff --git a/module/plugins/hoster/FileboomMe.py b/module/plugins/hoster/FileboomMe.py index 4328565f4..1a2c89b0b 100644 --- a/module/plugins/hoster/FileboomMe.py +++ b/module/plugins/hoster/FileboomMe.py @@ -39,64 +39,50 @@ class FileboomMe(SimpleHoster): post_url = urlparse.urljoin(pyfile.url, "file/" + self.info['pattern']['ID']) m = re.search(r'data-slow-id="(\w+)"', self.html) - if m: + if m is not None: self.html = self.load(post_url, post={'slow_id': m.group(1)}) m = re.search(self.LINK_PATTERN, self.html) - if m: + if m is not None: self.link = urlparse.urljoin(pyfile.url, m.group(0)) else: - for _i in xrange(5): - m = re.search(r'<input type="hidden" name="uniqueId" value="(\w+)">', self.html) - if m: - uniqueId = m.group(1) + m = re.search(r'<input type="hidden" name="uniqueId" value="(\w+)">', self.html) + if m is None: + m = re.search(r'>\s*Please wait ([\d:]+)', self.html) + if m is not None: + wait_time = 0 + for v in re.findall(r'(\d+)', m.group(1), re.I): + wait_time = 60 * wait_time + int(v) + self.wait(wait_time) + self.retry() - m = re.search(self.CAPTCHA_PATTERN, self.html) - if m: - captcha = self.captcha.decrypt(urlparse.urljoin(pyfile.url, m.group(1))) - - self.html = self.load(post_url, - post={'CaptchaForm[code]' : captcha, - 'free' : 1, - 'freeDownloadRequest': 1, - 'uniqueId' : uniqueId}) - - if 'The verification code is incorrect' in self.html: - self.captcha.invalid() - - else: - self.check_errors() - - self.html = self.load(post_url, - post={'free' : 1, - 'uniqueId': uniqueId}) - - m = re.search(self.LINK_PATTERN, self.html) - if m: - self.link = urlparse.urljoin(pyfile.url, m.group(0)) + else: + uniqueId = m.group(1) - else: - self.captcha.invalid() + m = re.search(self.CAPTCHA_PATTERN, self.html) + if m is not None: + captcha = self.captcha.decrypt(urlparse.urljoin(pyfile.url, m.group(1))) + self.html = self.load(post_url, + post={'CaptchaForm[code]' : captcha, + 'free' : 1, + 'freeDownloadRequest': 1, + 'uniqueId' : uniqueId}) - break + if 'The verification code is incorrect' in self.html: + self.retry_captcha() else: - self.fail(_("Captcha not found")) - - else: - m = re.search(r'>\s*Please wait ([\d:]+)', self.html) - if m: - wait_time = 0 - for v in re.findall(r'(\d+)', m.group(1), re.I): - wait_time = 60 * wait_time + int(v) - self.wait(wait_time) - self.retry() - break + self.check_errors() - else: - self.fail(_("Invalid captcha")) + self.html = self.load(post_url, + post={'free' : 1, + 'uniqueId': uniqueId}) + + m = re.search(self.LINK_PATTERN, self.html) + if m is not None: + self.link = urlparse.urljoin(pyfile.url, m.group(0)) getInfo = create_getInfo(FileboomMe) diff --git a/module/plugins/hoster/FilecloudIo.py b/module/plugins/hoster/FilecloudIo.py index aa864271a..da81d3f37 100644 --- a/module/plugins/hoster/FilecloudIo.py +++ b/module/plugins/hoster/FilecloudIo.py @@ -78,22 +78,18 @@ class FilecloudIo(SimpleHoster): self.log_debug(res) if res['captcha']: data['ctype'] = "recaptcha" + data['recaptcha_response'], data['recaptcha_challenge'] = recaptcha.challenge(captcha_key) - for _i in xrange(5): - data['recaptcha_response'], data['recaptcha_challenge'] = recaptcha.challenge(captcha_key) + json_url = "http://filecloud.io/download-request.json" + res = self.load(json_url, post=data) + self.log_debug(res) + res = json_loads(res) - json_url = "http://filecloud.io/download-request.json" - res = self.load(json_url, post=data) - self.log_debug(res) - res = json_loads(res) - - if "retry" in res and res['retry']: - self.captcha.invalid() - else: - self.captcha.correct() - break + if "retry" in res and res['retry']: + self.retry_captcha() else: - self.fail(_("Incorrect captcha")) + self.captcha.correct() + if res['dl']: self.html = self.load('http://filecloud.io/download.html') diff --git a/module/plugins/hoster/FiledropperCom.py b/module/plugins/hoster/FiledropperCom.py index 3f5e2b761..8cef6c709 100644 --- a/module/plugins/hoster/FiledropperCom.py +++ b/module/plugins/hoster/FiledropperCom.py @@ -32,16 +32,14 @@ class FiledropperCom(SimpleHoster): def handle_free(self, pyfile): m = re.search(r'img id="img" src="(.+?)"', self.html) if m is None: - self.fail("Captcha not found") + self.fail(_("Captcha not found")) captcha_code = self.captcha.decrypt("http://www.filedropper.com/%s" % m.group(1)) m = re.search(r'method="post" action="(.+?)"', self.html) - if m is None: - self.fail("Download link not found") - - self.download(urlparse.urljoin("http://www.filedropper.com/", m.group(1)), - post={'code': captcha_code}) + if m is not None: + self.download(urlparse.urljoin("http://www.filedropper.com/", m.group(1)), + post={'code': captcha_code}) getInfo = create_getInfo(FiledropperCom) diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index e8890086b..637f3b2e0 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -50,12 +50,12 @@ class FilefactoryCom(SimpleHoster): m = re.search(self.LINK_FREE_PATTERN, self.html) if m is None: - self.error(_("Free download link not found")) + return self.link = m.group(1) m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: self.wait(m.group(1)) @@ -65,21 +65,9 @@ class FilefactoryCom(SimpleHoster): if check == "multiple": self.log_debug("Parallel downloads detected; waiting 15 minutes") - self.retry(delay=15 * 60, msg=_("Parallel downloads")) + self.retry(wait=15 * 60, msg=_("Parallel downloads")) elif check == "error": self.error(_("Unknown error")) return super(FilefactoryCom, self).check_download() - - - def handle_premium(self, pyfile): - self.link = self.direct_link(self.load(pyfile.url, just_header=True)) - - if not self.link: - html = self.load(pyfile.url) - m = re.search(self.LINK_PREMIUM_PATTERN, html) - if m: - self.link = m.group(1) - else: - self.error(_("Premium download link not found")) diff --git a/module/plugins/hoster/FilepostCom.py b/module/plugins/hoster/FilepostCom.py index f2e3fb76d..3d42bebed 100644 --- a/module/plugins/hoster/FilepostCom.py +++ b/module/plugins/hoster/FilepostCom.py @@ -64,27 +64,20 @@ class FilepostCom(SimpleHoster): self.link = self.get_json_response(get_dict, post_dict, 'link') if not self.link: - self.fail(_("Incorrect password")) + self.fail(_("Wrong password")) else: self.fail(_("No password found")) else: - #: Solve recaptcha - recaptcha = ReCaptcha(self) - - for i in xrange(5): - get_dict['JsHttpRequest'] = str(int(time.time() * 10000)) + '-xml' - if i: - post_dict['recaptcha_response_field'], post_dict['recaptcha_challenge_field'] = recaptcha.challenge( - captcha_key) - self.log_debug(u"RECAPTCHA: %s : %s : %s" % ( - captcha_key, post_dict['recaptcha_challenge_field'], post_dict['recaptcha_response_field'])) + get_dict['JsHttpRequest'] = str(int(time.time() * 10000)) + '-xml' + self.link = self.get_json_response(get_dict, post_dict, 'link') + if not self.link: + #: Solve recaptcha + recaptcha = ReCaptcha(self) + post_dict['recaptcha_response_field'], post_dict['recaptcha_challenge_field'] = recaptcha.challenge(captcha_key) self.link = self.get_json_response(get_dict, post_dict, 'link') - else: - self.fail(_("Invalid captcha")) - def get_json_response(self, get_dict, post_dict, field): res = json_loads(self.load('https://filepost.com/files/get/', get=get_dict, post=post_dict)) @@ -101,8 +94,8 @@ class FilepostCom(SimpleHoster): if 'error' in res['js']: if res['js']['error'] == "download_delay": - self.retry(delay=res['js']['params']['next_download']) - #: ~? self.retry(delay=js_answer['params']['next_download']) + self.retry(wait=res['js']['params']['next_download']) + #: ~? self.retry(wait=js_answer['params']['next_download']) elif 'Wrong file password' in res['js']['error'] \ or 'You entered a wrong CAPTCHA code' in res['js']['error'] \ diff --git a/module/plugins/hoster/FilepupNet.py b/module/plugins/hoster/FilepupNet.py index 8bb23adb1..7793afe53 100644 --- a/module/plugins/hoster/FilepupNet.py +++ b/module/plugins/hoster/FilepupNet.py @@ -39,11 +39,9 @@ class FilepupNet(SimpleHoster): def handle_free(self, pyfile): m = re.search(self.LINK_FREE_PATTERN, self.html) - if m is None: - self.error(_("Download link not found")) - - dl_link = m.group(1) - self.download(dl_link, post={'task': "download"}) + if m is not None: + dl_link = m.group(1) + self.download(dl_link, post={'task': "download"}) getInfo = create_getInfo(FilepupNet) diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py index af755e0a6..37c88dec7 100644 --- a/module/plugins/hoster/FilerNet.py +++ b/module/plugins/hoster/FilerNet.py @@ -57,10 +57,10 @@ class FilerNet(SimpleHoster): self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 1) if 'location' in self.req.http.header.lower(): - self.link = re.search(r'location: (\S+)', self.req.http.header, re.I).group(1) self.captcha.correct() + self.link = re.search(r'location: (\S+)', self.req.http.header, re.I).group(1) else: - self.captcha.invalid() + self.retry_captcha() getInfo = create_getInfo(FilerNet) diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py index 36ccd473f..277d4f2a8 100644 --- a/module/plugins/hoster/FileserveCom.py +++ b/module/plugins/hoster/FileserveCom.py @@ -34,7 +34,7 @@ def check_file(plugin, urls): class FileserveCom(Hoster): __name__ = "FileserveCom" __type__ = "hoster" - __version__ = "0.60" + __version__ = "0.61" __status__ = "testing" __pattern__ = r'http://(?:www\.)?fileserve\.com/file/(?P<ID>[^/]+)' @@ -95,7 +95,7 @@ class FileserveCom(Hoster): elif action['fail'] == "parallelDownload": self.log_warning(_("Parallel download error, now waiting 60s")) - self.retry(delay=60, msg=_("parallelDownload")) + self.retry(wait=60, msg=_("parallelDownload")) else: self.fail(_("Download check returned: %s") % action['fail']) @@ -161,19 +161,15 @@ class FileserveCom(Hoster): captcha_key = re.search(self.CAPTCHA_KEY_PATTERN, self.html).group(1) recaptcha = ReCaptcha(self) - for _i in xrange(5): - response, challenge = recaptcha.challenge(captcha_key) - res = json_loads(self.load(self.URLS[2], - post={'recaptcha_challenge_field' : challenge, - 'recaptcha_response_field' : response, - 'recaptcha_shortencode_field': self.file_id})) - if not res['success']: - self.captcha.invalid() - else: - self.captcha.correct() - break + response, challenge = recaptcha.challenge(captcha_key) + res = json_loads(self.load(self.URLS[2], + post={'recaptcha_challenge_field' : challenge, + 'recaptcha_response_field' : response, + 'recaptcha_shortencode_field': self.file_id})) + if res['success']: + self.captcha.correct() else: - self.fail(_("Invalid captcha")) + self.retry_captcha() def do_long_wait(self, m): @@ -197,7 +193,7 @@ class FileserveCom(Hoster): elif res['error_code'] in ["305", "500"]: self.temp_offline() elif res['error_code'] in ["403", "605"]: - self.restart(nopremium=True) + self.restart() elif res['error_code'] in ["606", "607", "608"]: self.offline() else: diff --git a/module/plugins/hoster/FourSharedCom.py b/module/plugins/hoster/FourSharedCom.py index 212eadb3b..d767f4ca1 100644 --- a/module/plugins/hoster/FourSharedCom.py +++ b/module/plugins/hoster/FourSharedCom.py @@ -38,7 +38,7 @@ class FourSharedCom(SimpleHoster): def handle_free(self, pyfile): m = re.search(self.LINK_BTN_PATTERN, self.html) - if m: + if m is not None: link = m.group(1) else: link = re.sub(r'/(download|get|file|document|photo|video|audio)/', r'/get/', pyfile.url) @@ -47,7 +47,7 @@ class FourSharedCom(SimpleHoster): m = re.search(self.LINK_FREE_PATTERN, self.html) if m is None: - self.error(_("Download link")) + return self.link = m.group(1) diff --git a/module/plugins/hoster/FreakshareCom.py b/module/plugins/hoster/FreakshareCom.py index 72a1c0401..450f11095 100644 --- a/module/plugins/hoster/FreakshareCom.py +++ b/module/plugins/hoster/FreakshareCom.py @@ -61,8 +61,7 @@ class FreakshareCom(Hoster): self.fail(_("File not downloadable")) elif check == "wrong_captcha": - self.captcha.invalid() - self.retry() + self.retry_captcha() elif check == "downloadserver": self.retry(5, 15 * 60, _("No Download server")) @@ -111,7 +110,7 @@ class FreakshareCom(Hoster): if not self.wantReconnect: m = re.search(r"<h1\sclass=\"box_heading\"\sstyle=\"text-align:center;\">([^ ]+)", self.html) - if m: + if m is not None: file_name = m.group(1) else: file_name = self.pyfile.url @@ -128,7 +127,7 @@ class FreakshareCom(Hoster): if not self.wantReconnect: m = re.search(r"<h1\sclass=\"box_heading\"\sstyle=\"text-align:center;\">[^ ]+ - ([^ ]+) (\w\w)yte", self.html) - if m: + if m is not None: units = float(m.group(1).replace(",", "")) pow = {'KB': 1, 'MB': 2, 'GB': 3}[m.group(2)] size = int(units * 1024 ** pow) diff --git a/module/plugins/hoster/FshareVn.py b/module/plugins/hoster/FshareVn.py index a5aac222c..b387151f7 100644 --- a/module/plugins/hoster/FshareVn.py +++ b/module/plugins/hoster/FshareVn.py @@ -68,7 +68,7 @@ class FshareVn(SimpleHoster): self.html = self.load(url, post=inputs) if 'name="link_file_pwd_dl"' in self.html: - self.fail(_("Incorrect password")) + self.fail(_("Wrong password")) else: self.fail(_("No password found")) @@ -93,7 +93,7 @@ class FshareVn(SimpleHoster): self.offline() m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: self.log_info(_("Wait until %s ICT") % m.group(1)) wait_until = time.mktime.time(time.strptime.time(m.group(1), "%d/%m/%Y %H:%M")) self.wait(wait_until - time.mktime.time(time.gmtime.time()) - 7 * 60 * 60, True) diff --git a/module/plugins/hoster/Ftp.py b/module/plugins/hoster/Ftp.py index 2fa5c1aa8..2ff1755f4 100644 --- a/module/plugins/hoster/Ftp.py +++ b/module/plugins/hoster/Ftp.py @@ -71,7 +71,7 @@ class Ftp(Hoster): self.log_debug(self.req.http.header) m = re.search(r"Content-Length:\s*(\d+)", res) - if m: + if m is not None: pyfile.size = int(m.group(1)) self.download(pyfile.url) diff --git a/module/plugins/hoster/GigapetaCom.py b/module/plugins/hoster/GigapetaCom.py index 381c39a21..85e5e4843 100644 --- a/module/plugins/hoster/GigapetaCom.py +++ b/module/plugins/hoster/GigapetaCom.py @@ -36,23 +36,22 @@ class GigapetaCom(SimpleHoster): self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0) - for _i in xrange(5): - self.check_errors() - - captcha = self.captcha.decrypt(captcha_url) - self.html = self.load(pyfile.url, post={ - 'captcha_key': captcha_key, - 'captcha': captcha, - 'download': "Download"}) - - m = re.search(r'Location\s*:\s*(.+)', self.req.http.header, re.I) - if m: - self.link = m.group(1).rstrip() #@TODO: Remove .rstrip() in 0.4.10 - break - elif "Entered figures don`t coincide with the picture" in self.html: - self.captcha.invalid() - else: - self.fail(_("No valid captcha code entered")) + self.check_errors() + + captcha = self.captcha.decrypt(captcha_url) + self.html = self.load(pyfile.url, post={ + 'captcha_key': captcha_key, + 'captcha': captcha, + 'download': "Download"}) + + m = re.search(r'Location\s*:\s*(.+)', self.req.http.header, re.I) + if m is not None: + self.captcha.correct() + self.link = m.group(1) + + elif "Entered figures don`t coincide with the picture" in self.html: + self.retry_captcha() + self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 1) diff --git a/module/plugins/hoster/GoogledriveCom.py b/module/plugins/hoster/GoogledriveCom.py index 381bd24dc..c6b84b776 100644 --- a/module/plugins/hoster/GoogledriveCom.py +++ b/module/plugins/hoster/GoogledriveCom.py @@ -41,17 +41,16 @@ class GoogledriveCom(SimpleHoster): m = re.search(self.LINK_FREE_PATTERN, self.html) if m is None: - self.error(_("Free download link not found")) + return + link = self.fixurl(link, "https://docs.google.com/") + direct_link = self.direct_link(link, False) + + if not direct_link: + self.html = self.load(link) else: - link = self.fixurl(link, "https://docs.google.com/") - direct_link = self.direct_link(link, False) - - if not direct_link: - self.html = self.load(link) - else: - self.link = direct_link - break + self.link = direct_link + break getInfo = create_getInfo(GoogledriveCom) diff --git a/module/plugins/hoster/HighWayMe.py b/module/plugins/hoster/HighWayMe.py index 5d990795f..53a8960c1 100644 --- a/module/plugins/hoster/HighWayMe.py +++ b/module/plugins/hoster/HighWayMe.py @@ -39,7 +39,7 @@ class HighWayMe(MultiHoster): elif "trafficlimit" in self.html: self.log_warning(_("Reached daily limit")) - self.retry(delay=seconds_to_midnight(), msg="Daily limit for this host reached") + self.retry(wait=seconds_to_midnight(), msg="Daily limit for this host reached") elif "<code>8</code>" in self.html: self.log_warning(_("Hoster temporarily unavailable, waiting 1 minute and retry")) diff --git a/module/plugins/hoster/HostujeNet.py b/module/plugins/hoster/HostujeNet.py index 4dbf550b3..3c0a53535 100644 --- a/module/plugins/hoster/HostujeNet.py +++ b/module/plugins/hoster/HostujeNet.py @@ -30,19 +30,19 @@ class HostujeNet(SimpleHoster): def handle_free(self, pyfile): m = re.search(r'<script src="([\w^_]+.php)"></script>', self.html) - if m: + if m is not None: jscript = self.load("http://hostuje.net/" + m.group(1)) m = re.search(r"\('(\w+\.php\?i=\w+)'\);", jscript) - if m: + if m is not None: self.load("http://hostuje.net/" + m.group(1)) else: - self.error(_("unexpected javascript format")) + self.error(_("Unexpected javascript format")) else: - self.error(_("script not found")) + self.error(_("Script not found")) action, inputs = self.parse_html_form(pyfile.url.replace(".", "\.").replace( "?", "\?")) if not action: - self.error(_("form not found")) + self.error(_("Form not found")) self.download(action, post=inputs) diff --git a/module/plugins/hoster/IfolderRu.py b/module/plugins/hoster/IfolderRu.py index 85d03489d..08e22a9df 100644 --- a/module/plugins/hoster/IfolderRu.py +++ b/module/plugins/hoster/IfolderRu.py @@ -45,21 +45,16 @@ class IfolderRu(SimpleHoster): self.get_fileInfo() session_id = re.search(self.SESSION_ID_PATTERN, self.html).groups() - captcha_url = "http://ints.rusfolder.com/random/images/?session=%s" % session_id - for _i in xrange(5): - action, inputs = self.parse_html_form('id="download-step-one-form"') - inputs['confirmed_number'] = self.captcha.decrypt(captcha_url, cookies=True) - inputs['action'] = '1' - self.log_debug(inputs) - - self.html = self.load(url, post=inputs) - if self.WRONG_CAPTCHA_PATTERN in self.html: - self.captcha.invalid() - else: - break - else: - self.fail(_("Invalid captcha")) + + action, inputs = self.parse_html_form('id="download-step-one-form"') + inputs['confirmed_number'] = self.captcha.decrypt(captcha_url, cookies=True) + inputs['action'] = '1' + self.log_debug(inputs) + + self.html = self.load(url, post=inputs) + if self.WRONG_CAPTCHA_PATTERN in self.html: + self.retry_captcha() self.link = re.search(self.LINK_FREE_PATTERN, self.html).group(1) diff --git a/module/plugins/hoster/Keep2ShareCc.py b/module/plugins/hoster/Keep2ShareCc.py index 1b9f69a02..427dbbec7 100644 --- a/module/plugins/hoster/Keep2ShareCc.py +++ b/module/plugins/hoster/Keep2ShareCc.py @@ -42,18 +42,18 @@ class Keep2ShareCc(SimpleHoster): def check_errors(self): m = re.search(self.TEMP_ERROR_PATTERN, self.html) - if m: + if m is not None: self.info['error'] = m.group(1) self.wantReconnect = True - self.retry(delay=30 * 60, msg=m.group(0)) + self.retry(wait=30 * 60, msg=m.group(0)) m = re.search(self.ERROR_PATTERN, self.html) - if m: + if m is not None: errmsg = self.info['error'] = m.group(1) self.error(errmsg) m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: self.log_debug("Hoster told us to wait for %s" % m.group(1)) #: String to time convert courtesy of https://stackoverflow.com/questions/10663720 @@ -61,7 +61,7 @@ class Keep2ShareCc(SimpleHoster): wait_time = sum(a * b for a, b in zip(ftr, map(int, m.group(1).split(':')))) self.wantReconnect = True - self.retry(delay=wait_time, msg="Please wait to download this file") + self.retry(wait=wait_time, msg="Please wait to download this file") self.info.pop('error', None) @@ -95,11 +95,11 @@ class Keep2ShareCc(SimpleHoster): 'yt0' : ''} m = re.search(r'id="(captcha\-form)"', self.html) - self.log_debug("captcha-form found %s" % m) + self.log_debug("Captcha form found", m) m = re.search(self.CAPTCHA_PATTERN, self.html) self.log_debug("CAPTCHA_PATTERN found %s" % m) - if m: + if m is not None: captcha_url = urlparse.urljoin("http://keep2s.cc/", m.group(1)) post_data['CaptchaForm[code]'] = self.captcha.decrypt(captcha_url) else: @@ -110,10 +110,10 @@ class Keep2ShareCc(SimpleHoster): self.html = self.load(self.pyfile.url, post=post_data) - if 'verification code is incorrect' not in self.html: - self.captcha.correct() + if 'verification code is incorrect' in self.html: + self.retry_captcha() else: - self.captcha.invalid() + self.captcha.correct() getInfo = create_getInfo(Keep2ShareCc) diff --git a/module/plugins/hoster/KingfilesNet.py b/module/plugins/hoster/KingfilesNet.py index 98f74ad0d..3f7b0bfb9 100644 --- a/module/plugins/hoster/KingfilesNet.py +++ b/module/plugins/hoster/KingfilesNet.py @@ -56,7 +56,7 @@ class KingfilesNet(SimpleHoster): self.error(_("Random key not found")) rand = m.group(1) - self.log_debug("rand = ", rand) + self.log_debug("rand = " + rand) post_data = {'op' : "download2", 'id' : self.info['pattern']['ID'], diff --git a/module/plugins/hoster/LetitbitNet.py b/module/plugins/hoster/LetitbitNet.py index 22d5c654a..b8a563007 100644 --- a/module/plugins/hoster/LetitbitNet.py +++ b/module/plugins/hoster/LetitbitNet.py @@ -60,7 +60,7 @@ class LetitbitNet(SimpleHoster): def handle_free(self, pyfile): action, inputs = self.parse_html_form('id="ifree_form"') if not action: - self.error(_("ifree_form")) + self.error(_("Form not found")) pyfile.size = float(inputs['sssize']) self.log_debug(action, inputs) @@ -99,17 +99,13 @@ class LetitbitNet(SimpleHoster): self.log_debug(res) - if not res: - self.captcha.invalid() + if not res or res == "error_wrong_captcha": + self.retry_captcha() - if res == "error_free_download_blocked": + elif res == "error_free_download_blocked": self.log_warning(_("Daily limit reached")) self.wait(seconds_to_midnight(), True) - if res == "error_wrong_captcha": - self.captcha.invalid() - self.retry() - elif res.startswith('['): urls = json_loads(res) diff --git a/module/plugins/hoster/LoadTo.py b/module/plugins/hoster/LoadTo.py index 7a42e0360..722f0e518 100644 --- a/module/plugins/hoster/LoadTo.py +++ b/module/plugins/hoster/LoadTo.py @@ -50,7 +50,7 @@ class LoadTo(SimpleHoster): #: Set Timer - may be obsolete m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: self.wait(m.group(1)) #: Load.to is using solvemedia captchas since ~july 2014: diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py index 71cccb71a..f9c7a89ef 100644 --- a/module/plugins/hoster/LuckyShareNet.py +++ b/module/plugins/hoster/LuckyShareNet.py @@ -29,10 +29,10 @@ class LuckyShareNet(SimpleHoster): if 'AJAX Error' in rep: html = self.load(self.pyfile.url) m = re.search(r"waitingtime = (\d+);", html) - if m: + if m is not None: seconds = int(m.group(1)) self.log_debug("You have to wait %d seconds between free downloads" % seconds) - self.retry(delay=seconds) + self.retry(wait=seconds) else: self.error(_("Unable to detect wait time between free downloads")) elif 'Hash expired' in rep: @@ -52,24 +52,20 @@ class LuckyShareNet(SimpleHoster): recaptcha = ReCaptcha(self) - for _i in xrange(5): - response, challenge = recaptcha.challenge() - rep = self.load(r"http://luckyshare.net/download/verify/challenge/%s/response/%s/hash/%s" % - (challenge, response, json['hash'])) - self.log_debug("JSON: " + rep) - if 'link' in rep: - json.update(self.parse_json(rep)) - self.captcha.correct() - break - elif 'Verification failed' in rep: - self.captcha.invalid() - else: - self.error(_("Unable to get downlaod link")) + response, challenge = recaptcha.challenge() + rep = self.load(r"http://luckyshare.net/download/verify/challenge/%s/response/%s/hash/%s" % + (challenge, response, json['hash'])) + + self.log_debug("JSON: " + rep) - if not json['link']: - self.fail(_("No Download url retrieved/all captcha attempts failed")) + if 'Verification failed' in rep: + self.retry_captcha() - self.link = json['link'] + elif 'link' in rep: + self.captcha.correct() + json.update(self.parse_json(rep)) + if json['link']: + self.link = json['link'] getInfo = create_getInfo(LuckyShareNet) diff --git a/module/plugins/hoster/MediafireCom.py b/module/plugins/hoster/MediafireCom.py index 21e643171..1abe87cd2 100644 --- a/module/plugins/hoster/MediafireCom.py +++ b/module/plugins/hoster/MediafireCom.py @@ -69,7 +69,7 @@ class MediafireCom(SimpleHoster): self.html = self.load(self.link, post={'downloadp': password}) if self.PASSWORD_PATTERN in self.html: - self.fail(_("Incorrect password")) + self.fail(_("Wrong password")) return super(MediafireCom, self).handle_free(pyfile) diff --git a/module/plugins/hoster/MegaDebridEu.py b/module/plugins/hoster/MegaDebridEu.py index 4afba0a3a..0dfc16c34 100644 --- a/module/plugins/hoster/MegaDebridEu.py +++ b/module/plugins/hoster/MegaDebridEu.py @@ -48,7 +48,7 @@ class MegaDebridEu(MultiHoster): Return The debrided link if succeed or original link if fail """ if not self.api_load(): - self.error("Unable to connect to remote API") + self.error(_("Unable to connect to remote API")) jsonResponse = self.load(self.API_URL, get={'action': 'getLink', 'token': self.token}, diff --git a/module/plugins/hoster/MegaRapidCz.py b/module/plugins/hoster/MegaRapidCz.py index c3cf8a2b6..69c1c411b 100644 --- a/module/plugins/hoster/MegaRapidCz.py +++ b/module/plugins/hoster/MegaRapidCz.py @@ -54,15 +54,12 @@ class MegaRapidCz(SimpleHoster): def handle_premium(self, pyfile): m = re.search(self.LINK_PREMIUM_PATTERN, self.html) - if m: + if m is not None: self.link = m.group(1) - else: - if re.search(self.ERR_LOGIN_PATTERN, self.html): - self.relogin() - self.retry(delay=60, msg=_("User login failed")) - elif re.search(self.ERR_CREDIT_PATTERN, self.html): - self.fail(_("Not enough credit left")) + elif re.search(self.ERR_LOGIN_PATTERN, self.html): + self.relogin() + self.retry(wait=60, msg=_("User login failed")) - else: - self.fail(_("Download link not found")) + elif re.search(self.ERR_CREDIT_PATTERN, self.html): + self.fail(_("Not enough credit left")) diff --git a/module/plugins/hoster/MegaRapidoNet.py b/module/plugins/hoster/MegaRapidoNet.py index b00daf713..573586639 100644 --- a/module/plugins/hoster/MegaRapidoNet.py +++ b/module/plugins/hoster/MegaRapidoNet.py @@ -42,15 +42,15 @@ class MegaRapidoNet(MultiHoster): def handle_premium(self, pyfile): self.html = self.load("http://megarapido.net/gerar.php", - post={'rand' :random_with_N_digits(16), - 'urllist' : pyfile.url, - 'links' : pyfile.url, - 'exibir' : "normal", - 'usar' : "premium", - 'user' : self.account.get_data('sid'), - 'autoreset': ""}) + post={'rand' :random_with_N_digits(16), + 'urllist' : pyfile.url, + 'links' : pyfile.url, + 'exibir' : "normal", + 'usar' : "premium", + 'user' : self.account.get_data('sid'), + 'autoreset': ""}) if "desloga e loga novamente para gerar seus links" in self.html.lower(): - self.error("You have logged in at another place") + self.error(_("You have logged in at another place")) return super(MegaRapidoNet, self).handle_premium(pyfile) diff --git a/module/plugins/hoster/MegasharesCom.py b/module/plugins/hoster/MegasharesCom.py index deee700ba..b183b882d 100644 --- a/module/plugins/hoster/MegasharesCom.py +++ b/module/plugins/hoster/MegasharesCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class MegasharesCom(SimpleHoster): __name__ = "MegasharesCom" __type__ = "hoster" - __version__ = "0.31" + __version__ = "0.32" __status__ = "testing" __pattern__ = r'http://(?:www\.)?(d\d{2}\.)?megashares\.com/((index\.php)?\?d\d{2}=|dl/)\w+' @@ -46,43 +46,40 @@ class MegasharesCom(SimpleHoster): def handle_free(self, pyfile): if self.NO_SLOTS_PATTERN in self.html: - self.retry(delay=5 * 60) + self.retry(wait=5 * 60) m = re.search(self.REACTIVATE_PASSPORT_PATTERN, self.html) - if m: + if m is not None: passport_num = m.group(1) request_uri = re.search(self.REQUEST_URI_PATTERN, self.html).group(1) - for _i in xrange(5): - random_num = re.search(self.REACTIVATE_NUM_PATTERN, self.html).group(1) + random_num = re.search(self.REACTIVATE_NUM_PATTERN, self.html).group(1) - verifyinput = self.captcha.decrypt("http://d01.megashares.com/index.php", - get={'secgfx': "gfx", 'random_num': random_num}) + verifyinput = self.captcha.decrypt("http://d01.megashares.com/index.php", + get={'secgfx': "gfx", 'random_num': random_num}) - self.log_info(_("Reactivating passport %s: %s %s") % (passport_num, random_num, verifyinput)) + self.log_info(_("Reactivating passport %s: %s %s") % (passport_num, random_num, verifyinput)) - res = self.load("http://d01.megashares.com%s" % request_uri, - get={'rs' : "check_passport_renewal", - 'rsargs[]': verifyinput, - 'rsargs[]': random_num, - 'rsargs[]': passport_num, - 'rsargs[]': "replace_sec_pprenewal", - 'rsrnd[]' : str(int(time.time() * 1000))}) + res = self.load("http://d01.megashares.com%s" % request_uri, + get={'rs' : "check_passport_renewal", + 'rsargs[]': verifyinput, + 'rsargs[]': random_num, + 'rsargs[]': passport_num, + 'rsargs[]': "replace_sec_pprenewal", + 'rsrnd[]' : str(int(time.time() * 1000))}) - if 'Thank you for reactivating your passport.' in res: - self.captcha.correct() - self.retry() - else: - self.captcha.invalid() + if 'Thank you for reactivating your passport' in res: + self.captcha.correct() + self.restart(premium=True) else: - self.fail(_("Failed to reactivate passport")) + self.retry_captcha(msg=_("Failed to reactivate passport")) m = re.search(self.PASSPORT_RENEW_PATTERN, self.html) - if m: + if m is not None: time = [int(x) for x in m.groups()] renew = time[0] + (time[1] * 60) + (time[2] * 60) self.log_debug("Waiting %d seconds for a new passport" % renew) - self.retry(delay=renew, msg=_("Passport renewal")) + self.retry(wait=renew, msg=_("Passport renewal")) #: Check traffic left on passport m = re.search(self.PASSPORT_LEFT_PATTERN, self.html, re.M | re.S) @@ -94,13 +91,12 @@ class MegasharesCom(SimpleHoster): self.log_info(_("Data left: %s %s (%d MB needed)") % (m.group(2), m.group(3), self.pyfile.size / 1048576)) if not data_left: - self.retry(delay=600, msg=_("Passport renewal")) + self.retry(wait=600, msg=_("Passport renewal")) self.handle_download(False) def handle_download(self, premium=False): - #: Find download link m = re.search(self.LINK_PATTERN % (1 if premium else 2), self.html) msg = _('%s download URL' % ('Premium' if premium else 'Free')) if m is None: diff --git a/module/plugins/hoster/MystoreTo.py b/module/plugins/hoster/MystoreTo.py index e4432f491..b23ca10bd 100644 --- a/module/plugins/hoster/MystoreTo.py +++ b/module/plugins/hoster/MystoreTo.py @@ -19,7 +19,7 @@ class MystoreTo(SimpleHoster): __description__ = """Mystore.to hoster plugin""" __license__ = "GPLv3" - __authors__ = [("zapp-brannigan", "")] + __authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")] NAME_PATTERN = r'<h1>(?P<N>.+?)<' diff --git a/module/plugins/hoster/NarodRu.py b/module/plugins/hoster/NarodRu.py index a20c23954..bea04c9cd 100644 --- a/module/plugins/hoster/NarodRu.py +++ b/module/plugins/hoster/NarodRu.py @@ -34,33 +34,25 @@ class NarodRu(SimpleHoster): def handle_free(self, pyfile): - for _i in xrange(5): - self.html = self.load('http://narod.ru/disk/getcapchaxml/?rnd=%d' % int(random.random() * 777)) + self.html = self.load('http://narod.ru/disk/getcapchaxml/?rnd=%d' % int(random.random() * 777)) - m = re.search(self.CAPTCHA_PATTERN, self.html) - if m is None: - self.error(_("Captcha")) + m = re.search(self.CAPTCHA_PATTERN, self.html) + if m is None: + self.error(_("Captcha")) - post_data = {'action': "sendcapcha"} - captcha_url, post_data['key'] = m.groups() - post_data['rep'] = self.captcha.decrypt(captcha_url) + post_data = {'action': "sendcapcha"} + captcha_url, post_data['key'] = m.groups() + post_data['rep'] = self.captcha.decrypt(captcha_url) - self.html = self.load(pyfile.url, post=post_data) + self.html = self.load(pyfile.url, post=post_data) - m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: - self.link = urlparse.urljoin("http://narod.ru/", m.group(1)) - self.captcha.correct() - break + m = re.search(self.LINK_FREE_PATTERN, self.html) + if m is not None: + self.captcha.correct() + self.link = urlparse.urljoin("http://narod.ru/", m.group(1)) - elif u'<b class="error-msg"><strong>ÐÑОблОÑÑ?</strong>' in self.html: - self.captcha.invalid() - - else: - self.error(_("Download link")) - - else: - self.fail(_("No valid captcha code entered")) + elif u'<b class="error-msg"><strong>ÐÑОблОÑÑ?</strong>' in self.html: + self.retry_captcha() getInfo = create_getInfo(NarodRu) diff --git a/module/plugins/hoster/NoPremiumPl.py b/module/plugins/hoster/NoPremiumPl.py index 0826d5252..8657d4527 100644 --- a/module/plugins/hoster/NoPremiumPl.py +++ b/module/plugins/hoster/NoPremiumPl.py @@ -66,14 +66,14 @@ class NoPremiumPl(MultiHoster): data = self.run_file_query(pyfile.url, 'fileinfo') except Exception: - self.log_debug("runFileQuery error") + self.log_debug("Query error #1") self.temp_offline() try: parsed = json_loads(data) except Exception: - self.log_debug("loads error") + self.log_debug("Data not found") self.temp_offline() self.log_debug(parsed) @@ -100,5 +100,5 @@ class NoPremiumPl(MultiHoster): self.link = self.run_file_query(pyfile.url, 'filedownload') except Exception: - self.log_debug("runFileQuery error #2") + self.log_debug("Query error #2") self.temp_offline() diff --git a/module/plugins/hoster/NosuploadCom.py b/module/plugins/hoster/NosuploadCom.py index 7de26f3fb..45521eebf 100644 --- a/module/plugins/hoster/NosuploadCom.py +++ b/module/plugins/hoster/NosuploadCom.py @@ -25,18 +25,18 @@ class NosuploadCom(XFSHoster): def get_download_link(self): - #: stage1: press the "Free Download" button + #: Stage1: press the "Free Download" button data = self.get_post_parameters() self.html = self.load(self.pyfile.url, post=data) - #: stage2: wait some time and press the "Download File" button + #: Stage2: wait some time and press the "Download File" button data = self.get_post_parameters() wait_time = re.search(self.WAIT_PATTERN, self.html, re.M | re.S).group(1) self.log_debug("Hoster told us to wait %s seconds" % wait_time) self.wait(wait_time) self.html = self.load(self.pyfile.url, post=data) - #: stage3: get the download link + #: Stage3: get the download link return re.search(self.LINK_PATTERN, self.html, re.S).group(1) diff --git a/module/plugins/hoster/NowDownloadSx.py b/module/plugins/hoster/NowDownloadSx.py index 5aadd0b3f..73b0efeaa 100644 --- a/module/plugins/hoster/NowDownloadSx.py +++ b/module/plugins/hoster/NowDownloadSx.py @@ -44,7 +44,7 @@ class NowDownloadSx(SimpleHoster): self.error() m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: wait = int(m.group(1)) else: wait = 60 @@ -56,10 +56,8 @@ class NowDownloadSx(SimpleHoster): self.html = self.load(baseurl + str(continuelink.group(1))) m = re.search(self.LINK_FREE_PATTERN, self.html) - if m is None: - self.error(_("Download link not found")) - - self.link = m.group(1) + if m is not None: + self.link = m.group(1) getInfo = create_getInfo(NowDownloadSx) diff --git a/module/plugins/hoster/NowVideoSx.py b/module/plugins/hoster/NowVideoSx.py index c1f369f2a..b919d74ab 100644 --- a/module/plugins/hoster/NowVideoSx.py +++ b/module/plugins/hoster/NowVideoSx.py @@ -37,10 +37,8 @@ class NowVideoSx(SimpleHoster): self.html = self.load("http://www.nowvideo.sx/mobile/video.php", get={'id': self.info['pattern']['ID']}) m = re.search(self.LINK_FREE_PATTERN, self.html) - if m is None: - self.error(_("Free download link not found")) - - self.link = m.group(1) + if m is not None: + self.link = m.group(1) getInfo = create_getInfo(NowVideoSx) diff --git a/module/plugins/hoster/OboomCom.py b/module/plugins/hoster/OboomCom.py index d294ae3c6..77cf6b68f 100644 --- a/module/plugins/hoster/OboomCom.py +++ b/module/plugins/hoster/OboomCom.py @@ -74,41 +74,36 @@ class OboomCom(Hoster): def solve_captcha(self): recaptcha = ReCaptcha(self) + response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY) - for _i in xrange(5): - response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY) - apiUrl = "http://www.oboom.com/1.0/download/ticket" - params = {'recaptcha_challenge_field': challenge, - 'recaptcha_response_field': response, - 'download_id': self.file_id, - 'token': self.session_token} - result = self.load_url(apiUrl, params) + apiUrl = "http://www.oboom.com/1.0/download/ticket" + params = {'recaptcha_challenge_field': challenge, + 'recaptcha_response_field': response, + 'download_id': self.file_id, + 'token': self.session_token} - if result[0] == 200: - self.download_token = result[1] - self.download_auth = result[2] - self.captcha.correct() - self.wait(30) - break - - elif result[0] == 400: - if result[1] == "incorrect-captcha-sol": - self.captcha.invalid() - elif result[1] == "captcha-timeout": - self.captcha.invalid() - elif result[1] == "forbidden": - self.retry(5, 15 * 60, _("Service unavailable")) - - elif result[0] == 403: + result = self.load_url(apiUrl, params) + + if result[0] == 200: + self.download_token = result[1] + self.download_auth = result[2] + self.captcha.correct() + self.wait(30) + + else: + if result[0] == 403: if result[1] == -1: #: Another download is running self.set_wait(15 * 60) else: self.set_wait(result[1], True) + self.wait() self.retry(5) - else: - self.captcha.invalid() - self.fail(_("Received invalid captcha 5 times")) + + elif result[0] == 400 and result[1] == "forbidden": + self.retry(5, 15 * 60, _("Service unavailable")) + + self.retry_captcha() def get_fileInfo(self, token, fileId): @@ -141,6 +136,6 @@ class OboomCom(Hoster): self.download_domain = result[1] self.download_ticket = result[2] elif result[0] == 421: - self.retry(delay=result[2] + 60, msg=_("Connection limit exceeded")) + self.retry(wait=result[2] + 60, msg=_("Connection limit exceeded")) else: self.fail(_("Could not retrieve download ticket. Error code: %s") % result[0]) diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py index 70229a6ef..f525e5b33 100644 --- a/module/plugins/hoster/OneFichierCom.py +++ b/module/plugins/hoster/OneFichierCom.py @@ -102,7 +102,7 @@ class OneFichierCom(SimpleHoster): url, inputs = self.parse_html_form('action="https://1fichier.com/\?%s' % id) if not url: - self.fail(_("Download link not found")) + return if "pass" in inputs: inputs['pass'] = self.get_password() diff --git a/module/plugins/hoster/OpenloadIo.py b/module/plugins/hoster/OpenloadIo.py index 1ebc12ad0..6213a9c09 100644 --- a/module/plugins/hoster/OpenloadIo.py +++ b/module/plugins/hoster/OpenloadIo.py @@ -10,7 +10,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class OpenloadIo(SimpleHoster): __name__ = "OpenloadIo" __type__ = "hoster" - __version__ = "0.06" + __version__ = "0.07" __status__ = "testing" __pattern__ = r'https?://(?:www\.)?openload\.(?:co|io)/f/([\w-_]+)' @@ -23,11 +23,11 @@ class OpenloadIo(SimpleHoster): # The API reference, that this implementation uses is available at https://openload.co/api API_URL = 'https://api.openload.co/1' - FILE_ID_PATTERN = '/f/([\w-_]+)' + _FILE_ID_PATTERN = '/f/([\w-_]+)' - DOWNLOAD_TICKET_URI_PATTERN = '/file/dlticket?file={0}' - DOWNLOAD_FILE_URI_PATTERN = '/file/dl?file={0}&ticket={1}' - FILE_INFO_URI_PATTERN = '/file/info?file={0}' + _DOWNLOAD_TICKET_URI_PATTERN = '/file/dlticket?file={0}' + _DOWNLOAD_FILE_URI_PATTERN = '/file/dl?file={0}&ticket={1}' + _FILE_INFO_URI_PATTERN = '/file/info?file={0}' @classmethod diff --git a/module/plugins/hoster/PornhostCom.py b/module/plugins/hoster/PornhostCom.py index 8b0a80c7f..e9d199a2e 100644 --- a/module/plugins/hoster/PornhostCom.py +++ b/module/plugins/hoster/PornhostCom.py @@ -49,7 +49,7 @@ class PornhostCom(Hoster): url = re.search(r'"http://file\d+\.pornhost\.com/\d+/.*?"', self.html) #@TODO: fix this one since it doesn't match - return url.group(1).strip() + return url.group(1) def get_file_name(self): diff --git a/module/plugins/hoster/PornhubCom.py b/module/plugins/hoster/PornhubCom.py index 5345566a1..ce6badedd 100644 --- a/module/plugins/hoster/PornhubCom.py +++ b/module/plugins/hoster/PornhubCom.py @@ -67,7 +67,7 @@ class PornhubCom(Hoster): self.download_html() m = re.search(r'<title.+?>([^<]+) - ', self.html) - if m: + if m is not None: name = m.group(1) else: matches = re.findall('<h1>(.*?)</h1>', self.html) diff --git a/module/plugins/hoster/PremiumizeMe.py b/module/plugins/hoster/PremiumizeMe.py index e682a5a4c..16c252dc1 100644 --- a/module/plugins/hoster/PremiumizeMe.py +++ b/module/plugins/hoster/PremiumizeMe.py @@ -54,7 +54,7 @@ class PremiumizeMe(MultiHoster): return elif status == 400: - self.fail(_("Invalid link")) + self.fail(_("Invalid url")) elif status == 404: self.offline() diff --git a/module/plugins/hoster/QuickshareCz.py b/module/plugins/hoster/QuickshareCz.py index 2baef4c6d..62240667c 100644 --- a/module/plugins/hoster/QuickshareCz.py +++ b/module/plugins/hoster/QuickshareCz.py @@ -69,12 +69,12 @@ class QuickshareCz(SimpleHoster): if m is None: self.fail(_("File not found")) - self.link = m.group(1).rstrip() #@TODO: Remove .rstrip() in 0.4.10 + self.link = m.group(1) self.log_debug("FREE URL2:" + self.link) #: Check errors m = re.search(r'/chyba/(\d+)', self.link) - if m: + if m is not None: if m.group(1) == "1": self.retry(60, 2 * 60, "This IP is already downloading") elif m.group(1) == "2": diff --git a/module/plugins/hoster/RPNetBiz.py b/module/plugins/hoster/RPNetBiz.py index 5207832ee..cbe3e2a52 100644 --- a/module/plugins/hoster/RPNetBiz.py +++ b/module/plugins/hoster/RPNetBiz.py @@ -28,7 +28,6 @@ class RPNetBiz(MultiHoster): def handle_premium(self, pyfile): user, info = self.account.select() - #: Get the download link res = self.load("https://premium.rpnet.biz/client_api.php", get={'username': user, 'password': info['login']['password'], diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py index 3f2003034..711f33e87 100644 --- a/module/plugins/hoster/RapidgatorNet.py +++ b/module/plugins/hoster/RapidgatorNet.py @@ -86,7 +86,7 @@ class RapidgatorNet(SimpleHoster): else: self.account.relogin() - self.retry(delay=60) + self.retry(wait=60) def handle_premium(self, pyfile): @@ -122,29 +122,25 @@ class RapidgatorNet(SimpleHoster): url = "http://rapidgator.net%s" % jsvars.get('captchaUrl', '/download/captcha') self.html = self.load(url) - for _i in xrange(5): - m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: - self.link = m.group(1) - break - else: - captcha = self.handle_captcha() + m = re.search(self.LINK_FREE_PATTERN, self.html) + if m is not None: + self.link = m.group(1) + else: + captcha = self.handle_captcha() - if not captcha: - self.error(_("Captcha pattern not found")) + if not captcha: + self.error(_("Captcha pattern not found")) - response, challenge = captcha.challenge() + response, challenge = captcha.challenge() - self.html = self.load(url, post={'DownloadCaptchaForm[captcha]': "", - 'adcopy_challenge' : challenge, - 'adcopy_response' : response}) + self.html = self.load(url, post={'DownloadCaptchaForm[captcha]': "", + 'adcopy_challenge' : challenge, + 'adcopy_response' : response}) - if "The verification code is incorrect" in self.html: - self.captcha.invalid() - else: - self.captcha.correct() - else: - self.error(_("Download link")) + if "The verification code is incorrect" in self.html: + self.retry_captcha() + else: + self.captcha.correct() def handle_captcha(self): diff --git a/module/plugins/hoster/RapiduNet.py b/module/plugins/hoster/RapiduNet.py index 267f41f36..99c877226 100644 --- a/module/plugins/hoster/RapiduNet.py +++ b/module/plugins/hoster/RapiduNet.py @@ -20,7 +20,7 @@ class RapiduNet(SimpleHoster): __description__ = """Rapidu.net hoster plugin""" __license__ = "GPLv3" - __authors__ = [("prOq", "")] + __authors__ = [("prOq", None)] COOKIES = [("rapidu.net", "rapidu_lang", "en")] diff --git a/module/plugins/hoster/SendspaceCom.py b/module/plugins/hoster/SendspaceCom.py index 13dd20b7c..ece048ed9 100644 --- a/module/plugins/hoster/SendspaceCom.py +++ b/module/plugins/hoster/SendspaceCom.py @@ -30,32 +30,31 @@ class SendspaceCom(SimpleHoster): def handle_free(self, pyfile): - params = {} - for _i in xrange(3): - m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: - if 'captcha_hash' in params: - self.captcha.correct() - self.link = m.group(1) - break + m = re.search(self.LINK_FREE_PATTERN, self.html) + if m is not None: + self.link = m.group(1) + else: m = re.search(self.CAPTCHA_PATTERN, self.html) - if m: - if 'captcha_hash' in params: - self.captcha.invalid() + if m is None: + params = {'download': "Regular Download"} + else: captcha_url1 = "http://www.sendspace.com/" + m.group(1) m = re.search(self.USER_CAPTCHA_PATTERN, self.html) captcha_url2 = "http://www.sendspace.com/" + m.group(1) params = {'captcha_hash': m.group(2), 'captcha_submit': 'Verify', 'captcha_answer': self.captcha.decrypt(captcha_url1) + " " + self.captcha.decrypt(captcha_url2)} - else: - params = {'download': "Regular Download"} self.log_debug(params) + self.html = self.load(pyfile.url, post=params) - else: - self.fail(_("Download link not found")) + + m = re.search(self.LINK_FREE_PATTERN, self.html) + if m is None: + self.retry_captcha() + else: + self.link = m.group(1) getInfo = create_getInfo(SendspaceCom) diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py index 56177f97a..a8f4a5c8b 100644 --- a/module/plugins/hoster/ShareonlineBiz.py +++ b/module/plugins/hoster/ShareonlineBiz.py @@ -67,25 +67,20 @@ class ShareonlineBiz(SimpleHoster): def handle_captcha(self): recaptcha = ReCaptcha(self) - - for _i in xrange(5): - response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY) - - m = re.search(r'var wait=(\d+);', self.html) - self.set_wait(int(m.group(1)) if m else 30) - - res = self.load("%s/free/captcha/%d" % (self.pyfile.url, int(time.time() * 1000)), - post={'dl_free' : "1", - 'recaptcha_challenge_field': challenge, - 'recaptcha_response_field' : response}) - if res != "0": - self.captcha.correct() - return res - else: - self.captcha.invalid() + response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY) + + m = re.search(r'var wait=(\d+);', self.html) + self.set_wait(int(m.group(1)) if m else 30) + + res = self.load("%s/free/captcha/%d" % (self.pyfile.url, int(time.time() * 1000)), + post={'dl_free' : "1", + 'recaptcha_challenge_field': challenge, + 'recaptcha_response_field' : response}) + if res != "0": + self.captcha.correct() + return res else: - self.captcha.invalid() - self.fail(_("No valid captcha solution received")) + self.retry_captcha() def handle_free(self, pyfile): @@ -100,7 +95,7 @@ class ShareonlineBiz(SimpleHoster): self.link = res.decode('base64') if not self.link.startswith("http://"): - self.error(_("Wrong download url")) + self.error(_("Invalid url")) self.wait() @@ -110,12 +105,10 @@ class ShareonlineBiz(SimpleHoster): 'fail' : re.compile(r"<title>Share-Online")}) if check == "cookie": - self.captcha.invalid() - self.retry(5, 60, _("Cookie failure")) + self.retry_captcha(5, 60, _("Cookie failure")) elif check == "fail": - self.captcha.invalid() - self.retry(5, 5 * 60, _("Download failed")) + self.retry_captcha(5, 5 * 60, _("Download failed")) return super(ShareonlineBiz, self).check_download() @@ -170,7 +163,7 @@ class ShareonlineBiz(SimpleHoster): self.fail(_("Premium account needed")) elif errmsg in ("expired", "server"): - self.retry(delay=600, msg=errmsg) + self.retry(wait=600, msg=errmsg) elif errmsg == "full": self.retry(10, 600, _("Server is full")) @@ -181,7 +174,7 @@ class ShareonlineBiz(SimpleHoster): else: self.wantReconnect = True - self.retry(delay=60, msg=errmsg) + self.retry(wait=60, msg=errmsg) getInfo = create_getInfo(ShareonlineBiz) diff --git a/module/plugins/hoster/ShareplaceCom.py b/module/plugins/hoster/ShareplaceCom.py index 11aef0c90..6b4cfed2b 100644 --- a/module/plugins/hoster/ShareplaceCom.py +++ b/module/plugins/hoster/ShareplaceCom.py @@ -40,7 +40,7 @@ class ShareplaceCom(Hoster): #: var zzipitime = 15 m = re.search(r'var zzipitime = (\d+);', self.html) - if m: + if m is not None: sec = int(m.group(1)) else: sec = 0 diff --git a/module/plugins/hoster/SimplyPremiumCom.py b/module/plugins/hoster/SimplyPremiumCom.py index 01b21079d..8e3890fb8 100644 --- a/module/plugins/hoster/SimplyPremiumCom.py +++ b/module/plugins/hoster/SimplyPremiumCom.py @@ -40,7 +40,7 @@ class SimplyPremiumCom(MultiHoster): elif "trafficlimit" in self.html: self.log_warning(_("Reached daily limit for this host")) - self.retry(delay=seconds_to_midnight(), msg="Daily limit for this host reached") + self.retry(wait=seconds_to_midnight(), msg="Daily limit for this host reached") elif "hostererror" in self.html: self.log_warning(_("Hoster temporarily unavailable, waiting 1 minute and retry")) diff --git a/module/plugins/hoster/SizedriveCom.py b/module/plugins/hoster/SizedriveCom.py index 8bfe46e86..d0db9985b 100644 --- a/module/plugins/hoster/SizedriveCom.py +++ b/module/plugins/hoster/SizedriveCom.py @@ -35,7 +35,7 @@ class SizedriveCom(SimpleHoster): post={'id': self.info['pattern']['ID']}) m = re.search(r'<span id="boton_download" ><a href="(.+?)"', self.html) - if m: + if m is not None: self.link = m.group(1) diff --git a/module/plugins/hoster/SmoozedCom.py b/module/plugins/hoster/SmoozedCom.py index 67e590cec..e864bb2c0 100644 --- a/module/plugins/hoster/SmoozedCom.py +++ b/module/plugins/hoster/SmoozedCom.py @@ -16,7 +16,7 @@ class SmoozedCom(MultiHoster): __description__ = """Smoozed.com hoster plugin""" __license__ = "GPLv3" - __authors__ = [("", "")] + __authors__ = [(None, None)] FILE_ERRORS = [("Error", r'{"state":"error"}'), diff --git a/module/plugins/hoster/TurbobitNet.py b/module/plugins/hoster/TurbobitNet.py index d323a214b..aad56788c 100644 --- a/module/plugins/hoster/TurbobitNet.py +++ b/module/plugins/hoster/TurbobitNet.py @@ -56,64 +56,64 @@ class TurbobitNet(SimpleHoster): self.req.http.c.setopt(pycurl.HTTPHEADER, ["X-Requested-With:"]) m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: + if m is not None: self.link = m.group(1) def solve_captcha(self): - for _i in xrange(5): - m = re.search(self.LIMIT_WAIT_PATTERN, self.html) - if m: - wait_time = int(m.group(1)) - self.wait(wait_time, wait_time > 60) - self.retry() + m = re.search(self.LIMIT_WAIT_PATTERN, self.html) + if m is not None: + wait_time = int(m.group(1)) + self.wait(wait_time, wait_time > 60) + self.retry() - action, inputs = self.parse_html_form("action='#'") - if not inputs: - self.error(_("Captcha form not found")) - self.log_debug(inputs) + action, inputs = self.parse_html_form("action='#'") + if not inputs: + self.error(_("Captcha form not found")) - if inputs['captcha_type'] == "recaptcha": - recaptcha = ReCaptcha(self) - inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge() - else: - m = re.search(self.CAPTCHA_PATTERN, self.html) - if m is None: - self.error(_("captcha")) - captcha_url = m.group(1) - inputs['captcha_response'] = self.captcha.decrypt(captcha_url) + self.log_debug(inputs) - self.log_debug(inputs) - self.html = self.load(self.url, post=inputs) + if inputs['captcha_type'] == "recaptcha": + recaptcha = ReCaptcha(self) + inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge() + else: + m = re.search(self.CAPTCHA_PATTERN, self.html) + if m is None: + self.error(_("Captcha pattern not found")) + captcha_url = m.group(1) + inputs['captcha_response'] = self.captcha.decrypt(captcha_url) - if '<div class="captcha-error">Incorrect, try again!<' in self.html: - self.captcha.invalid() - else: - self.captcha.correct() - break + self.log_debug(inputs) + + self.html = self.load(self.url, post=inputs) + + if '<div class="captcha-error">Incorrect, try again' in self.html: + self.retry_captcha() else: - self.fail(_("Invalid captcha")) + self.captcha.correct() def get_rt_update(self): rtUpdate = self.retrieve("rtUpdate") - if not rtUpdate: - if self.retrieve("version") is not self.__version__ \ - or int(self.retrieve("timestamp", 0)) + 86400000 < timestamp(): - #: that's right, we are even using jdownloader updates - rtUpdate = self.load("http://update0.jdownloader.org/pluginstuff/tbupdate.js") - rtUpdate = self.decrypt(rtUpdate.splitlines()[1]) - #: But we still need to fix the syntax to work with other engines than rhino - rtUpdate = re.sub(r'for each\(var (\w+) in(\[[^\]]+\])\)\{', - r'zza=\2;for(var zzi=0;zzi<zza.length;zzi++){\1=zza[zzi];', rtUpdate) - rtUpdate = re.sub(r"for\((\w+)=", r"for(var \1=", rtUpdate) - - self.store("rtUpdate", rtUpdate) - self.store("timestamp", timestamp()) - self.store("version", self.__version__) - else: - self.log_error(_("Unable to download, wait for update...")) - self.temp_offline() + if rtUpdate: + return rtUpdate + + if self.retrieve("version") is not self.__version__ or \ + int(self.retrieve("timestamp", 0)) + 86400000 < timestamp(): + #: that's right, we are even using jdownloader updates + rtUpdate = self.load("http://update0.jdownloader.org/pluginstuff/tbupdate.js") + rtUpdate = self.decrypt(rtUpdate.splitlines()[1]) + #: But we still need to fix the syntax to work with other engines than rhino + rtUpdate = re.sub(r'for each\(var (\w+) in(\[[^\]]+\])\)\{', + r'zza=\2;for(var zzi=0;zzi<zza.length;zzi++){\1=zza[zzi];', rtUpdate) + rtUpdate = re.sub(r"for\((\w+)=", r"for(var \1=", rtUpdate) + + self.store("rtUpdate", rtUpdate) + self.store("timestamp", timestamp()) + self.store("version", self.__version__) + else: + self.log_error(_("Unable to download, wait for update...")) + self.temp_offline() return rtUpdate @@ -122,7 +122,7 @@ class TurbobitNet(SimpleHoster): self.req.http.lastURL = self.url m = re.search("(/\w+/timeout\.js\?\w+=)([^\"\'<>]+)", self.html) - if m: + if m is not None: url = "http://turbobit.net%s%s" % m.groups() else: url = "http://turbobit.net/files/timeout.js?ver=%s" % "".join(random.choice('0123456789ABCDEF') for _i in xrange(32)) diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py index ba9ac390e..cc07770d4 100644 --- a/module/plugins/hoster/UlozTo.py +++ b/module/plugins/hoster/UlozTo.py @@ -52,7 +52,7 @@ class UlozTo(SimpleHoster): if not action or not inputs: self.error(_("Free download form not found")) - self.log_debug("inputs.keys = " + str(inputs.keys())) + self.log_debug("inputs.keys = %s" % inputs.keys()) #: Get and decrypt captcha if all(key in inputs for key in ("captcha_value", "captcha_id", "captcha_key")): #: Old version - last seen 9.12.2013 @@ -70,7 +70,7 @@ class UlozTo(SimpleHoster): xapca = self.load("http://www.ulozto.net/reloadXapca.php", get={'rnd': str(int(time.time()))}) xapca = xapca.replace('sound":"', 'sound":"http:').replace('image":"', 'image":"http:') - self.log_debug("xapca = " + str(xapca)) + self.log_debug("xapca = %s" % xapca) data = json_loads(xapca) captcha_value = self.captcha.decrypt(str(data['image'])) @@ -110,7 +110,7 @@ class UlozTo(SimpleHoster): post={'password': password, 'password_send': 'Send'}) if self.PASSWD_PATTERN in self.html: - self.fail(_("Incorrect password")) + self.fail(_("Wrong password")) else: self.fail(_("No password found")) @@ -130,8 +130,7 @@ class UlozTo(SimpleHoster): }) if check == "wrong_captcha": - self.captcha.invalid() - self.retry(msg=_("Wrong captcha code")) + self.retry_captcha() elif check == "offline": self.offline() diff --git a/module/plugins/hoster/UloziskoSk.py b/module/plugins/hoster/UloziskoSk.py index 12e88cf1c..5bbbb1f7c 100644 --- a/module/plugins/hoster/UloziskoSk.py +++ b/module/plugins/hoster/UloziskoSk.py @@ -35,7 +35,7 @@ class UloziskoSk(SimpleHoster): self.get_fileInfo() m = re.search(self.IMG_PATTERN, self.html) - if m: + if m is not None: self.link = "http://ulozisko.sk" + m.group(1) else: self.handle_free(pyfile) diff --git a/module/plugins/hoster/UnibytesCom.py b/module/plugins/hoster/UnibytesCom.py index b82c04ad1..50006dd27 100644 --- a/module/plugins/hoster/UnibytesCom.py +++ b/module/plugins/hoster/UnibytesCom.py @@ -40,7 +40,7 @@ class UnibytesCom(SimpleHoster): self.html = self.load(urlparse.urljoin(domain, action), post=post_data) m = re.search(r'location:\s*(\S+)', self.req.http.header, re.I) - if m: + if m is not None: self.link = m.group(1) break @@ -50,12 +50,12 @@ class UnibytesCom(SimpleHoster): if post_data['step'] == "last": m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: - self.link = m.group(1) + if m is not None: self.captcha.correct() + self.link = m.group(1) break else: - self.captcha.invalid() + self.retry_captcha() last_step = post_data['step'] action, post_data = self.parse_html_form('id="stepForm"') diff --git a/module/plugins/hoster/UpleaCom.py b/module/plugins/hoster/UpleaCom.py index 15d47dec5..9c422ce01 100644 --- a/module/plugins/hoster/UpleaCom.py +++ b/module/plugins/hoster/UpleaCom.py @@ -49,7 +49,7 @@ class UpleaCom(XFSHoster): self.html = self.load(urlparse.urljoin("http://uplea.com/", m.group(1))) m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: self.log_debug("Waiting %s seconds" % m.group(1)) self.wait(m.group(1), True) self.retry() diff --git a/module/plugins/hoster/UploadheroCom.py b/module/plugins/hoster/UploadheroCom.py index ded0d60dd..517ed293a 100644 --- a/module/plugins/hoster/UploadheroCom.py +++ b/module/plugins/hoster/UploadheroCom.py @@ -50,14 +50,14 @@ class UploadheroCom(SimpleHoster): get={'code': captcha}) m = re.search(self.LINK_FREE_PATTERN, self.html) - if m: + if m is not None: self.link = m.group(1) or m.group(2) self.wait(50) def check_errors(self): m = re.search(self.IP_BLOCKED_PATTERN, self.html) - if m: + if m is not None: self.html = self.load(urlparse.urljoin("http://uploadhero.co/", m.group(1))) m = re.search(self.IP_WAIT_PATTERN, self.html) diff --git a/module/plugins/hoster/UploadingCom.py b/module/plugins/hoster/UploadingCom.py index 36f0c766e..a7878f731 100644 --- a/module/plugins/hoster/UploadingCom.py +++ b/module/plugins/hoster/UploadingCom.py @@ -61,7 +61,7 @@ class UploadingCom(SimpleHoster): def handle_free(self, pyfile): m = re.search('<h2>((Daily )?Download Limit)</h2>', self.html) - if m: + if m is not None: pyfile.error = encode(m.group(1)) self.log_warning(pyfile.error) self.retry(6, (6 * 60 if m.group(2) else 15) * 60, pyfile.error) @@ -88,7 +88,7 @@ class UploadingCom(SimpleHoster): self.html = self.load(url) m = re.search(r'<form id="file_form" action="(.*?)"', self.html) - if m: + if m is not None: url = m.group(1) else: self.error(_("No URL")) diff --git a/module/plugins/hoster/UpstoreNet.py b/module/plugins/hoster/UpstoreNet.py index 12c667efb..caa12e8af 100644 --- a/module/plugins/hoster/UpstoreNet.py +++ b/module/plugins/hoster/UpstoreNet.py @@ -62,13 +62,11 @@ class UpstoreNet(SimpleHoster): #: STAGE 3: get direct link m = re.search(self.LINK_FREE_PATTERN, self.html, re.S) - if m: + if m is not None: break - if m is None: - self.error(_("Download link not found")) - - self.link = m.group(1) + if m is not None: + self.link = m.group(1) getInfo = create_getInfo(UpstoreNet) diff --git a/module/plugins/hoster/VeohCom.py b/module/plugins/hoster/VeohCom.py index 7d46ee335..ba18fd529 100644 --- a/module/plugins/hoster/VeohCom.py +++ b/module/plugins/hoster/VeohCom.py @@ -42,7 +42,7 @@ class VeohCom(SimpleHoster): for q in quality: pattern = r'"fullPreviewHash%sPath":"(.+?)"' % q m = re.search(pattern, self.html) - if m: + if m is not None: pyfile.name += ".mp4" self.link = m.group(1).replace("\\", "") return diff --git a/module/plugins/hoster/WebshareCz.py b/module/plugins/hoster/WebshareCz.py index 0009cc471..a11b59492 100644 --- a/module/plugins/hoster/WebshareCz.py +++ b/module/plugins/hoster/WebshareCz.py @@ -49,7 +49,7 @@ class WebshareCz(SimpleHoster): self.log_debug("API data: " + api_data) m = re.search('<link>(.+)</link>', api_data) - if m: + if m is not None: self.link = m.group(1) diff --git a/module/plugins/hoster/XHamsterCom.py b/module/plugins/hoster/XHamsterCom.py index 8df1a441f..576451644 100644 --- a/module/plugins/hoster/XHamsterCom.py +++ b/module/plugins/hoster/XHamsterCom.py @@ -79,6 +79,7 @@ class XHamsterCom(Hoster): file_url = re.search(r"<a href=\"" + srv_url + "(.+?)\"", self.html) if file_url is None: self.error(_("file_url not found")) + file_url = file_url.group(1) long_url = srv_url + file_url self.log_debug("long_url = " + long_url) diff --git a/module/plugins/hoster/Xdcc.py b/module/plugins/hoster/Xdcc.py index aba66ee94..098143751 100644 --- a/module/plugins/hoster/Xdcc.py +++ b/module/plugins/hoster/Xdcc.py @@ -172,10 +172,10 @@ class Xdcc(Hoster): retry = time.time() + 300 if "you must be on a known channel to request a pack" in msg['text']: - self.fail(_("Wrong channel")) + self.fail(_("Invalid channel")) m = re.match('\x01DCC SEND (.*?) (\d+) (\d+)(?: (\d+))?\x01', msg['text']) - if m: + if m is not None: done = True #: Get connection data diff --git a/module/plugins/hoster/YadiSk.py b/module/plugins/hoster/YadiSk.py index a907cd282..354ba1b4c 100644 --- a/module/plugins/hoster/YadiSk.py +++ b/module/plugins/hoster/YadiSk.py @@ -34,7 +34,7 @@ class YadiSk(SimpleHoster): info ['idclient'] += random.choice('0123456abcdef') m = re.search(r'<script id="models-client" type="application/json">(.+?)</script>', html) - if m: + if m is not None: api_data = json_loads(m.group(1)) try: for sect in api_data: diff --git a/module/plugins/hoster/YourfilesTo.py b/module/plugins/hoster/YourfilesTo.py index a75bbcc94..cdf69afbe 100644 --- a/module/plugins/hoster/YourfilesTo.py +++ b/module/plugins/hoster/YourfilesTo.py @@ -41,7 +41,7 @@ class YourfilesTo(Hoster): #: var zzipitime = 15 m = re.search(r'var zzipitime = (\d+);', self.html) - if m: + if m is not None: sec = int(m.group(1)) else: sec = 0 diff --git a/module/plugins/internal/Account.py b/module/plugins/internal/Account.py index 7060959ee..123241be3 100644 --- a/module/plugins/internal/Account.py +++ b/module/plugins/internal/Account.py @@ -331,7 +331,7 @@ class Account(Plugin): continue except Exception: - self.log_warning(_("Wrong time format `%s` for account `%s`, use 1:22-3:44") + self.log_warning(_("Invalid time format `%s` for account `%s`, use 1:22-3:44") % (user, time_data)) if data['trafficleft'] == 0: diff --git a/module/plugins/internal/Base.py b/module/plugins/internal/Base.py new file mode 100644 index 000000000..4235cf94d --- /dev/null +++ b/module/plugins/internal/Base.py @@ -0,0 +1,493 @@ +# -*- coding: utf-8 -*- + +import inspect +import mimetypes +import os +import time +import urlparse + +from module.plugins.internal.Captcha import Captcha +from module.plugins.internal.Plugin import (Plugin, Abort, Fail, Reconnect, Retry, Skip, + decode, encode, fixurl, parse_html_form, + parse_name, replace_patterns) + + +#@TODO: Remove in 0.4.10 +def getInfo(urls): + #: result = [ .. (name, size, status, url) .. ] + pass + + +#@TODO: Remove in 0.4.10 +def create_getInfo(klass): + def get_info(urls): + for url in urls: + if hasattr(klass, "URL_REPLACEMENTS"): + url = replace_patterns(url, klass.URL_REPLACEMENTS) + yield parse_fileInfo(klass, url) + + return get_info + + +#@NOTE: `check_abort` decorator +def check_abort(fn): + + def wrapper(self, *args, **kwargs): + self.check_abort() + return fn(self, *args, **kwargs) + + return wrapper + + +class Base(Plugin): + __name__ = "Base" + __type__ = "base" + __version__ = "0.01" + __status__ = "testing" + + __pattern__ = r'^unmatchable$' + __config__ = [("use_premium", "bool", "Use premium account if available", True)] + + __description__ = """Base plugin for Hoster and Crypter""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + def __init__(self, pyfile): + self._init(pyfile.m.core) + + #: Engage wan reconnection + self.wantReconnect = False #@TODO: Change to `want_reconnect` in 0.4.10 + + #: Enable simultaneous processing of multiple downloads + self.multiDL = True #@TODO: Change to `multi_dl` in 0.4.10 + + #: time.time() + wait in seconds + self.wait_until = 0 + self.waiting = False + + #: Account handler instance, see :py:class:`Account` + self.account = None + self.user = None #@TODO: Remove in 0.4.10 + + #: Associated pyfile instance, see `PyFile` + self.pyfile = pyfile + + self.thread = None #: Holds thread in future + + #: Js engine, see `JsEngine` + self.js = self.pyload.js + + #: Captcha stuff + self.captcha = Captcha(self) + + #: Some plugins store html code here + self.html = None + + #: Dict of the amount of retries already made + self.retries = {} + + + def _log(self, level, plugintype, pluginname, messages): + log = getattr(self.pyload.log, level) + msg = u" | ".join(decode(a).strip() for a in messages if a) + log("%(plugintype)s %(pluginname)s[%(id)s]: %(msg)s" + % {'plugintype': plugintype.upper(), + 'pluginname': pluginname, + 'id' : self.pyfile.id, + 'msg' : msg}) + + + @classmethod + def get_info(cls, url="", html=""): + url = fixurl(url) + info = {'name' : parse_name(url), + 'size' : 0, + 'status': 3 if url else 8, + 'url' : url} + + return info + + + def init(self): + """ + Initialize the plugin (in addition to `__init__`) + """ + pass + + + def setup(self): + """ + Setup for enviroment and other things, called before downloading (possibly more than one time) + """ + pass + + + def _setup(self): + #@TODO: Remove in 0.4.10 + self.html = "" + self.pyfile.error = "" + self.last_html = None + + if self.get_config('use_premium', True): + self.load_account() #@TODO: Move to PluginThread in 0.4.10 + else: + self.account = False + self.user = None #@TODO: Remove in 0.4.10 + + try: + self.req.close() + except Exception: + pass + + if self.account: + self.req = self.pyload.requestFactory.getRequest(self.__name__, self.account.user) + self.chunk_limit = -1 #: -1 for unlimited + self.resume_download = True + self.premium = self.account.premium + else: + self.req = self.pyload.requestFactory.getRequest(self.__name__) + self.chunk_limit = 1 + self.resume_download = False + self.premium = False + + self.setup() + + + def load_account(self): + if not self.account: + self.account = self.pyload.accountManager.getAccountPlugin(self.__name__) + + if not self.account: + self.account = False + self.user = None #@TODO: Remove in 0.4.10 + + else: + self.account.choose() + self.user = self.account.user #@TODO: Remove in 0.4.10 + if self.account.user is None: + self.account = False + + + def _process(self, thread): + """ + Handles important things to do before starting + """ + self.thread = thread + + self._setup() + + # self.pyload.hookManager.downloadPreparing(self.pyfile) #@TODO: Recheck in 0.4.10 + self.check_abort() + + self.pyfile.setStatus("starting") + + self.log_debug("PROCESS URL " + self.pyfile.url, "PLUGIN VERSION %s" % self.__version__) + self.process(self.pyfile) + + + #: Deprecated method, use `_process` instead (Remove in 0.4.10) + def preprocessing(self, *args, **kwargs): + return self._process(*args, **kwargs) + + + def process(self, pyfile): + """ + The "main" method of every hoster plugin, you **have to** overwrite it + """ + raise NotImplementedError + + + def set_reconnect(self, reconnect): + self.log_debug("RECONNECT %s required" % ("" if reconnect else "not"), + "Previous wantReconnect: %s" % self.wantReconnect) + self.wantReconnect = bool(reconnect) + + + def set_wait(self, seconds, reconnect=None): + """ + Set a specific wait time later used with `wait` + + :param seconds: wait time in seconds + :param reconnect: True if a reconnect would avoid wait time + """ + wait_time = max(int(seconds), 1) + wait_until = time.time() + wait_time + 1 + + self.log_debug("WAIT set to %d seconds" % wait_time, + "Previous waitUntil: %f" % self.pyfile.waitUntil) + + self.pyfile.waitUntil = wait_until + + if reconnect is not None: + self.set_reconnect(reconnect) + + + def wait(self, seconds=None, reconnect=None): + """ + Waits the time previously set + """ + pyfile = self.pyfile + + if seconds is not None: + self.set_wait(seconds) + + if reconnect is not None: + self.set_reconnect(reconnect) + + self.waiting = True + + status = pyfile.status #@NOTE: Recheck in 0.4.10 + pyfile.setStatus("waiting") + + self.log_info(_("Waiting %d seconds...") % (pyfile.waitUntil - time.time())) + + if self.wantReconnect: + self.log_info(_("Requiring reconnection...")) + if self.account: + self.log_warning("Ignore reconnection due logged account") + + if not self.wantReconnect or self.account: + while pyfile.waitUntil > time.time(): + self.check_abort() + time.sleep(2) + + else: + while pyfile.waitUntil > time.time(): + self.check_abort() + self.thread.m.reconnecting.wait(1) + + if self.thread.m.reconnecting.isSet(): + self.waiting = False + self.wantReconnect = False + raise Reconnect + + time.sleep(2) + + self.waiting = False + pyfile.status = status #@NOTE: Recheck in 0.4.10 + + + def skip(self, msg=""): + """ + Skip and give msg + """ + raise Skip(encode(msg or self.pyfile.error or self.pyfile.pluginname)) #@TODO: Remove `encode` in 0.4.10 + + + #@TODO: Remove in 0.4.10 + def fail(self, msg): + """ + Fail and give msg + """ + msg = msg.strip() + + if msg: + self.pyfile.error = msg + else: + msg = self.pyfile.error or (self.info['error'] if 'error' in self.info else self.pyfile.getStatusName()) + + raise Fail(encode(msg)) #@TODO: Remove `encode` in 0.4.10 + + + def error(self, msg="", type=_("Parse")): + type = _("%s error") % type.strip().capitalize() if type else _("Unknown") + msg = _("%(type)s: %(msg)s | Plugin may be out of date" + % {'type': type, 'msg': msg or self.pyfile.error}) + + self.fail(msg) + + + def abort(self, msg=""): + """ + Abort and give msg + """ + if msg: #@TODO: Remove in 0.4.10 + self.pyfile.error = encode(msg) + + raise Abort + + + #@TODO: Recheck in 0.4.10 + def offline(self, msg=""): + """ + Fail and indicate file is offline + """ + self.fail("offline") + + + #@TODO: Recheck in 0.4.10 + def temp_offline(self, msg=""): + """ + Fail and indicates file ist temporary offline, the core may take consequences + """ + self.fail("temp. offline") + + + def retry(self, attemps=5, wait=1, msg=""): + """ + Retries and begin again from the beginning + + :param attemps: number of maximum retries + :param wait: time to wait in seconds before retry + :param msg: message passed to fail if attemps value was reached + """ + id = inspect.currentframe().f_back.f_lineno + if id not in self.retries: + self.retries[id] = 0 + + if 0 < attemps <= self.retries[id]: + self.fail(msg or _("Max retries reached")) + + self.wait(wait, False) + + self.retries[id] += 1 + raise Retry(encode(msg)) #@TODO: Remove `encode` in 0.4.10 + + + def retry_captcha(self, attemps=10, wait=1, msg=_("Wrong captcha")): + self.captcha.invalid() + self.retry(attemps, wait, msg) + + + def fixurl(self, url, baseurl=None, unquote=True): + url = fixurl(url) + + if not baseurl: + baseurl = fixurl(self.pyfile.url) + + if not urlparse.urlparse(url).scheme: + url_p = urlparse.urlparse(baseurl) + baseurl = "%s://%s" % (url_p.scheme, url_p.netloc) + url = urlparse.urljoin(baseurl, url) + + return fixurl(url, unquote) + + + @check_abort + def load(self, *args, **kwargs): + return super(Hoster, self).load(*args, **kwargs) + + + def check_abort(self): + if not self.pyfile.abort: + return + + if self.pyfile.status is 8: + self.fail() + + elif self.pyfile.status is 4: + self.skip(self.pyfile.statusname) + + elif self.pyfile.status is 1: + self.offline() + + elif self.pyfile.status is 6: + self.temp_offline() + + else: + self.abort() + + + def direct_link(self, url, follow_location=None): + link = "" + + if follow_location is None: + redirect = 1 + + elif type(follow_location) is int: + redirect = max(follow_location, 1) + + else: + redirect = self.get_config("maxredirs", 10, "UserAgentSwitcher") + + for i in xrange(redirect): + try: + self.log_debug("Redirect #%d to: %s" % (i, url)) + header = self.load(url, just_header=True) + + except Exception: #: Bad bad bad... rewrite this part in 0.4.10 + res = self.load(url, + just_header=True, + req=self.pyload.requestFactory.getRequest(self.__name__)) + + header = {'code': req.code} + for line in res.splitlines(): + line = line.strip() + if not line or ":" not in line: + continue + + key, none, value = line.partition(":") + key = key.lower().strip() + value = value.strip() + + if key in header: + if type(header[key]) is list: + header[key].append(value) + else: + header[key] = [header[key], value] + else: + header[key] = value + + if 'content-disposition' in header: + link = url + + elif header.get('location'): + location = self.fixurl(header['location'], url) + + if header.get('code') == 302: + link = location + + if follow_location: + url = location + continue + + else: + extension = os.path.splitext(parse_name(url))[-1] + + if header.get('content-type'): + mimetype = header['content-type'].split(';')[0].strip() + + elif extension: + mimetype = mimetypes.guess_type(extension, False)[0] or "application/octet-stream" + + else: + mimetype = "" + + if mimetype and (link or 'html' not in mimetype): + link = url + else: + link = "" + + break + + else: + try: + self.log_error(_("Too many redirects")) + + except Exception: + pass + + return link + + + def parse_html_form(self, attr_str="", input_names={}): + return parse_html_form(attr_str, self.html, input_names) + + + def get_password(self): + """ + Get the password the user provided in the package + """ + return self.pyfile.package().password or "" + + + def clean(self): + """ + Clean everything and remove references + """ + super(Base, self).clean() + + for attr in ("account", "html", "pyfile", "thread"): + if hasattr(self, attr): + setattr(self, attr, None) diff --git a/module/plugins/internal/Captcha.py b/module/plugins/internal/Captcha.py index 3d105ed12..a8f48b5e4 100644 --- a/module/plugins/internal/Captcha.py +++ b/module/plugins/internal/Captcha.py @@ -104,8 +104,7 @@ class Captcha(Plugin): self.fail(self.task.error) elif not self.task.result: - self.invalid() - self.plugin.retry(msg=_("No captcha result obtained in appropiate time")) + self.plugin.retry_captcha(msg=_("No captcha result obtained in appropriate time")) result = self.task.result diff --git a/module/plugins/internal/Crypter.py b/module/plugins/internal/Crypter.py index ad5bcc74e..069ffb589 100644 --- a/module/plugins/internal/Crypter.py +++ b/module/plugins/internal/Crypter.py @@ -1,17 +1,18 @@ # -*- coding: utf-8 -*- -from module.plugins.internal.Hoster import Hoster, parse_name +from module.plugins.internal.Base import Base, parse_name from module.utils import save_path as safe_filename -class Crypter(Hoster): +class Crypter(Base): __name__ = "Crypter" __type__ = "crypter" - __version__ = "0.09" + __version__ = "0.10" __status__ = "testing" __pattern__ = r'^unmatchable$' - __config__ = [("use_subfolder", "bool", "Save package to subfolder", True), #: Overrides pyload.config.get("general", "folder_per_package") + __config__ = [("use_premium" , "bool", "Use premium account if available" , True), + ("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides pyload.config.get("general", "folder_per_package") ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] __description__ = """Base decrypter plugin""" @@ -19,11 +20,8 @@ class Crypter(Hoster): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - html = None #: Last html loaded #@TODO: Move to Hoster - - def __init__(self, pyfile): - super(Crypter, self).__init__(pyfile) + super(Base, self).__init__(pyfile) #: Put all packages here. It's a list of tuples like: ( name, [list of links], folder ) self.packages = [] @@ -31,6 +29,16 @@ class Crypter(Hoster): #: List of urls, pyLoad will generate packagenames self.urls = [] + self._setup() + self.init() + + + def _setup(self): + super(Base, self)._setup() + + self.packages = [] + self.urls = [] + def process(self, pyfile): """ @@ -48,6 +56,9 @@ class Crypter(Hoster): def decrypt(self, pyfile): + """ + The "main" method of every crypter plugin, you **have to** overwrite it + """ raise NotImplementedError @@ -77,6 +88,7 @@ class Crypter(Hoster): "Saved to folder: %s" % folder if folder else "Saved to download folder") links = map(self.fixurl, links) + pid = self.pyload.api.addPackage(name, links, package_queue) if package_password: diff --git a/module/plugins/internal/Hoster.py b/module/plugins/internal/Hoster.py index bc340e78f..d1b894c6f 100644 --- a/module/plugins/internal/Hoster.py +++ b/module/plugins/internal/Hoster.py @@ -2,19 +2,10 @@ from __future__ import with_statement -import inspect -import mimetypes import os -import random -import time -import urlparse - -from module.plugins.internal.Captcha import Captcha -from module.plugins.internal.Plugin import (Plugin, Abort, Fail, Reconnect, Retry, Skip, - chunks, decode, encode, exists, fixurl, - parse_html_form, parse_html_tag_attr_value, parse_name, - replace_patterns, seconds_to_midnight, - set_cookie, set_cookies, timestamp) + +from module.plugins.internal.Base import Base, check_abort, create_getInfo, getInfo +from module.plugins.internal.Plugin import Fail, Retry, encode, exists, fixurl, parse_name from module.utils import fs_decode, fs_encode, save_join as fs_join, save_path as safe_filename @@ -24,40 +15,17 @@ def parse_fileInfo(klass, url="", html=""): return encode(info['name']), info['size'], info['status'], info['url'] -#@TODO: Remove in 0.4.10 -def getInfo(urls): - #: result = [ .. (name, size, status, url) .. ] - pass - - -#@TODO: Remove in 0.4.10 -def create_getInfo(klass): - def get_info(urls): - for url in urls: - if hasattr(klass, "URL_REPLACEMENTS"): - url = replace_patterns(url, klass.URL_REPLACEMENTS) - yield parse_fileInfo(klass, url) - - return get_info - - -#@NOTE: `check_abort` decorator -def check_abort(fn): - - def wrapper(self, *args, **kwargs): - self.check_abort() - return fn(self, *args, **kwargs) - - return wrapper - -class Hoster(Plugin): +class Hoster(Base): __name__ = "Hoster" __type__ = "hoster" - __version__ = "0.31" + __version__ = "0.32" __status__ = "testing" __pattern__ = r'^unmatchable$' + __config__ = [("use_premium" , "bool", "Use premium account if available" , True), + ("fallback_premium", "bool", "Fallback to free download if premium fails", True), + ("chk_filesize" , "bool", "Check file size" , True)] __description__ = """Base hoster plugin""" __license__ = "GPLv3" @@ -65,107 +33,39 @@ class Hoster(Plugin): def __init__(self, pyfile): - self._init(pyfile.m.core) - - #: Engage wan reconnection - self.wantReconnect = False #@TODO: Change to `want_reconnect` in 0.4.10 + super(Base, self).__init__(pyfile) #: Enable simultaneous processing of multiple downloads - self.multiDL = True #@TODO: Change to `multi_dl` in 0.4.10 self.limitDL = 0 #@TODO: Change to `limit_dl` in 0.4.10 - #: time.time() + wait in seconds - self.wait_until = 0 - self.waiting = False - - #: Account handler instance, see :py:class:`Account` - self.account = None - self.user = None #@TODO: Remove in 0.4.10 - - #: Associated pyfile instance, see `PyFile` - self.pyfile = pyfile - - self.thread = None #: Holds thread in future - #: Location where the last call to download was saved - self.last_download = "" + self.last_download = None #: Re match of the last call to `checkDownload` self.last_check = None - #: Js engine, see `JsEngine` - self.js = self.pyload.js - - #: Captcha stuff - self.captcha = Captcha(self) - - #: Some plugins store html code here - self.html = None - - #: Dict of the amount of retries already made - self.retries = {} - self.force_free = False #@TODO: Recheck in 0.4.10 + #: Restart flag + self.rst_free = False #@TODO: Recheck in 0.4.10 self._setup() self.init() - def _log(self, level, plugintype, pluginname, messages): - log = getattr(self.pyload.log, level) - msg = u" | ".join(decode(a).strip() for a in messages if a) - log("%(plugintype)s %(pluginname)s[%(id)s]: %(msg)s" - % {'plugintype': plugintype.upper(), - 'pluginname': pluginname, - 'id' : self.pyfile.id, - 'msg' : msg}) - - - @classmethod - def get_info(cls, url="", html=""): - url = fixurl(url, unquote=True) - return {'name' : parse_name(url), - 'size' : 0, - 'status': 3 if url else 8, - 'url' : url} - - - def init(self): - """ - Initialize the plugin (in addition to `__init__`) - """ - pass - - - def setup(self): - """ - Setup for enviroment and other things, called before downloading (possibly more than one time) - """ - pass + def _setup(self): + super(Base, self)._setup() + self.last_download = None + self.last_check = None + self.rst_free = False - def _setup(self): - #@TODO: Remove in 0.4.10 - self.html = "" - self.last_download = "" - self.pyfile.error = "" - try: - self.req.close() - except Exception: - pass - - if self.account: - self.req = self.pyload.requestFactory.getRequest(self.__name__, self.account.user) - self.chunk_limit = -1 #: -1 for unlimited - self.resume_download = True - self.premium = self.account.premium + def load_account(self): + if self.rst_free: + self.account = False + self.user = None #@TODO: Remove in 0.4.10 else: - self.req = self.pyload.requestFactory.getRequest(self.__name__) - self.chunk_limit = 1 - self.resume_download = False - self.premium = False - - return self.setup() + super(Base, self).load_account() + # self.rst_free = False def _process(self, thread): @@ -174,229 +74,44 @@ class Hoster(Plugin): """ self.thread = thread - if self.force_free: - self.account = False - else: - self.load_account() #@TODO: Move to PluginThread in 0.4.10 - self.force_free = False - self._setup() # self.pyload.hookManager.downloadPreparing(self.pyfile) #@TODO: Recheck in 0.4.10 - self.pyfile.setStatus("starting") - self.check_abort() - self.log_debug("PROCESS URL " + self.pyfile.url, "PLUGIN VERSION %s" % self.__version__) - return self.process(self.pyfile) - - - #: Deprecated method, use `_process` instead (Remove in 0.4.10) - def preprocessing(self, *args, **kwargs): - return self._process(*args, **kwargs) - - - def load_account(self): - if not self.account: - self.account = self.pyload.accountManager.getAccountPlugin(self.__name__) - - if not self.account: - self.account = False - self.user = None #@TODO: Remove in 0.4.10 - - else: - self.account.choose() - self.user = self.account.user #@TODO: Remove in 0.4.10 - if self.account.user is None: - self.account = False - - - def process(self, pyfile): - """ - The 'main' method of every plugin, you **have to** overwrite it - """ - raise NotImplementedError - - - def set_reconnect(self, reconnect): - self.log_debug("RECONNECT %s required" % ("" if reconnect else "not"), - "Previous wantReconnect: %s" % self.wantReconnect) - self.wantReconnect = bool(reconnect) - - - def set_wait(self, seconds, reconnect=None): - """ - Set a specific wait time later used with `wait` - - :param seconds: wait time in seconds - :param reconnect: True if a reconnect would avoid wait time - """ - wait_time = max(int(seconds), 1) - wait_until = time.time() + wait_time + 1 - - self.log_debug("WAIT set to %d seconds" % wait_time, - "Previous waitUntil: %f" % self.pyfile.waitUntil) - - self.pyfile.waitUntil = wait_until - - if reconnect is not None: - self.set_reconnect(reconnect) - - - def wait(self, seconds=None, reconnect=None): - """ - Waits the time previously set - """ - pyfile = self.pyfile - - if seconds is not None: - self.set_wait(seconds) - - if reconnect is not None: - self.set_reconnect(reconnect) - - self.waiting = True - - status = pyfile.status #@NOTE: Recheck in 0.4.10 - pyfile.setStatus("waiting") - - self.log_info(_("Waiting %d seconds...") % pyfile.waitUntil - time.time()) - - if self.wantReconnect: - self.log_info(_("Requiring reconnection...")) - if self.account: - self.log_warning("Ignore reconnection due logged account") - - if not self.wantReconnect or self.account: - while pyfile.waitUntil > time.time(): - self.check_abort() - time.sleep(2) - - else: - while pyfile.waitUntil > time.time(): - self.check_abort() - self.thread.m.reconnecting.wait(1) - - if self.thread.m.reconnecting.isSet(): - self.waiting = False - self.wantReconnect = False - raise Reconnect - - time.sleep(2) - - self.waiting = False - pyfile.status = status #@NOTE: Recheck in 0.4.10 - - - def skip(self, msg=""): - """ - Skip and give msg - """ - raise Skip(encode(msg or self.pyfile.error or self.pyfile.pluginname)) #@TODO: Remove `encode` in 0.4.10 - - - #@TODO: Remove in 0.4.10 - def fail(self, msg): - """ - Fail and give msg - """ - msg = msg.strip() - - if msg: - self.pyfile.error = msg - else: - msg = self.pyfile.error or (self.info['error'] if 'error' in self.info else self.pyfile.getStatusName()) - - raise Fail(encode(msg)) #@TODO: Remove `encode` in 0.4.10 - - - def error(self, msg="", type=_("Parse")): - type = _("%s error") % type.strip().capitalize() if type else _("Unknown") - msg = _("%(type)s: %(msg)s | Plugin may be out of date" - % {'type': type, 'msg': msg or self.pyfile.error}) - - self.fail(msg) - - - def abort(self, msg=""): - """ - Abort and give msg - """ - if msg: #@TODO: Remove in 0.4.10 - self.pyfile.error = encode(msg) - - raise Abort - - - #@TODO: Recheck in 0.4.10 - def offline(self, msg=""): - """ - Fail and indicate file is offline - """ - self.fail("offline") - - - #@TODO: Recheck in 0.4.10 - def temp_offline(self, msg=""): - """ - Fail and indicates file ist temporary offline, the core may take consequences - """ - self.fail("temp. offline") - + self.pyfile.setStatus("starting") - def retry(self, attemps=5, delay=1, msg=""): - """ - Retries and begin again from the beginning + try: + self.log_debug("PROCESS URL " + self.pyfile.url, "PLUGIN VERSION %s" % self.__version__) #@TODO: Remove in 0.4.10 + self.process(self.pyfile) - :param attemps: number of maximum retries - :param delay: time to wait in seconds - :param msg: msg for retrying, will be passed to fail if attemps value was reached - """ - id = inspect.currentframe().f_back.f_lineno - if id not in self.retries: - self.retries[id] = 0 + self.check_abort() - if 0 < attemps <= self.retries[id]: - self.fail(msg or _("Max retries reached")) + self.log_debug("CHECK DOWNLOAD") #@TODO: Recheck in 0.4.10 + self._check_download() - self.wait(delay, False) + except Fail, e: #@TODO: Move to PluginThread in 0.4.10 + if self.get_config('fallback_premium', True) and self.premium: + self.log_warning(_("Premium download failed"), e) + self.restart() - self.retries[id] += 1 - raise Retry(encode(msg)) #@TODO: Remove `encode` in 0.4.10 + else: + raise Fail(e) - def restart(self, msg=None, nopremium=False): + def restart(self, msg="", premium=False): if not msg: - msg = _("Fallback to free download") if nopremium else _("Restart") + msg = _("Simple restart") if premium else _("Fallback to free download") - if nopremium: + if not premium: if self.premium: - self.force_free = True + self.rst_free = True else: self.fail("%s | %s" % (msg, _("Download was already free"))) raise Retry(encode(msg)) #@TODO: Remove `encode` in 0.4.10 - def fixurl(self, url, baseurl=None, unquote=None): - url = fixurl(url) - - if not baseurl: - baseurl = fixurl(self.pyfile.url) - - if not urlparse.urlparse(url).scheme: - url_p = urlparse.urlparse(baseurl) - baseurl = "%s://%s" % (url_p.scheme, url_p.netloc) - url = urlparse.urljoin(baseurl, url) - - return fixurl(url, unquote) - - - @check_abort - def load(self, *args, **kwargs): - return super(Hoster, self).load(*args, **kwargs) - - @check_abort def download(self, url, get={}, post={}, ref=True, cookies=True, disposition=True): """ @@ -415,7 +130,7 @@ class Hoster(Plugin): self.log_debug("DOWNLOAD URL " + url, *["%s=%s" % (key, val) for key, val in locals().items() if key not in ("self", "url", "_[1]")]) - url = self.fixurl(url, unquote=True) + url = self.fixurl(url) self.pyfile.name = parse_name(self.pyfile.name) #: Safe check @@ -475,27 +190,7 @@ class Hoster(Plugin): self.last_download = filename - return self.last_download - - - def check_abort(self): - if not self.pyfile.abort: - return - - if self.pyfile.status is 8: - self.fail() - - elif self.pyfile.status is 4: - self.skip(self.pyfile.statusname) - - elif self.pyfile.status is 1: - self.offline() - - elif self.pyfile.status is 6: - self.temp_offline() - - else: - self.abort() + return filename def check_filesize(self, file_size, size_tolerance=1024): @@ -537,7 +232,7 @@ class Hoster(Plugin): :return: dictionary key of the first rule that matched """ do_delete = False - last_download = fs_encode(self.last_download) + last_download = fs_encode(self.last_download) #@TODO: Recheck in 0.4.10 if not self.last_download or not exists(last_download): self.fail(self.pyfile.error or _("No file downloaded")) @@ -558,7 +253,7 @@ class Hoster(Plugin): elif hasattr(rule, "search"): m = rule.search(content) - if m: + if m is not None: do_delete = True self.last_check = m return name @@ -575,11 +270,25 @@ class Hoster(Plugin): self.last_download = "" #: Recheck in 0.4.10 + def _check_download(self): + if self.captcha.task and not self.last_download: + self.retry_captcha() + + elif self.check_file({'Empty file': re.compile(r'\A((.|)(\2|\s)*)\Z')}, + delete=True): + self.error(_("Empty file")) + + elif self.get_config('chk_filesize', False) and self.info.get('size'): + # 10485760 is 10MB, tolerance is used when comparing displayed size on the hoster website to real size + # For example displayed size can be 1.46GB for example, but real size can be 1.4649853GB + self.check_filesize(self.info['size'], size_tolerance=10485760) + + def check_traffic(self): if not self.account: return True - traffic = self.account.get_data(refresh=True)['trafficleft'] + traffic = self.account.get_data('trafficleft') if traffic is None: return False @@ -632,96 +341,3 @@ class Hoster(Plugin): def checkForSameFiles(self, *args, **kwargs): if self.pyload.config.get("download", "skip_existing"): return self.check_filedupe() - - - def direct_link(self, url, follow_location=None): - link = "" - - if follow_location is None: - redirect = 1 - - elif type(follow_location) is int: - redirect = max(follow_location, 1) - - else: - redirect = self.get_config("maxredirs", 10, "UserAgentSwitcher") - - for i in xrange(redirect): - try: - self.log_debug("Redirect #%d to: %s" % (i, url)) - header = self.load(url, just_header=True) - - except Exception: #: Bad bad bad... rewrite this part in 0.4.10 - res = self.load(url, - just_header=True, - req=self.pyload.requestFactory.getRequest(self.__name__)) - - header = {'code': req.code} - for line in res.splitlines(): - line = line.strip() - if not line or ":" not in line: - continue - - key, none, value = line.partition(":") - key = key.lower().strip() - value = value.strip() - - if key in header: - if type(header[key]) is list: - header[key].append(value) - else: - header[key] = [header[key], value] - else: - header[key] = value - - if 'content-disposition' in header: - link = url - - elif header.get('location'): - location = self.fixurl(header['location'], url) - - if header.get('code') == 302: - link = location - - if follow_location: - url = location - continue - - else: - extension = os.path.splitext(parse_name(url))[-1] - - if header.get('content-type'): - mimetype = header['content-type'].split(';')[0].strip() - - elif extension: - mimetype = mimetypes.guess_type(extension, False)[0] or "application/octet-stream" - - else: - mimetype = "" - - if mimetype and (link or 'html' not in mimetype): - link = url - else: - link = "" - - break - - else: - try: - self.log_error(_("Too many redirects")) - - except Exception: - pass - - return link - - - def parse_html_form(self, attr_str="", input_names={}): - return parse_html_form(attr_str, self.html, input_names) - - - def get_password(self): - """ - Get the password the user provided in the package - """ - return self.pyfile.package().password or "" diff --git a/module/plugins/internal/MultiCrypter.py b/module/plugins/internal/MultiCrypter.py index ae8785116..9d4ac3ab9 100644 --- a/module/plugins/internal/MultiCrypter.py +++ b/module/plugins/internal/MultiCrypter.py @@ -10,8 +10,9 @@ class MultiCrypter(SimpleCrypter): __status__ = "testing" __pattern__ = r'^unmatchable$' - __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), - ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] + __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)] __description__ = """Multi decrypter plugin""" __license__ = "GPLv3" diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py index fbfab1ade..d7d3c5ccd 100644 --- a/module/plugins/internal/MultiHoster.py +++ b/module/plugins/internal/MultiHoster.py @@ -9,12 +9,14 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, r class MultiHoster(SimpleHoster): __name__ = "MultiHoster" __type__ = "hoster" - __version__ = "0.51" + __version__ = "0.52" __status__ = "testing" __pattern__ = r'^unmatchable$' - __config__ = [("use_premium" , "bool", "Use premium account if available" , True), - ("revertfailed", "bool", "Revert to standard download if fails", True)] + __config__ = [("use_premium" , "bool", "Use premium account if available" , True), + ("fallback_premium", "bool", "Fallback to free download if premium fails", True), + ("chk_filesize" , "bool", "Check file size" , True), + ("revertfailed" , "bool", "Revert to standard download if fails" , True)] __description__ = """Multi hoster plugin""" __license__ = "GPLv3" @@ -100,7 +102,7 @@ class MultiHoster(SimpleHoster): except Fail, e: #@TODO: Move to PluginThread in 0.4.10 if self.premium: self.log_warning(_("Premium download failed")) - self.restart(nopremium=True) + self.restart() elif self.get_config("revertfailed", True) \ and "new_module" in self.pyload.pluginManager.hosterPlugins[self.__name__]: @@ -116,7 +118,7 @@ class MultiHoster(SimpleHoster): hdict['new_module'] = tmp_module hdict['new_name'] = tmp_name - self.restart(_("Revert to original hoster plugin")) + self.restart(_("Revert to original hoster plugin"), premium=True) else: raise Fail(encode(e)) #@TODO: Remove `encode` in 0.4.10 diff --git a/module/plugins/internal/Plugin.py b/module/plugins/internal/Plugin.py index 6f3e52962..dbf6775cb 100644 --- a/module/plugins/internal/Plugin.py +++ b/module/plugins/internal/Plugin.py @@ -45,7 +45,7 @@ def encode(string, encoding='utf8'): def exists(path): if os.path.exists(path): if os.name == "nt": - dir, name = os.path.split(path) + dir, name = os.path.split(path.rstrip(os.sep)) return name in os.listdir(dir) else: return True @@ -77,11 +77,6 @@ def parse_name(string): #@TODO: Move to utils in 0.4.10 -def timestamp(): - return int(time.time() * 1000) - - -#@TODO: Move to utils in 0.4.10 def which(program): """ Works exactly like the unix command which @@ -184,7 +179,7 @@ def chunks(iterable, size): class Plugin(object): __name__ = "Plugin" __type__ = "plugin" - __version__ = "0.38" + __version__ = "0.40" __status__ = "testing" __pattern__ = r'^unmatchable$' @@ -206,9 +201,10 @@ class Plugin(object): def _init(self, core): - self.pyload = core - self.info = {} #: Provide information in dict here - self.req = None #: Browser instance, see `network.Browser` + self.pyload = core + self.info = {} #: Provide information in dict here + self.req = None #: Browser instance, see `network.Browser` + self.last_html = None def init(self): @@ -355,7 +351,7 @@ class Plugin(object): self.log_debug("LOAD URL " + url, *["%s=%s" % (key, val) for key, val in locals().items() if key not in ("self", "url", "_[1]")]) - url = fixurl(url, unquote=True) #: Recheck in 0.4.10 + url = fixurl(url) #: Recheck in 0.4.10 if req is None: req = self.req or self.pyload.requestFactory.getRequest(self.__name__) @@ -364,15 +360,17 @@ class Plugin(object): if isinstance(cookies, list): set_cookies(req.cj, cookies) - res = req.load(url, get, post, ref, bool(cookies), just_header, multipart, decode is True) #@TODO: Fix network multipart in 0.4.10 + html = req.load(url, get, post, ref, bool(cookies), just_header, multipart, decode is True) #@TODO: Fix network multipart in 0.4.10 #@TODO: Move to network in 0.4.10 if decode: - res = html_unescape(res) + html = html_unescape(html) #@TODO: Move to network in 0.4.10 if isinstance(decode, basestring): - res = _decode(res, decode) #@NOTE: Use `utils.decode()` in 0.4.10 + html = _decode(html, decode) #@NOTE: Use `utils.decode()` in 0.4.10 + + self.last_html = html if self.pyload.debug: frame = inspect.currentframe() @@ -383,15 +381,18 @@ class Plugin(object): with open(framefile, "wb") as f: del frame #: Delete the frame or it wont be cleaned - f.write(encode(res)) + f.write(encode(html)) except IOError, e: self.log_error(e) - if just_header: - #: Parse header + if not just_header: + return html + + else: + #@TODO: Move to network in 0.4.10 header = {'code': req.code} - for line in res.splitlines(): + for line in html.splitlines(): line = line.strip() if not line or ":" not in line: continue @@ -407,14 +408,13 @@ class Plugin(object): header[key] = [header[key], value] else: header[key] = value - res = header - return res + return header def clean(self): """ - Clean everything and remove references + Remove references """ try: self.req.clearCookies() @@ -423,6 +423,5 @@ class Plugin(object): except Exception: pass - for attr in ("account", "html", "pyfile", "req", "thread"): - if hasattr(self, attr): - setattr(self, attr, None) + else: + self.req = None diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index 53d69b2a5..d4ae85ebe 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -13,8 +13,9 @@ class SimpleCrypter(Crypter, SimpleHoster): __status__ = "testing" __pattern__ = r'^unmatchable$' - __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), - ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] + __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)] __description__ = """Simple decrypter plugin""" __license__ = "GPLv3" diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index 3bb3ff211..8ba227c92 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -16,12 +16,12 @@ from module.utils import fixup, fs_encode, parseFileSize as parse_size class SimpleHoster(Hoster): __name__ = "SimpleHoster" __type__ = "hoster" - __version__ = "1.88" + __version__ = "1.89" __status__ = "testing" __pattern__ = r'^unmatchable$' __config__ = [("use_premium" , "bool", "Use premium account if available" , True), - ("premium_fallback", "bool", "Fallback to free download if premium fails", True), + ("fallback_premium", "bool", "Fallback to free download if premium fails", True), ("chk_filesize" , "bool", "Check file size" , True)] __description__ = """Simple hoster plugin""" @@ -200,9 +200,6 @@ class SimpleHoster(Hoster): self.direct_dl = False self.leech_dl = False - if not self.get_config('use_premium', True) and self.premium: - self.restart(nopremium=True) - if self.LOGIN_PREMIUM and not self.premium: self.fail(_("Required premium account not found")) @@ -243,94 +240,70 @@ class SimpleHoster(Hoster): def process(self, pyfile): - try: - self.prepare() - self.check_info() #@TODO: Remove in 0.4.10 - - if self.leech_dl: - self.log_info(_("Processing as debrid download...")) - self.handle_multi(pyfile) + self.prepare() + self.check_info() #@TODO: Remove in 0.4.10 - if not self.link and not was_downloaded(): - self.log_info(_("Failed to leech url")) - - else: - if not self.link and self.direct_dl and not self.last_download: - self.log_info(_("Looking for direct download link...")) - self.handle_direct(pyfile) + if self.leech_dl: + self.log_info(_("Processing as debrid download...")) + self.handle_multi(pyfile) - if self.link or self.last_download: - self.log_info(_("Direct download link detected")) - else: - self.log_info(_("Direct download link not found")) + if not self.link and not was_downloaded(): + self.log_info(_("Failed to leech url")) - if not self.link and not self.last_download: - self.preload() + else: + if not self.link and self.direct_dl and not self.last_download: + self.log_info(_("Looking for direct download link...")) + self.handle_direct(pyfile) - if 'status' not in self.info or self.info['status'] is 3: #@TODO: Recheck in 0.4.10 - self.check_info() + if self.link or self.last_download: + self.log_info(_("Direct download link detected")) + else: + self.log_info(_("Direct download link not found")) - if self.premium and (not self.CHECK_TRAFFIC or self.check_traffic()): - self.log_info(_("Processing as premium download...")) - self.handle_premium(pyfile) + if not self.link and not self.last_download: + self.preload() - elif not self.LOGIN_ACCOUNT or (not self.CHECK_TRAFFIC or self.check_traffic()): - self.log_info(_("Processing as free download...")) - self.handle_free(pyfile) + if 'status' not in self.info or self.info['status'] is 3: #@TODO: Recheck in 0.4.10 + self.check_info() - if not self.last_download: - self.log_info(_("Downloading file...")) - self.download(self.link, disposition=self.DISPOSITION) + if self.premium and (not self.CHECK_TRAFFIC or self.check_traffic()): + self.log_info(_("Processing as premium download...")) + self.handle_premium(pyfile) - self.check_download() + elif not self.LOGIN_ACCOUNT or (not self.CHECK_TRAFFIC or self.check_traffic()): + self.log_info(_("Processing as free download...")) + self.handle_free(pyfile) - except Fail, e: #@TODO: Move to PluginThread in 0.4.10 - if self.get_config('premium_fallback', True) and self.premium: - self.log_warning(_("Premium download failed"), e) - self.restart(nopremium=True) + if not self.last_download: + self.log_info(_("Downloading file...")) + self.download(self.link, disposition=self.DISPOSITION) - else: - raise Fail(encode(e)) #@TODO: Remove `encode` in 0.4.10 + self.check_download() def check_download(self): self.log_info(_("Checking downloaded file...")) + self.log_debug("Using default check rules...") + for r, p in self.FILE_ERRORS: + errmsg = self.check_file({r: re.compile(p)}) + if errmsg is not None: + errmsg = errmsg.strip().capitalize() - if self.captcha.task and not self.last_download: - self.captcha.invalid() - self.retry(10, msg=_("Wrong captcha")) + try: + errmsg += " | " + self.last_check.group(1).strip() - elif self.check_file({'Empty file': re.compile(r'\A((.|)(\2|\s)*)\Z')}, - delete=True): - self.error(_("Empty file")) + except Exception: + pass + self.log_warning(_("Check result: ") + errmsg, _("Waiting 1 minute and retry")) + self.wantReconnect = True + self.retry(wait=60, msg=errmsg) else: - if self.get_config('chk_filesize', False) and self.info.get('size'): - # 10485760 is 10MB, tolerance is used when comparing displayed size on the hoster website to real size - # For example displayed size can be 1.46GB for example, but real size can be 1.4649853GB - self.check_filesize(self.info['size'], size_tolerance=10485760) - - self.log_debug("Using default check rules...") - for r, p in self.FILE_ERRORS: - errmsg = self.check_file({r: re.compile(p)}) - if errmsg is not None: - errmsg = errmsg.strip().capitalize() - - try: - errmsg += " | " + self.last_check.group(1).strip() - - except Exception: - pass - - self.log_warning(_("Check result: ") + errmsg, _("Waiting 1 minute and retry")) - self.wantReconnect = True - self.retry(delay=60, msg=errmsg) - else: - if self.CHECK_FILE: - self.log_debug("Using custom check rules...") - with open(fs_encode(self.last_download), "rb") as f: - self.html = f.read(1048576) #@TODO: Recheck in 0.4.10 - self.check_errors() + if self.CHECK_FILE: + self.log_debug("Using custom check rules...") + with open(fs_encode(self.last_download), "rb") as f: + self.html = f.read(1048576) #@TODO: Recheck in 0.4.10 + self.check_errors() self.log_info(_("No errors found")) @@ -375,7 +348,7 @@ class SimpleHoster(Hoster): if hasattr(self, 'ERROR_PATTERN'): m = re.search(self.ERROR_PATTERN, self.html) - if m: + if m is not None: try: errmsg = m.group(1).strip() @@ -399,8 +372,7 @@ class SimpleHoster(Hoster): self.fail(_("Connection from your current IP address is not allowed")) elif re.search('captcha|code', errmsg, re.I): - self.captcha.invalid() - self.retry(10, msg=_("Wrong captcha")) + self.retry_captcha() elif re.search('countdown|expired', errmsg, re.I): self.retry(10, 60, _("Link expired")) @@ -415,18 +387,18 @@ class SimpleHoster(Hoster): self.offline() elif re.search('filename', errmsg, re.I): - self.fail(_("Wrong url")) + self.fail(_("Invalid url")) elif re.search('premium', errmsg, re.I): self.fail(_("File can be downloaded by premium users only")) else: self.wantReconnect = True - self.retry(delay=60, msg=errmsg) + self.retry(wait=60, msg=errmsg) elif hasattr(self, 'WAIT_PATTERN'): m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: try: waitmsg = m.group(1).strip() diff --git a/module/plugins/internal/XFSAccount.py b/module/plugins/internal/XFSAccount.py index 91136a2a0..7b9410222 100644 --- a/module/plugins/internal/XFSAccount.py +++ b/module/plugins/internal/XFSAccount.py @@ -13,7 +13,7 @@ from module.plugins.internal.Plugin import parse_html_form, set_cookie class XFSAccount(Account): __name__ = "XFSAccount" __type__ = "account" - __version__ = "0.48" + __version__ = "0.49" __status__ = "testing" __description__ = """XFileSharing account plugin""" @@ -42,6 +42,16 @@ class XFSAccount(Account): LOGIN_SKIP_PATTERN = r'op=logout' + def set_xfs_cookie(self): + if not self.COOKIES: + return + + if isinstance(self.COOKIES, list) and (self.PLUGIN_DOMAIN, "lang", "english") not in self.COOKIES: + self.COOKIES.insert((self.PLUGIN_DOMAIN, "lang", "english")) + else: + set_cookie(self.req.cj, self.PLUGIN_DOMAIN, "lang", "english") + + def grab_info(self, user, password, data): validuntil = None trafficleft = None @@ -61,7 +71,7 @@ class XFSAccount(Account): premium = True if re.search(self.PREMIUM_PATTERN, html) else False m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: + if m is not None: expiredate = m.group(1).strip() self.log_debug("Expire date: " + expiredate) @@ -84,7 +94,7 @@ class XFSAccount(Account): self.log_debug("VALID_UNTIL_PATTERN not found") m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: + if m is not None: try: traffic = m.groupdict() size = traffic['S'] @@ -146,11 +156,7 @@ class XFSAccount(Account): if not self.PLUGIN_URL: self.PLUGIN_URL = "http://www.%s/" % self.PLUGIN_DOMAIN - if self.COOKIES: - if isinstance(self.COOKIES, list) and (self.PLUGIN_DOMAIN, "lang", "english") not in self.COOKIES: - self.COOKIES.insert((self.PLUGIN_DOMAIN, "lang", "english")) - else: - set_cookie(self.req.cj, self.PLUGIN_DOMAIN, "lang", "english") + self.set_xfs_cookie() if not self.PLUGIN_URL: self.fail_login(_("Missing PLUGIN_URL")) diff --git a/module/plugins/internal/XFSCrypter.py b/module/plugins/internal/XFSCrypter.py index 8047fd03e..69565e22c 100644 --- a/module/plugins/internal/XFSCrypter.py +++ b/module/plugins/internal/XFSCrypter.py @@ -7,10 +7,13 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo class XFSCrypter(SimpleCrypter): __name__ = "XFSCrypter" __type__ = "crypter" - __version__ = "0.15" + __version__ = "0.16" __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)] __description__ = """XFileSharing decrypter plugin""" __license__ = "GPLv3" @@ -27,6 +30,15 @@ class XFSCrypter(SimpleCrypter): OFFLINE_PATTERN = r'>\s*(No such user|\w+ (Not Found|file (was|has been) removed|no longer available)' TEMP_OFFLINE_PATTERN = r'>\s*\w+ server (is in )?(maintenance|maintainance)' + def set_xfs_cookie(self): + if not self.COOKIES: + return + + if isinstance(self.COOKIES, list) and (self.PLUGIN_DOMAIN, "lang", "english") not in self.COOKIES: + self.COOKIES.insert((self.PLUGIN_DOMAIN, "lang", "english")) + else: + set_cookie(self.req.cj, self.PLUGIN_DOMAIN, "lang", "english") + def prepare(self): if not self.PLUGIN_DOMAIN: @@ -41,10 +53,6 @@ class XFSCrypter(SimpleCrypter): else: self.fail(_("Missing PLUGIN_DOMAIN")) - if self.COOKIES: - if isinstance(self.COOKIES, list) and (self.PLUGIN_DOMAIN, "lang", "english") not in self.COOKIES: - self.COOKIES.insert((self.PLUGIN_DOMAIN, "lang", "english")) - else: - set_cookie(self.req.cj, self.PLUGIN_DOMAIN, "lang", "english") + self.set_xfs_cookie() return super(XFSCrypter, self).prepare() diff --git a/module/plugins/internal/XFSHoster.py b/module/plugins/internal/XFSHoster.py index 346422ff7..dcb85d23b 100644 --- a/module/plugins/internal/XFSHoster.py +++ b/module/plugins/internal/XFSHoster.py @@ -18,6 +18,9 @@ class XFSHoster(SimpleHoster): __status__ = "testing" __pattern__ = r'^unmatchable$' + __config__ = [("use_premium" , "bool", "Use premium account if available" , True), + ("fallback_premium", "bool", "Fallback to free download if premium fails", True), + ("chk_filesize" , "bool", "Check file size" , True)] __description__ = """XFileSharing hoster plugin""" __license__ = "GPLv3" @@ -57,6 +60,16 @@ class XFSHoster(SimpleHoster): self.resume_download = self.multiDL = self.premium + def set_xfs_cookie(self): + if not self.COOKIES: + return + + if isinstance(self.COOKIES, list) and (self.PLUGIN_DOMAIN, "lang", "english") not in self.COOKIES: + self.COOKIES.insert((self.PLUGIN_DOMAIN, "lang", "english")) + else: + set_cookie(self.req.cj, self.PLUGIN_DOMAIN, "lang", "english") + + def prepare(self): """ Initialize important variables @@ -72,11 +85,7 @@ class XFSHoster(SimpleHoster): else: self.fail(_("Missing PLUGIN_DOMAIN")) - if self.COOKIES: - if isinstance(self.COOKIES, list) and (self.PLUGIN_DOMAIN, "lang", "english") not in self.COOKIES: - self.COOKIES.insert((self.PLUGIN_DOMAIN, "lang", "english")) - else: - set_cookie(self.req.cj, self.PLUGIN_DOMAIN, "lang", "english") + self.set_xfs_cookie() if not self.LINK_PATTERN: pattern = r'(?:file: "(.+?)"|(https?://(?:www\.)?([^/]*?%s|\d+\.\d+\.\d+\.\d+)(\:\d+)?(/d/|(/files)?/\d+/\w+/).+?)["\'<])' @@ -95,7 +104,7 @@ class XFSHoster(SimpleHoster): self.check_errors() m = re.search(self.LINK_PATTERN, self.html, re.S) - if m: + if m is not None: break data = self.get_post_parameters() @@ -111,7 +120,7 @@ class XFSHoster(SimpleHoster): break m = re.search(self.LINK_PATTERN, self.html, re.S) - if m: + if m is not None: break else: if 'op' in data: @@ -163,7 +172,7 @@ class XFSHoster(SimpleHoster): self.retry(20, 3 * 60, _("Can not leech file")) elif 'today' in stmsg: - self.retry(delay=seconds_to_midnight(), msg=_("You've used all Leech traffic today")) + self.retry(wait=seconds_to_midnight(), msg=_("You've used all Leech traffic today")) else: self.fail(stmsg) @@ -202,7 +211,7 @@ class XFSHoster(SimpleHoster): if not self.premium: m = re.search(self.WAIT_PATTERN, self.html) - if m: + if m is not None: wait_time = int(m.group(1)) self.set_wait(wait_time, False) @@ -223,13 +232,13 @@ class XFSHoster(SimpleHoster): def handle_captcha(self, inputs): m = re.search(self.CAPTCHA_PATTERN, self.html) - if m: + if m is not None: captcha_url = m.group(1) inputs['code'] = self.captcha.decrypt(captcha_url) return m = re.search(self.CAPTCHA_BLOCK_PATTERN, self.html, re.S) - if m: + if m is not None: captcha_div = m.group(1) numerals = re.findall(r'<span.*?padding-left\s*:\s*(\d+).*?>(\d)</span>', html_unescape(captcha_div)) |