diff options
Diffstat (limited to 'module/plugins')
142 files changed, 1354 insertions, 1349 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..0d1bb7bcb 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() 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 771966389..dbf6775cb 100644 --- a/module/plugins/internal/Plugin.py +++ b/module/plugins/internal/Plugin.py @@ -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 8af6b83ed..ce87642f0 100644 --- a/module/plugins/internal/XFSHoster.py +++ b/module/plugins/internal/XFSHoster.py @@ -14,10 +14,13 @@ from module.utils import html_unescape  class XFSHoster(SimpleHoster):      __name__    = "XFSHoster"      __type__    = "hoster" -    __version__ = "0.61" +    __version__ = "0.62"      __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))  | 
