diff options
135 files changed, 1077 insertions, 833 deletions
diff --git a/module/plugins/accounts/AlldebridCom.py b/module/plugins/accounts/AlldebridCom.py index 6a2f09c9c..845c1b835 100644 --- a/module/plugins/accounts/AlldebridCom.py +++ b/module/plugins/accounts/AlldebridCom.py @@ -12,7 +12,7 @@ from module.plugins.internal.Account import Account  class AlldebridCom(Account):      __name__    = "AlldebridCom"      __type__    = "account" -    __version__ = "0.26" +    __version__ = "0.27"      __status__  = "testing"      __description__ = """AllDebrid.com account plugin""" @@ -20,7 +20,7 @@ class AlldebridCom(Account):      __authors__     = [("Andy Voigt", "spamsales@online.de")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          data = self.get_data(user)          html = self.load("http://www.alldebrid.com/account/")          soup = BeautifulSoup.BeautifulSoup(html) @@ -63,4 +63,4 @@ class AlldebridCom(Account):          if "This login doesn't exist" in html \             or "The password is not valid" in html \             or "Invalid captcha" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/BitshareCom.py b/module/plugins/accounts/BitshareCom.py index 280f008b2..16eeb02b2 100644 --- a/module/plugins/accounts/BitshareCom.py +++ b/module/plugins/accounts/BitshareCom.py @@ -6,7 +6,7 @@ from module.plugins.internal.Account import Account  class BitshareCom(Account):      __name__    = "BitshareCom"      __type__    = "account" -    __version__ = "0.15" +    __version__ = "0.16"      __status__  = "testing"      __description__ = """Bitshare account plugin""" @@ -14,7 +14,7 @@ class BitshareCom(Account):      __authors__     = [("Paul King", None)] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://bitshare.com/mysettings.html")          if "\"http://bitshare.com/myupgrade.html\">Free" in html: @@ -33,4 +33,4 @@ class BitshareCom(Account):                                 'submit'  : "Login"})          if "login" in req.lastEffectiveURL: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/CatShareNet.py b/module/plugins/accounts/CatShareNet.py index 92f1cb27e..a8a164352 100644 --- a/module/plugins/accounts/CatShareNet.py +++ b/module/plugins/accounts/CatShareNet.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class CatShareNet(Account):      __name__    = "CatShareNet"      __type__    = "account" -    __version__ = "0.08" +    __version__ = "0.09"      __status__  = "testing"      __description__ = """Catshare.net account plugin""" @@ -22,7 +22,7 @@ class CatShareNet(Account):      TRAFFIC_LEFT_PATTERN = r'<a href="/premium">([0-9.]+ [kMG]B)' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium     = False          validuntil  = -1          trafficleft = -1 @@ -58,4 +58,4 @@ class CatShareNet(Account):                                 'user[submit]'  : "Login"})          if not '<a href="/logout">Wyloguj</a>' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/CloudzillaTo.py b/module/plugins/accounts/CloudzillaTo.py index 0d473eb7d..127e226a2 100644 --- a/module/plugins/accounts/CloudzillaTo.py +++ b/module/plugins/accounts/CloudzillaTo.py @@ -8,7 +8,7 @@ from module.plugins.internal.Account import Account  class CloudzillaTo(Account):      __name__    = "CloudzillaTo"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = """Cloudzilla.to account plugin""" @@ -19,7 +19,7 @@ class CloudzillaTo(Account):      PREMIUM_PATTERN = r'<h2>account type</h2>\s*Premium Account' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://www.cloudzilla.to/")          premium = True if re.search(self.PREMIUM_PATTERN, html) else False @@ -34,4 +34,4 @@ class CloudzillaTo(Account):                                 'w'        : "dologin"})          if "ERROR" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/CzshareCom.py b/module/plugins/accounts/CzshareCom.py index e9a34cb83..77d1073ca 100644 --- a/module/plugins/accounts/CzshareCom.py +++ b/module/plugins/accounts/CzshareCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class CzshareCom(Account):      __name__    = "CzshareCom"      __type__    = "account" -    __version__ = "0.20" +    __version__ = "0.21"      __status__  = "testing"      __description__ = """Czshare.com account plugin, now Sdilej.cz""" @@ -21,7 +21,7 @@ class CzshareCom(Account):      CREDIT_LEFT_PATTERN = r'<tr class="active">\s*<td>([\d ,]+) (KiB|MiB|GiB)</td>\s*<td>([^<]*)</td>\s*</tr>' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium     = False          validuntil  = None          trafficleft = None @@ -51,4 +51,4 @@ class CzshareCom(Account):                                 "login-name"    : user})          if '<div class="login' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/DebridItaliaCom.py b/module/plugins/accounts/DebridItaliaCom.py index 9c0956668..35fd6262e 100644 --- a/module/plugins/accounts/DebridItaliaCom.py +++ b/module/plugins/accounts/DebridItaliaCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class DebridItaliaCom(Account):      __name__    = "DebridItaliaCom"      __type__    = "account" -    __version__ = "0.15" +    __version__ = "0.16"      __status__  = "testing"      __description__ = """Debriditalia.com account plugin""" @@ -21,7 +21,7 @@ class DebridItaliaCom(Account):      WALID_UNTIL_PATTERN = r'Premium valid till: (.+?) \|' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          info = {'premium': False, 'validuntil': None, 'trafficleft': None}          html = self.load("http://debriditalia.com/") @@ -42,4 +42,4 @@ class DebridItaliaCom(Account):                                'p': password})          if 'NO' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/DepositfilesCom.py b/module/plugins/accounts/DepositfilesCom.py index 848529bc3..6e4bf9a1b 100644 --- a/module/plugins/accounts/DepositfilesCom.py +++ b/module/plugins/accounts/DepositfilesCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class DepositfilesCom(Account):      __name__    = "DepositfilesCom"      __type__    = "account" -    __version__ = "0.34" +    __version__ = "0.35"      __status__  = "testing"      __description__ = """Depositfiles.com account plugin""" @@ -19,7 +19,7 @@ class DepositfilesCom(Account):                         ("Walter Purcaro", "vuolter@gmail.com")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("https://dfiles.eu/de/gold/")          validuntil = re.search(r"Sie haben Gold Zugang bis: <b>(.*?)</b></div>", html).group(1) @@ -35,4 +35,4 @@ class DepositfilesCom(Account):                                 'password': password})          if r'<div class="error_message">Sie haben eine falsche Benutzername-Passwort-Kombination verwendet.</div>' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/EuroshareEu.py b/module/plugins/accounts/EuroshareEu.py index bc8618250..2b90bfc13 100644 --- a/module/plugins/accounts/EuroshareEu.py +++ b/module/plugins/accounts/EuroshareEu.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class EuroshareEu(Account):      __name__    = "EuroshareEu"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = """Euroshare.eu account plugin""" @@ -17,7 +17,7 @@ class EuroshareEu(Account):      __authors__     = [("zoidberg", "zoidberg@mujmail.cz")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          self.relogin(user)          html = self.load("http://euroshare.eu/customer-zone/settings/") @@ -39,4 +39,4 @@ class EuroshareEu(Account):                                 'password': password})          if u">Nesprávne prihlasovacie meno alebo heslo" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FastixRu.py b/module/plugins/accounts/FastixRu.py index 13edbbb44..31e7d8bca 100644 --- a/module/plugins/accounts/FastixRu.py +++ b/module/plugins/accounts/FastixRu.py @@ -7,7 +7,7 @@ from module.common.json_layer import json_loads  class FastixRu(Account):      __name__    = "FastixRu"      __type__    = "account" -    __version__ = "0.05" +    __version__ = "0.07"      __status__  = "testing"      __description__ = """Fastix account plugin""" @@ -15,10 +15,19 @@ class FastixRu(Account):      __authors__     = [("Massimo Rosamilia", "max@spiritix.eu")] -    def parse_info(self, user, password, data, req): +    def grab_hosters(self, user, password, data, req): +        html = self.load("http://fastix.ru/api_v2", +                      get={'apikey': "5182964c3f8f9a7f0b00000a_kelmFB4n1IrnCDYuIFn2y", +                           'sub'   : "allowed_sources"}) +        host_list = json_loads(html) +        host_list = host_list['allow'] +        return host_list + + +    def grab_info(self, user, password, data, req):          data = self.get_data(user)          html = json_loads(self.load("http://fastix.ru/api_v2/", -                                    get={'apikey': data['api'], +                                    get={'apikey': data['apikey'],                                           'sub'   : "getaccountdetails"}))          points = html['points'] @@ -32,15 +41,13 @@ class FastixRu(Account):      def login(self, user, password, data, req): -        html = self.load("https://fastix.ru/api_v2/", -                         get={'sub'     : "get_apikey", -                              'email'   : user, -                              'password': password}) +        api = json_loads(self.load("https://fastix.ru/api_v2/", +                                   get={'sub'     : "get_apikey", +                                        'email'   : user, +                                        'password': password})) -        api = json_loads(html) -        api = api['apikey'] +        if 'error' in api: +            self.fail_login(api['error_txt']) -        data['api'] = api - -        if "error_code" in html: -            self.login_fail() +        else: +            data['apikey'] = api['apikey'] diff --git a/module/plugins/accounts/FastshareCz.py b/module/plugins/accounts/FastshareCz.py index 3a3769a1c..6cf2551d0 100644 --- a/module/plugins/accounts/FastshareCz.py +++ b/module/plugins/accounts/FastshareCz.py @@ -9,7 +9,7 @@ from module.plugins.internal.Plugin import set_cookie  class FastshareCz(Account):      __name__    = "FastshareCz"      __type__    = "account" -    __version__ = "0.09" +    __version__ = "0.10"      __status__  = "testing"      __description__ = """Fastshare.cz account plugin""" @@ -21,7 +21,7 @@ class FastshareCz(Account):      CREDIT_PATTERN = r'Credit\s*:\s*</td>\s*<td>(.+?)\s*<' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = -1          trafficleft = None          premium     = False @@ -49,4 +49,4 @@ class FastshareCz(Account):                                 'heslo': password})          if ">Wrong username or password" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FilecloudIo.py b/module/plugins/accounts/FilecloudIo.py index bdb13bd3d..075778af4 100644 --- a/module/plugins/accounts/FilecloudIo.py +++ b/module/plugins/accounts/FilecloudIo.py @@ -8,7 +8,7 @@ from module.plugins.internal.Plugin import set_cookie  class FilecloudIo(Account):      __name__    = "FilecloudIo"      __type__    = "account" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __description__ = """FilecloudIo account plugin""" @@ -17,7 +17,7 @@ class FilecloudIo(Account):                         ("stickell", "l.stickell@yahoo.it")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          #: It looks like the first API request always fails, so we retry 5 times, it should work on the second try          for _i in xrange(5):              rep = self.load("https://secure.filecloud.io/api-fetch_apikey.api", @@ -57,4 +57,4 @@ class FilecloudIo(Account):                           post=self.form_data)          if "you have successfully logged in" not in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FilefactoryCom.py b/module/plugins/accounts/FilefactoryCom.py index e3d0c8491..69b1a7d7e 100644 --- a/module/plugins/accounts/FilefactoryCom.py +++ b/module/plugins/accounts/FilefactoryCom.py @@ -10,7 +10,7 @@ from module.plugins.internal.Account import Account  class FilefactoryCom(Account):      __name__    = "FilefactoryCom"      __type__    = "account" -    __version__ = "0.17" +    __version__ = "0.18"      __status__  = "testing"      __description__ = """Filefactory.com account plugin""" @@ -22,7 +22,7 @@ class FilefactoryCom(Account):      VALID_UNTIL_PATTERN = r'Premium valid until: <strong>(?P<D>\d{1,2})\w{1,2} (?P<M>\w{3}), (?P<Y>\d{4})</strong>' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://www.filefactory.com/account/")          m = re.search(self.VALID_UNTIL_PATTERN, html) @@ -46,4 +46,4 @@ class FilefactoryCom(Account):                                 'Submit'       : "Sign In"})          if req.lastEffectiveURL != "http://www.filefactory.com/account/": -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FilejungleCom.py b/module/plugins/accounts/FilejungleCom.py index fb251ac5f..a2ab676ee 100644 --- a/module/plugins/accounts/FilejungleCom.py +++ b/module/plugins/accounts/FilejungleCom.py @@ -10,7 +10,7 @@ from module.plugins.internal.Account import Account  class FilejungleCom(Account):      __name__    = "FilejungleCom"      __type__    = "account" -    __version__ = "0.14" +    __version__ = "0.15"      __status__  = "testing"      __description__ = """Filejungle.com account plugin""" @@ -25,7 +25,7 @@ class FilejungleCom(Account):      LOGIN_FAILED_PATTERN = r'<span htmlfor="loginUser(Name|Password)" generated="true" class="fail_info">' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load(self.URL + "dashboard.php")          m = re.search(self.TRAFFIC_LEFT_PATTERN, html)          if m: @@ -48,4 +48,4 @@ class FilejungleCom(Account):                                 'recaptcha_shortencode_field': ""})          if re.search(self.LOGIN_FAILED_PATTERN, html): -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FilerNet.py b/module/plugins/accounts/FilerNet.py index 674c7a5dd..8cfc39ef5 100644 --- a/module/plugins/accounts/FilerNet.py +++ b/module/plugins/accounts/FilerNet.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class FilerNet(Account):      __name__    = "FilerNet"      __type__    = "account" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __description__ = """Filer.net account plugin""" @@ -23,7 +23,7 @@ class FilerNet(Account):      FREE_PATTERN = r'Account Status</th>\s*<td>\s*Free' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("https://filer.net/profile")          #: Free user @@ -56,4 +56,4 @@ class FilerNet(Account):                                 '_target_path': "https://filer.net/"})          if 'Logout' not in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FilesMailRu.py b/module/plugins/accounts/FilesMailRu.py index 7ed09e731..cbbdd7528 100644 --- a/module/plugins/accounts/FilesMailRu.py +++ b/module/plugins/accounts/FilesMailRu.py @@ -6,7 +6,7 @@ from module.plugins.internal.Account import Account  class FilesMailRu(Account):      __name__    = "FilesMailRu"      __type__    = "account" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __description__ = """Filesmail.ru account plugin""" @@ -14,7 +14,7 @@ class FilesMailRu(Account):      __authors__     = [("RaNaN", "RaNaN@pyload.org")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          return {'validuntil': None, 'trafficleft': None} @@ -28,4 +28,4 @@ class FilesMailRu(Account):                                 'Page'    : "http://files.mail.ru/"})          if "ÐевеÑМПе ÐžÐŒÑ Ð¿ÐŸÐ»ÑзПваÑÐµÐ»Ñ ÐžÐ»Ðž паÑПлÑ" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FileserveCom.py b/module/plugins/accounts/FileserveCom.py index dabfc1932..86401a486 100644 --- a/module/plugins/accounts/FileserveCom.py +++ b/module/plugins/accounts/FileserveCom.py @@ -9,7 +9,7 @@ from module.common.json_layer import json_loads  class FileserveCom(Account):      __name__    = "FileserveCom"      __type__    = "account" -    __version__ = "0.22" +    __version__ = "0.23"      __status__  = "testing"      __description__ = """Fileserve.com account plugin""" @@ -17,7 +17,7 @@ class FileserveCom(Account):      __authors__     = [("mkaay", "mkaay@mkaay.de")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          data = self.get_data(user)          html = self.load("http://app.fileserve.com/api/login/", @@ -41,7 +41,7 @@ class FileserveCom(Account):          res = json_loads(html)          if not res['type']: -            self.login_fail() +            self.fail_login()          #: Login at fileserv html          self.load("http://www.fileserve.com/login.php", diff --git a/module/plugins/accounts/FourSharedCom.py b/module/plugins/accounts/FourSharedCom.py index a7ec8e2c5..913de1a55 100644 --- a/module/plugins/accounts/FourSharedCom.py +++ b/module/plugins/accounts/FourSharedCom.py @@ -7,7 +7,7 @@ from module.plugins.internal.Plugin import set_cookie  class FourSharedCom(Account):      __name__    = "FourSharedCom"      __type__    = "account" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __description__ = """FourShared.com account plugin""" @@ -16,7 +16,7 @@ class FourSharedCom(Account):                         ("stickell", "l.stickell@yahoo.it")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          #: Free mode only for now          return {'premium': False} @@ -32,4 +32,4 @@ class FourSharedCom(Account):                                'returnTo' : "http://www.4shared.com/account/home.jsp"})          if 'Please log in to access your 4shared account' in res: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FreakshareCom.py b/module/plugins/accounts/FreakshareCom.py index a2f66f3b3..f02741ed2 100644 --- a/module/plugins/accounts/FreakshareCom.py +++ b/module/plugins/accounts/FreakshareCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class FreakshareCom(Account):      __name__    = "FreakshareCom"      __type__    = "account" -    __version__ = "0.15" +    __version__ = "0.16"      __status__  = "testing"      __description__ = """Freakshare.com account plugin""" @@ -17,7 +17,7 @@ class FreakshareCom(Account):      __authors__     = [("RaNaN", "RaNaN@pyload.org")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium = False          validuntil  = None          trafficleft = None @@ -50,4 +50,4 @@ class FreakshareCom(Account):                                 'pass'  : password})          if ">Wrong Username or Password" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/FreeWayMe.py b/module/plugins/accounts/FreeWayMe.py index 0c315873f..0cf80348a 100644 --- a/module/plugins/accounts/FreeWayMe.py +++ b/module/plugins/accounts/FreeWayMe.py @@ -7,7 +7,7 @@ from module.common.json_layer import json_loads  class FreeWayMe(Account):      __name__    = "FreeWayMe"      __type__    = "account" -    __version__ = "0.16" +    __version__ = "0.17"      __status__  = "testing"      __description__ = """FreeWayMe account plugin""" @@ -15,7 +15,7 @@ class FreeWayMe(Account):      __authors__     = [("Nicolas Giese", "james@free-way.me")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          status = self.get_account_status(user, password, req)          self.log_debug(status) @@ -38,7 +38,7 @@ class FreeWayMe(Account):          #: Check if user and password are valid          if not status: -            self.login_fail() +            self.fail_login()      def get_account_status(self, user, password, req): @@ -48,6 +48,6 @@ class FreeWayMe(Account):          self.log_debug("Login: %s" % answer)          if answer == "Invalid login": -            self.login_fail() +            self.fail_login()          return json_loads(answer) diff --git a/module/plugins/accounts/FshareVn.py b/module/plugins/accounts/FshareVn.py index bc8ced5e2..3bd6d9d7f 100644 --- a/module/plugins/accounts/FshareVn.py +++ b/module/plugins/accounts/FshareVn.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class FshareVn(Account):      __name__    = "FshareVn"      __type__    = "account" -    __version__ = "0.11" +    __version__ = "0.12"      __status__  = "testing"      __description__ = """Fshare.vn account plugin""" @@ -24,7 +24,7 @@ class FshareVn(Account):      DIRECT_DOWNLOAD_PATTERN = ur'<input type="checkbox"\s*([^=>]*)[^>]*/>KÃch hoạt download trá»±c tiếp</dt>' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://www.fshare.vn/account_info.php")          if re.search(self.LIFETIME_PATTERN, html): @@ -53,7 +53,7 @@ class FshareVn(Account):                                 'yt0'                  : "Login"})          if not re.search(r'<img\s+alt="VIP"', html): -            self.login_fail() +            self.fail_login()      def get_traffic_left(self): diff --git a/module/plugins/accounts/HellshareCz.py b/module/plugins/accounts/HellshareCz.py index 55daa8c2d..7dbc828a0 100644 --- a/module/plugins/accounts/HellshareCz.py +++ b/module/plugins/accounts/HellshareCz.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class HellshareCz(Account):      __name__    = "HellshareCz"      __type__    = "account" -    __version__ = "0.18" +    __version__ = "0.19"      __status__  = "testing"      __description__ = """Hellshare.cz account plugin""" @@ -20,7 +20,7 @@ class HellshareCz(Account):      CREDIT_LEFT_PATTERN = r'<div class="credit-link">\s*<table>\s*<tr>\s*<th>(\d+|\d\d\.\d\d\.)</th>' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          self.relogin(user)          html = self.load("http://www.hellshare.com/") @@ -44,6 +44,7 @@ class HellshareCz(Account):                      #: Traffic-based account                      trafficleft = self.parse_traffic(credit + "MB")                      validuntil = -1 +              except Exception, e:                  self.log_error(_("Unable to parse credit info"), e)                  validuntil = -1 @@ -77,4 +78,4 @@ class HellshareCz(Account):                                 'perm_login': "on"})          if "<p>You input a wrong user name or wrong password</p>" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/HighWayMe.py b/module/plugins/accounts/HighWayMe.py index ff90ec2d2..5189870b0 100644 --- a/module/plugins/accounts/HighWayMe.py +++ b/module/plugins/accounts/HighWayMe.py @@ -7,7 +7,7 @@ from module.plugins.internal.Account import Account  class HighWayMe(Account):      __name__    = "HighWayMe.py"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = """High-Way.me account plugin""" @@ -15,7 +15,7 @@ class HighWayMe(Account):      __authors__     = [("EvolutionClip", "evolutionclip@live.de")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium     = False          validuntil  = -1          trafficleft = None @@ -47,4 +47,4 @@ class HighWayMe(Account):                                 'pass': password})          if 'UserOrPassInvalid' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/Keep2ShareCc.py b/module/plugins/accounts/Keep2ShareCc.py index 014d43a69..f67219af0 100644 --- a/module/plugins/accounts/Keep2ShareCc.py +++ b/module/plugins/accounts/Keep2ShareCc.py @@ -10,7 +10,7 @@ from module.plugins.internal.Plugin import set_cookie  class Keep2ShareCc(Account):      __name__    = "Keep2ShareCc"      __type__    = "account" -    __version__ = "0.08" +    __version__ = "0.09"      __status__  = "testing"      __description__ = """Keep2Share.cc account plugin""" @@ -25,7 +25,7 @@ class Keep2ShareCc(Account):      LOGIN_FAIL_PATTERN = r'Please fix the following input errors' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = -1          premium     = False @@ -71,4 +71,4 @@ class Keep2ShareCc(Account):                                 'yt0'                  : ""})          if re.search(self.LOGIN_FAIL_PATTERN, html): -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/LetitbitNet.py b/module/plugins/accounts/LetitbitNet.py index 1fc9b76ba..f829e5737 100644 --- a/module/plugins/accounts/LetitbitNet.py +++ b/module/plugins/accounts/LetitbitNet.py @@ -7,7 +7,7 @@ from module.plugins.internal.Account import Account  class LetitbitNet(Account):      __name__    = "LetitbitNet"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = """Letitbit.net account plugin""" @@ -15,7 +15,7 @@ class LetitbitNet(Account):      __authors__     = [("stickell", "l.stickell@yahoo.it")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          ## DISABLED BECAUSE IT GET 'key exausted' EVEN IF VALID ##          # json_data = [password, ['key/info']]          # api_rep   = self.load("http://api.letitbit.net/json", diff --git a/module/plugins/accounts/LinestorageCom.py b/module/plugins/accounts/LinestorageCom.py deleted file mode 100644 index 87dd2a1d3..000000000 --- a/module/plugins/accounts/LinestorageCom.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.XFSAccount import XFSAccount - - -class LinestorageCom(XFSAccount): -    __name__    = "LinestorageCom" -    __type__    = "account" -    __version__ = "0.04" -    __status__  = "testing" - -    __description__ = """Linestorage.com account plugin""" -    __license__     = "GPLv3" -    __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] - - -    HOSTER_DOMAIN = "linestorage.com" -    HOSTER_URL    = "http://linestorage.com/" diff --git a/module/plugins/accounts/LinksnappyCom.py b/module/plugins/accounts/LinksnappyCom.py index 00ae64b44..53801c8b0 100644 --- a/module/plugins/accounts/LinksnappyCom.py +++ b/module/plugins/accounts/LinksnappyCom.py @@ -9,7 +9,7 @@ from module.common.json_layer import json_loads  class LinksnappyCom(Account):      __name__    = "LinksnappyCom"      __type__    = "account" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __description__ = """Linksnappy.com account plugin""" @@ -17,7 +17,7 @@ class LinksnappyCom(Account):      __authors__     = [("stickell", "l.stickell@yahoo.it")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          data = self.get_data(user)          r = self.load('http://gen.linksnappy.com/lseAPI.php',                        get={'act'     : 'USERDETAILS', @@ -59,4 +59,4 @@ class LinksnappyCom(Account):                                'password': hashlib.md5(password).hexdigest()})          if "Invalid Account Details" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/MegaDebridEu.py b/module/plugins/accounts/MegaDebridEu.py index d7a04491d..7a14730ce 100644 --- a/module/plugins/accounts/MegaDebridEu.py +++ b/module/plugins/accounts/MegaDebridEu.py @@ -7,7 +7,7 @@ from module.common.json_layer import json_loads  class MegaDebridEu(Account):      __name__    = "MegaDebridEu"      __type__    = "account" -    __version__ = "0.22" +    __version__ = "0.23"      __status__  = "testing"      __description__ = """Mega-debrid.eu account plugin""" @@ -19,7 +19,7 @@ class MegaDebridEu(Account):      API_URL = "https://www.mega-debrid.eu/api.php" -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          data = self.get_data(user)          jsonResponse = self.load(self.API_URL,                                   get={'action'  : 'connectUser', @@ -41,4 +41,4 @@ class MegaDebridEu(Account):                                        'password': password})          res = json_loads(jsonResponse)          if res['response_code'] != "ok": -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/MegaRapidCz.py b/module/plugins/accounts/MegaRapidCz.py index ce2d78994..8a5f92404 100644 --- a/module/plugins/accounts/MegaRapidCz.py +++ b/module/plugins/accounts/MegaRapidCz.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class MegaRapidCz(Account):      __name__    = "MegaRapidCz"      __type__    = "account" -    __version__ = "0.37" +    __version__ = "0.38"      __status__  = "testing"      __description__ = """MegaRapid.cz account plugin""" @@ -25,7 +25,7 @@ class MegaRapidCz(Account):      TRAFFIC_LEFT_PATTERN = r'<tr><td>Kredit</td><td>(.*?) GiB' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          htmll = self.load("http://megarapid.cz/mujucet/")          m = re.search(self.LIMITDL_PATTERN, htmll) diff --git a/module/plugins/accounts/MegaRapidoNet.py b/module/plugins/accounts/MegaRapidoNet.py index 08cf1f535..f11cf284c 100644 --- a/module/plugins/accounts/MegaRapidoNet.py +++ b/module/plugins/accounts/MegaRapidoNet.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class MegaRapidoNet(Account):      __name__    = "MegaRapidoNet"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = """MegaRapido.net account plugin""" @@ -21,7 +21,7 @@ class MegaRapidoNet(Account):      USER_ID_PATTERN     = r'<\s*?div[^>]*?class\s*?=\s*?["\']checkbox_compartilhar["\'].*?>.*?<\s*?input[^>]*?name\s*?=\s*?["\']usar["\'].*?>.*?<\s*?input[^>]*?name\s*?=\s*?["\']user["\'][^>]*?value\s*?=\s*?["\'](.*?)\s*?["\']' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = None          premium     = False @@ -49,10 +49,10 @@ class MegaRapidoNet(Account):          html = self.load("http://megarapido.net/gerador")          if "sair" not in html.lower(): -            self.login_fail() +            self.fail_login()          else:              m = re.search(self.USER_ID_PATTERN, html)              if m:                  data['uid'] = m.group(1)              else: -                self.login_fail("Couldn't find the user ID") +                self.fail_login("Couldn't find the user ID") diff --git a/module/plugins/accounts/MegasharesCom.py b/module/plugins/accounts/MegasharesCom.py index ec43b7fc0..da8d6d62f 100644 --- a/module/plugins/accounts/MegasharesCom.py +++ b/module/plugins/accounts/MegasharesCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class MegasharesCom(Account):      __name__    = "MegasharesCom"      __type__    = "account" -    __version__ = "0.05" +    __version__ = "0.06"      __status__  = "testing"      __description__ = """Megashares.com account plugin""" @@ -20,7 +20,7 @@ class MegasharesCom(Account):      VALID_UNTIL_PATTERN = r'<p class="premium_info_box">Period Ends: (\w{3} \d{1,2}, \d{4})</p>' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          # self.relogin(user)          html = self.load("http://d01.megashares.com/myms.php") @@ -31,6 +31,7 @@ class MegasharesCom(Account):              timestr = re.search(self.VALID_UNTIL_PATTERN, html).group(1)              self.log_debug(timestr)              validuntil = time.mktime(time.strptime(timestr, "%b %d, %Y")) +          except Exception, e:              self.log_error(e) @@ -45,4 +46,4 @@ class MegasharesCom(Account):                                 'mymspassword'  : password})          if not '<span class="b ml">%s</span>' % user in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/MultishareCz.py b/module/plugins/accounts/MultishareCz.py index c9e30a93f..b1cbdea8a 100644 --- a/module/plugins/accounts/MultishareCz.py +++ b/module/plugins/accounts/MultishareCz.py @@ -8,7 +8,7 @@ from module.plugins.internal.Account import Account  class MultishareCz(Account):      __name__    = "MultishareCz"      __type__    = "account" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __description__ = """Multishare.cz account plugin""" @@ -20,7 +20,7 @@ class MultishareCz(Account):      ACCOUNT_INFO_PATTERN = r'<input type="hidden" id="(u_ID|u_hash)" name=".+?" value="(.+?)">' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          # self.relogin(user)          html = self.load("http://www.multishare.cz/profil/") @@ -41,4 +41,4 @@ class MultishareCz(Account):                                 'jmeno': user})          if '<div class="akce-chyba akce">' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/MyfastfileCom.py b/module/plugins/accounts/MyfastfileCom.py index 008b62cc6..244a7408b 100644 --- a/module/plugins/accounts/MyfastfileCom.py +++ b/module/plugins/accounts/MyfastfileCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class MyfastfileCom(Account):      __name__    = "MyfastfileCom"      __type__    = "account" -    __version__ = "0.06" +    __version__ = "0.07"      __status__  = "testing"      __description__ = """Myfastfile.com account plugin""" @@ -17,7 +17,7 @@ class MyfastfileCom(Account):      __authors__     = [("stickell", "l.stickell@yahoo.it")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          if 'days_left' in self.json_data:              validuntil = time.time() + self.json_data['days_left'] * 24 * 60 * 60              return {'premium': True, 'validuntil': validuntil, 'trafficleft': -1} @@ -36,4 +36,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.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/NitroflareCom.py b/module/plugins/accounts/NitroflareCom.py index b7edcca32..ec90ac341 100644 --- a/module/plugins/accounts/NitroflareCom.py +++ b/module/plugins/accounts/NitroflareCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class NitroflareCom(Account):      __name__    = "NitroflareCom"      __type__    = "account" -    __version__ = "0.06" +    __version__ = "0.07"      __status__  = "testing"      __description__ = """Nitroflare.com account plugin""" @@ -24,7 +24,7 @@ class NitroflareCom(Account):      TOKEN_PATTERN = r'name="token" value="(.+?)"' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil   = -1          trafficleft  = None          premium      = False @@ -40,6 +40,7 @@ class NitroflareCom(Account):              try:                  validuntil = sum(int(v) * {'day': 24 * 3600, 'hour': 3600, 'minute': 60}[u.lower()] for v, u in                                   re.findall(r'(\d+)\s*(day|hour|minute)', expiredate, re.I)) +              except Exception, e:                  self.log_error(e) @@ -79,4 +80,4 @@ class NitroflareCom(Account):                                 'token'   : token})          if re.search(self.LOGIN_FAIL_PATTERN, html): -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/NoPremiumPl.py b/module/plugins/accounts/NoPremiumPl.py index 97e58f5f0..e8de0f4cf 100644 --- a/module/plugins/accounts/NoPremiumPl.py +++ b/module/plugins/accounts/NoPremiumPl.py @@ -11,7 +11,7 @@ from module.plugins.internal.Account import Account  class NoPremiumPl(Account):      __name__    = "NoPremiumPl"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = "NoPremium.pl account plugin" @@ -32,10 +32,11 @@ class NoPremiumPl(Account):      _pwd = None -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          self._req = req          try:              result = json_loads(self.run_auth_query()) +          except Exception:              #@TODO: return or let it be thrown?              return @@ -61,11 +62,12 @@ class NoPremiumPl(Account):          try:              response = json_loads(self.run_auth_query()) +          except Exception: -            self.login_fail() +            self.fail_login()          if "errno" in response.keys(): -            self.login_fail() +            self.fail_login()          data['usr'] = self._usr          data['pwd'] = self._pwd diff --git a/module/plugins/accounts/NowVideoSx.py b/module/plugins/accounts/NowVideoSx.py index 73bb383be..f2b2b7bdc 100644 --- a/module/plugins/accounts/NowVideoSx.py +++ b/module/plugins/accounts/NowVideoSx.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class NowVideoSx(Account):      __name__    = "NowVideoSx"      __type__    = "account" -    __version__ = "0.05" +    __version__ = "0.06"      __status__  = "testing"      __description__ = """NowVideo.at account plugin""" @@ -20,7 +20,7 @@ class NowVideoSx(Account):      VALID_UNTIL_PATTERN = r'>Your premium membership expires on: (.+?)<' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = -1          premium     = None @@ -54,4 +54,4 @@ class NowVideoSx(Account):                                 'pass': password})          if re.search(r'>Log In<', html): -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/OboomCom.py b/module/plugins/accounts/OboomCom.py index 380368b70..abb223e65 100644 --- a/module/plugins/accounts/OboomCom.py +++ b/module/plugins/accounts/OboomCom.py @@ -23,7 +23,7 @@ from module.plugins.internal.Account import Account  class OboomCom(Account):      __name__    = "OboomCom"      __type__    = "account" -    __version__ = "0.27" +    __version__ = "0.28"      __status__  = "testing"      __description__ = """Oboom.com account plugin""" @@ -40,22 +40,19 @@ class OboomCom(Account):                                        get={'auth': user,                                             'pass': pbkdf2})) -        if not result[0] == 200: +        if result[0] != 200:              self.log_warning(_("Failed to log in: %s") % result[1]) -            self.login_fail() +            self.fail_login()          return result[1] -    def parse_info(self, name, req): +    def grab_info(self, name, req):          account_data = self.load_account_data(name, req)          userData = account_data['user'] -        if userData['premium'] == "null": -            premium = False -        else: -            premium = True +        premium = userData['premium'] != "null"          if userData['premium_unix'] == "null":              validUntil = -1 @@ -65,7 +62,7 @@ class OboomCom(Account):          traffic = userData['traffic']          trafficLeft = traffic['current'] / 1024  #@TODO: Remove `/ 1024` in 0.4.10 -        maxTraffic = traffic['max'] / 1024  #@TODO: Remove `/ 1024` in 0.4.10 +        maxTraffic  = traffic['max'] / 1024  #@TODO: Remove `/ 1024` in 0.4.10          session = account_data['session'] diff --git a/module/plugins/accounts/OneFichierCom.py b/module/plugins/accounts/OneFichierCom.py index e2e84feef..e215e1fe0 100644 --- a/module/plugins/accounts/OneFichierCom.py +++ b/module/plugins/accounts/OneFichierCom.py @@ -10,7 +10,7 @@ from module.plugins.internal.Account import Account  class OneFichierCom(Account):      __name__    = "OneFichierCom"      __type__    = "account" -    __version__ = "0.15" +    __version__ = "0.16"      __status__  = "testing"      __description__ = """1fichier.com account plugin""" @@ -22,7 +22,7 @@ class OneFichierCom(Account):      VALID_UNTIL_PATTERN = r'Your subscription will end the (\d+-\d+-\d+)' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil = None          trafficleft = -1          premium = None @@ -36,6 +36,7 @@ class OneFichierCom(Account):              try:                  validuntil = time.mktime(time.strptime(expiredate, "%Y-%m-%d")) +              except Exception, e:                  self.log_error(e)              else: @@ -55,4 +56,4 @@ class OneFichierCom(Account):                                 'valider': "Send"})          if '>Invalid email address' in html or '>Invalid password' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/OverLoadMe.py b/module/plugins/accounts/OverLoadMe.py index 6741b674f..cdb500767 100644 --- a/module/plugins/accounts/OverLoadMe.py +++ b/module/plugins/accounts/OverLoadMe.py @@ -7,7 +7,7 @@ from module.common.json_layer import json_loads  class OverLoadMe(Account):      __name__    = "OverLoadMe"      __type__    = "account" -    __version__ = "0.06" +    __version__ = "0.07"      __status__  = "testing"      __description__ = """Over-Load.me account plugin""" @@ -15,7 +15,7 @@ class OverLoadMe(Account):      __authors__     = [("marley", "marley@over-load.me")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          data  = self.get_data(user)          html  = self.load("https://api.over-load.me/account.php",                            get={'user': user, @@ -39,4 +39,4 @@ class OverLoadMe(Account):          data = json_loads(jsondata)          if data['err'] == 1: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/PremiumTo.py b/module/plugins/accounts/PremiumTo.py index ba8f24c6d..946ee4f80 100644 --- a/module/plugins/accounts/PremiumTo.py +++ b/module/plugins/accounts/PremiumTo.py @@ -6,7 +6,7 @@ from module.plugins.internal.Account import Account  class PremiumTo(Account):      __name__    = "PremiumTo"      __type__    = "account" -    __version__ = "0.11" +    __version__ = "0.12"      __status__  = "testing"      __description__ = """Premium.to account plugin""" @@ -16,7 +16,7 @@ class PremiumTo(Account):                         ("stickell", "l.stickell@yahoo.it")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          traffic = self.load("http://premium.to/api/straffic.php",  #@TODO: Revert to `https` in 0.4.10                              get={'username': self.username,                                   'password': self.password}) @@ -36,4 +36,4 @@ class PremiumTo(Account):                                    'password': self.password})          if "wrong username" in authcode: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/PremiumizeMe.py b/module/plugins/accounts/PremiumizeMe.py index df3b5db51..fcc187efd 100644 --- a/module/plugins/accounts/PremiumizeMe.py +++ b/module/plugins/accounts/PremiumizeMe.py @@ -7,7 +7,7 @@ from module.plugins.internal.Account import Account  class PremiumizeMe(Account):      __name__    = "PremiumizeMe"      __type__    = "account" -    __version__ = "0.19" +    __version__ = "0.20"      __status__  = "testing"      __description__ = """Premiumize.me account plugin""" @@ -15,7 +15,7 @@ class PremiumizeMe(Account):      __authors__     = [("Florian Franzen", "FlorianFranzen@gmail.com")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          #: Get user data from premiumize.me          status = self.get_account_status(user, password)          self.log_debug(status) @@ -36,7 +36,7 @@ class PremiumizeMe(Account):          #: Check if user and password are valid          if status['status'] != 200: -            self.login_fail() +            self.fail_login()      def get_account_status(self, user, password): diff --git a/module/plugins/accounts/QuickshareCz.py b/module/plugins/accounts/QuickshareCz.py index 42022ec82..97c320ec6 100644 --- a/module/plugins/accounts/QuickshareCz.py +++ b/module/plugins/accounts/QuickshareCz.py @@ -8,7 +8,7 @@ from module.plugins.internal.Account import Account  class QuickshareCz(Account):      __name__    = "QuickshareCz"      __type__    = "account" -    __version__ = "0.05" +    __version__ = "0.06"      __status__  = "testing"      __description__ = """Quickshare.cz account plugin""" @@ -19,7 +19,7 @@ class QuickshareCz(Account):      TRAFFIC_LEFT_PATTERN = r'Stav kreditu: <strong>(.+?)</strong>' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://www.quickshare.cz/premium")          m = re.search(self.TRAFFIC_LEFT_PATTERN, html) @@ -40,4 +40,4 @@ class QuickshareCz(Account):                                 'jmeno': user})          if u'>TakovÜ uÅŸivatel neexistuje.<' in html or u'>Å patné heslo.<' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/RPNetBiz.py b/module/plugins/accounts/RPNetBiz.py index d713cedca..f973ea4cd 100644 --- a/module/plugins/accounts/RPNetBiz.py +++ b/module/plugins/accounts/RPNetBiz.py @@ -7,7 +7,7 @@ from module.common.json_layer import json_loads  class RPNetBiz(Account):      __name__    = "RPNetBiz"      __type__    = "account" -    __version__ = "0.15" +    __version__ = "0.16"      __status__  = "testing"      __description__ = """RPNet.biz account plugin""" @@ -15,7 +15,7 @@ class RPNetBiz(Account):      __authors__     = [("Dman", "dmanugm@gmail.com")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          #: Get account information from rpnet.biz          res = self.get_account_status(user, password, req)          try: @@ -39,7 +39,7 @@ class RPNetBiz(Account):          #: If we have an error in the res, we have wrong login information          if 'error' in res: -            self.login_fail() +            self.fail_login()      def get_account_status(self, user, password, req): diff --git a/module/plugins/accounts/RapideoPl.py b/module/plugins/accounts/RapideoPl.py index e9a483927..4585bc718 100644 --- a/module/plugins/accounts/RapideoPl.py +++ b/module/plugins/accounts/RapideoPl.py @@ -11,7 +11,7 @@ from module.plugins.internal.Account import Account  class RapideoPl(Account):      __name__    = "RapideoPl"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = "Rapideo.pl account plugin" @@ -32,10 +32,11 @@ class RapideoPl(Account):      _pwd = None -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          self._req = req          try:              result = json_loads(self.run_auth_query()) +          except Exception:              #@TODO: return or let it be thrown?              return @@ -61,11 +62,12 @@ class RapideoPl(Account):          try:              response = json_loads(self.run_auth_query()) +          except Exception: -            self.login_fail() +            self.fail_login()          if "errno" in response.keys(): -            self.login_fail() +            self.fail_login()          data['usr'] = self._usr          data['pwd'] = self._pwd diff --git a/module/plugins/accounts/RapidgatorNet.py b/module/plugins/accounts/RapidgatorNet.py index 2fc266722..65cf1b047 100644 --- a/module/plugins/accounts/RapidgatorNet.py +++ b/module/plugins/accounts/RapidgatorNet.py @@ -9,7 +9,7 @@ from module.common.json_layer import json_loads  class RapidgatorNet(Account):      __name__    = "RapidgatorNet"      __type__    = "account" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __description__ = """Rapidgator.net account plugin""" @@ -20,7 +20,7 @@ class RapidgatorNet(Account):      API_URL = "http://rapidgator.net/api/user/" -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = None          premium     = False @@ -75,4 +75,4 @@ class RapidgatorNet(Account):          except Exception, e:              self.log_error(e) -        self.login_fail() +        self.fail_login() diff --git a/module/plugins/accounts/RapiduNet.py b/module/plugins/accounts/RapiduNet.py index 1ec29bd77..30bac4fba 100644 --- a/module/plugins/accounts/RapiduNet.py +++ b/module/plugins/accounts/RapiduNet.py @@ -10,7 +10,7 @@ from module.common.json_layer import json_loads  class RapiduNet(Account):      __name__    = "RapiduNet"      __type__    = "account" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __description__ = """Rapidu.net account plugin""" @@ -26,7 +26,7 @@ class RapiduNet(Account):      TRAFFIC_LEFT_PATTERN = r'class="tipsyS"><b>(.+?)<' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = -1          premium     = False @@ -62,5 +62,5 @@ class RapiduNet(Account):          self.log_debug(json) -        if not json['message'] == "success": -            self.login_fail() +        if json['message'] != "success": +            self.fail_login() diff --git a/module/plugins/accounts/RealdebridCom.py b/module/plugins/accounts/RealdebridCom.py index 718850c1a..f4c2c754d 100644 --- a/module/plugins/accounts/RealdebridCom.py +++ b/module/plugins/accounts/RealdebridCom.py @@ -8,7 +8,7 @@ from module.plugins.internal.Account import Account  class RealdebridCom(Account):      __name__    = "RealdebridCom"      __type__    = "account" -    __version__ = "0.48" +    __version__ = "0.49"      __status__  = "testing"      __description__ = """Real-Debrid.com account plugin""" @@ -16,7 +16,7 @@ class RealdebridCom(Account):      __authors__     = [("Devirex Hazzard", "naibaf_11@yahoo.de")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          if self.pin_code:              return @@ -38,7 +38,7 @@ class RealdebridCom(Account):                                'pass': password})          if "Your login informations are incorrect" in html: -            self.login_fail() +            self.fail_login()          elif "PIN Code required" in html:              self.log_warning(_("PIN code required. Please login to https://real-debrid.com using the PIN or disable the double authentication in your control panel on https://real-debrid.com")) diff --git a/module/plugins/accounts/RehostTo.py b/module/plugins/accounts/RehostTo.py index 36e5e33eb..50b64bff8 100644 --- a/module/plugins/accounts/RehostTo.py +++ b/module/plugins/accounts/RehostTo.py @@ -6,7 +6,7 @@ from module.plugins.internal.Account import Account  class RehostTo(Account):      __name__    = "RehostTo"      __type__    = "account" -    __version__ = "0.18" +    __version__ = "0.19"      __status__  = "testing"      __description__ = """Rehost.to account plugin""" @@ -14,7 +14,7 @@ class RehostTo(Account):      __authors__     = [("RaNaN", "RaNaN@pyload.org")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium     = False          trafficleft = None          validuntil  = -1 @@ -55,4 +55,4 @@ class RehostTo(Account):          if "ERROR" in html:              self.log_debug(html) -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/ShareonlineBiz.py b/module/plugins/accounts/ShareonlineBiz.py index 87bbc4632..c0dc7e688 100644 --- a/module/plugins/accounts/ShareonlineBiz.py +++ b/module/plugins/accounts/ShareonlineBiz.py @@ -9,7 +9,7 @@ from module.plugins.internal.Plugin import set_cookie  class ShareonlineBiz(Account):      __name__    = "ShareonlineBiz"      __type__    = "account" -    __version__ = "0.39" +    __version__ = "0.40"      __status__  = "testing"      __description__ = """Share-online.biz account plugin""" @@ -30,15 +30,15 @@ class ShareonlineBiz(Account):          api = dict(line.split("=") for line in res.splitlines() if "=" in line)          if not 'a' in api: -            self.login_fail(res.strip('*').strip()) +            self.fail_login(res.strip('*').strip())          if api['a'].lower() == "not_available": -            self.login_fail(_("No info available")) +            self.fail_login(_("No info available"))          return api -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium     = False          validuntil  = None          trafficleft = -1 diff --git a/module/plugins/accounts/SimplyPremiumCom.py b/module/plugins/accounts/SimplyPremiumCom.py index a5c69f51c..133a96ec3 100644 --- a/module/plugins/accounts/SimplyPremiumCom.py +++ b/module/plugins/accounts/SimplyPremiumCom.py @@ -8,7 +8,7 @@ from module.plugins.internal.Plugin import set_cookie  class SimplyPremiumCom(Account):      __name__    = "SimplyPremiumCom"      __type__    = "account" -    __version__ = "0.08" +    __version__ = "0.09"      __status__  = "testing"      __description__ = """Simply-Premium.com account plugin""" @@ -16,7 +16,7 @@ class SimplyPremiumCom(Account):      __authors__     = [("EvolutionClip", "evolutionclip@live.de")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium     = False          validuntil  = -1          trafficleft = None @@ -46,4 +46,4 @@ class SimplyPremiumCom(Account):                           post={'key': user} if not password else {'login_name': user, 'login_pass': password})          if 'logout' not in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/SimplydebridCom.py b/module/plugins/accounts/SimplydebridCom.py index 84c38227e..b8d679604 100644 --- a/module/plugins/accounts/SimplydebridCom.py +++ b/module/plugins/accounts/SimplydebridCom.py @@ -8,7 +8,7 @@ from module.plugins.internal.Account import Account  class SimplydebridCom(Account):      __name__    = "SimplydebridCom"      __type__    = "account" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __description__ = """Simply-Debrid.com account plugin""" @@ -16,7 +16,7 @@ class SimplydebridCom(Account):      __authors__     = [("Kagenoshin", "kagenoshin@gmx.ch")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          res = self.load("http://simply-debrid.com/api.php",                          get={'login': 2,                               'u'    : user, @@ -34,4 +34,4 @@ class SimplydebridCom(Account):                               'u'    : user,                               'p'    : password})          if res != "02: loggin success": -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/SmoozedCom.py b/module/plugins/accounts/SmoozedCom.py index 9c2451794..2da4563ab 100644 --- a/module/plugins/accounts/SmoozedCom.py +++ b/module/plugins/accounts/SmoozedCom.py @@ -26,7 +26,7 @@ from module.plugins.internal.Account import Account  class SmoozedCom(Account):      __name__    = "SmoozedCom"      __type__    = "account" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __description__ = """Smoozed.com account plugin""" @@ -34,7 +34,7 @@ class SmoozedCom(Account):      __authors__     = [("", "")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          status = self.get_account_status(user, password, req)          self.log_debug(status) @@ -67,7 +67,7 @@ class SmoozedCom(Account):          #: Check if user and password are valid          if status['state'] != 'ok': -            self.login_fail() +            self.fail_login()      def get_account_status(self, user, password, req): diff --git a/module/plugins/accounts/TurbobitNet.py b/module/plugins/accounts/TurbobitNet.py index 206e7874f..cfec97545 100644 --- a/module/plugins/accounts/TurbobitNet.py +++ b/module/plugins/accounts/TurbobitNet.py @@ -10,7 +10,7 @@ from module.plugins.internal.Plugin import set_cookie  class TurbobitNet(Account):      __name__    = "TurbobitNet"      __type__    = "account" -    __version__ = "0.05" +    __version__ = "0.06"      __status__  = "testing"      __description__ = """TurbobitNet account plugin""" @@ -18,7 +18,7 @@ class TurbobitNet(Account):      __authors__     = [("zoidberg", "zoidberg@mujmail.cz")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://turbobit.net")          m = re.search(r'<u>Turbo Access</u> to ([\d.]+)', html) @@ -41,4 +41,4 @@ class TurbobitNet(Account):                                 "user[submit]": "Login"})          if not '<div class="menu-item user-name">' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/UlozTo.py b/module/plugins/accounts/UlozTo.py index 00e125dbc..79b1bd050 100644 --- a/module/plugins/accounts/UlozTo.py +++ b/module/plugins/accounts/UlozTo.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class UlozTo(Account):      __name__    = "UlozTo"      __type__    = "account" -    __version__ = "0.12" +    __version__ = "0.13"      __status__  = "testing"      __description__ = """Uloz.to account plugin""" @@ -21,7 +21,7 @@ class UlozTo(Account):      TRAFFIC_LEFT_PATTERN = r'<li class="menu-kredit"><a .*?title=".+?GB = ([\d.]+) MB"' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://www.ulozto.net/")          m = re.search(self.TRAFFIC_LEFT_PATTERN, html) @@ -46,4 +46,4 @@ class UlozTo(Account):                                 'remember': "on"})          if '<div class="flash error">' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/UploadableCh.py b/module/plugins/accounts/UploadableCh.py index 9c2649e51..6f9229a49 100644 --- a/module/plugins/accounts/UploadableCh.py +++ b/module/plugins/accounts/UploadableCh.py @@ -6,7 +6,7 @@ from module.plugins.internal.Account import Account  class UploadableCh(Account):      __name__    = "UploadableCh"      __type__    = "account" -    __version__ = "0.05" +    __version__ = "0.06"      __status__  = "testing"      __description__ = """Uploadable.ch account plugin""" @@ -14,7 +14,7 @@ class UploadableCh(Account):      __authors__     = [("Sasch", "gsasch@gmail.com")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("http://www.uploadable.ch/login.php")          premium     = '<a href="/logout.php"' in html @@ -31,4 +31,4 @@ class UploadableCh(Account):                                 'action__login': "normalLogin"})          if "Login failed" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/UploadedTo.py b/module/plugins/accounts/UploadedTo.py index 59d3fcff9..5a96b04bc 100644 --- a/module/plugins/accounts/UploadedTo.py +++ b/module/plugins/accounts/UploadedTo.py @@ -9,7 +9,7 @@ from module.plugins.internal.Account import Account  class UploadedTo(Account):      __name__    = "UploadedTo"      __type__    = "account" -    __version__ = "0.35" +    __version__ = "0.36"      __status__  = "testing"      __description__ = """Uploaded.to account plugin""" @@ -24,7 +24,7 @@ class UploadedTo(Account):      TRAFFIC_LEFT_PATTERN = r'<b class="cB">(?P<S>[\d.,]+) (?P<U>[\w^_]+)' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = None          premium     = None @@ -72,4 +72,4 @@ class UploadedTo(Account):          m = re.search(r'"err":"(.+?)"', html)          if m is not None: -            self.login_fail(m.group(1)) +            self.fail_login(m.group(1)) diff --git a/module/plugins/accounts/UploadheroCom.py b/module/plugins/accounts/UploadheroCom.py index f31b01d03..2b676e90a 100644 --- a/module/plugins/accounts/UploadheroCom.py +++ b/module/plugins/accounts/UploadheroCom.py @@ -10,7 +10,7 @@ from module.plugins.internal.Account import Account  class UploadheroCom(Account):      __name__    = "UploadheroCom"      __type__    = "account" -    __version__ = "0.23" +    __version__ = "0.24"      __status__  = "testing"      __description__ = """Uploadhero.co account plugin""" @@ -18,7 +18,7 @@ class UploadheroCom(Account):      __authors__     = [("mcmyst", "mcmyst@hotmail.fr")] -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          premium_pattern = re.compile('Il vous reste <span class="bleu">(\d+)</span> jours premium')          data = self.get_data(user) @@ -40,4 +40,4 @@ class UploadheroCom(Account):                                 'password_login': password})          if "mot de passe invalide" in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/UploadingCom.py b/module/plugins/accounts/UploadingCom.py index d269abde7..9aaf395f9 100644 --- a/module/plugins/accounts/UploadingCom.py +++ b/module/plugins/accounts/UploadingCom.py @@ -10,7 +10,7 @@ from module.plugins.internal.Plugin import set_cookies  class UploadingCom(Account):      __name__    = "UploadingCom"      __type__    = "account" -    __version__ = "0.14" +    __version__ = "0.15"      __status__  = "testing"      __description__ = """Uploading.com account plugin""" @@ -22,7 +22,7 @@ class UploadingCom(Account):      VALID_UNTIL_PATTERN = r'Valid Until:(.+?)<' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = None          premium     = None diff --git a/module/plugins/accounts/UptoboxCom.py b/module/plugins/accounts/UptoboxCom.py index 68aaecc47..54d733375 100644 --- a/module/plugins/accounts/UptoboxCom.py +++ b/module/plugins/accounts/UptoboxCom.py @@ -6,14 +6,14 @@ from module.plugins.internal.XFSAccount import XFSAccount  class UptoboxCom(XFSAccount):      __name__    = "UptoboxCom"      __type__    = "account" -    __version__ = "0.09" +    __version__ = "0.12"      __status__  = "testing" -    __description__ = """DDLStorage.com account plugin""" +    __description__ = """Uptobox.com account plugin"""      __license__     = "GPLv3" -    __authors__     = [("zoidberg", "zoidberg@mujmail.cz")] +    __authors__     = [("benbox69", "dev@tollet.me")]      HOSTER_DOMAIN = "uptobox.com"      HOSTER_URL    = "https://uptobox.com/" -    LOGIN_URL     = "https://login.uptobox.com/" +    LOGIN_URL     = "https://login.uptobox.com/logarithme/" diff --git a/module/plugins/accounts/WebshareCz.py b/module/plugins/accounts/WebshareCz.py index bbfb90a92..33f851263 100644 --- a/module/plugins/accounts/WebshareCz.py +++ b/module/plugins/accounts/WebshareCz.py @@ -12,7 +12,7 @@ from module.plugins.internal.Account import Account  class WebshareCz(Account):      __name__    = "WebshareCz"      __type__    = "account" -    __version__ = "0.10" +    __version__ = "0.11"      __status__  = "testing"      __description__ = """Webshare.cz account plugin""" @@ -25,7 +25,7 @@ class WebshareCz(Account):      TRAFFIC_LEFT_PATTERN = r'<bytes>(.+)</bytes>' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          html = self.load("https://webshare.cz/api/user_data/",                          post={'wst': self.get_data(user).get('wst', None)}) @@ -47,7 +47,7 @@ class WebshareCz(Account):                                 'wst'              : ""})          if "<status>OK</status>" not in salt: -            self.login_fail() +            self.fail_login()          salt     = re.search('<salt>(.+)</salt>', salt).group(1)          password = hashlib.sha1(md5_crypt.encrypt(password, salt=salt)).hexdigest() @@ -61,6 +61,6 @@ class WebshareCz(Account):                                  'wst'              : ""})          if "<status>OK</status>" not in login: -            self.login_fail() +            self.fail_login()          data['wst'] = re.search('<token>(.+)</token>', login).group(1) diff --git a/module/plugins/accounts/YibaishiwuCom.py b/module/plugins/accounts/YibaishiwuCom.py index c5dda0921..fdacfde4d 100644 --- a/module/plugins/accounts/YibaishiwuCom.py +++ b/module/plugins/accounts/YibaishiwuCom.py @@ -8,7 +8,7 @@ from module.plugins.internal.Account import Account  class YibaishiwuCom(Account):      __name__    = "YibaishiwuCom"      __type__    = "account" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing"      __description__ = """115.com account plugin""" @@ -19,7 +19,7 @@ class YibaishiwuCom(Account):      ACCOUNT_INFO_PATTERN = r'var USER_PERMISSION = {(.*?)}' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          # self.relogin(user)          html = self.load("http://115.com/") @@ -37,4 +37,4 @@ class YibaishiwuCom(Account):                                 "login[passwd]" : password})          if not 'var USER_PERMISSION = {' in html: -            self.login_fail() +            self.fail_login() diff --git a/module/plugins/accounts/ZeveraCom.py b/module/plugins/accounts/ZeveraCom.py index 4138ba3cc..ac057b76a 100644 --- a/module/plugins/accounts/ZeveraCom.py +++ b/module/plugins/accounts/ZeveraCom.py @@ -8,7 +8,7 @@ from module.plugins.internal.Account import Account  class ZeveraCom(Account):      __name__    = "ZeveraCom"      __type__    = "account" -    __version__ = "0.28" +    __version__ = "0.29"      __status__  = "testing"      __description__ = """Zevera.com account plugin""" @@ -33,7 +33,7 @@ class ZeveraCom(Account):              self.API_URL = "http://api.%s/jDownloader.ashx" % (self.HOSTER_DOMAIN or "") -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil  = None          trafficleft = None          premium     = False @@ -53,7 +53,7 @@ class ZeveraCom(Account):          self.password = password          if self.api_response(req) == "No trafic": -            self.login_fail() +            self.fail_login()      def api_response(self, req, just_header=False, **kwargs): diff --git a/module/plugins/captcha/LinksaveIn.py b/module/plugins/captcha/LinksaveIn.py index 4d2e2bc34..a9ccecf3c 100644 --- a/module/plugins/captcha/LinksaveIn.py +++ b/module/plugins/captcha/LinksaveIn.py @@ -79,8 +79,10 @@ class LinksaveIn(OCR):                      rgb_c = lut[pix[x, y]]                      try:                          cstat[rgb_c] += 1 +                      except Exception:                          cstat[rgb_c] = 1 +                      if rgb_bg is rgb_c:                          stat[bgpath] += 1          max_p = 0 diff --git a/module/plugins/crypter/ChipDe.py b/module/plugins/crypter/ChipDe.py index 3604635e5..8d823d88d 100644 --- a/module/plugins/crypter/ChipDe.py +++ b/module/plugins/crypter/ChipDe.py @@ -23,8 +23,10 @@ class ChipDe(Crypter):          self.html = self.load(pyfile.url)          try:              f = re.search(r'"(http://video\.chip\.de/.+)"', self.html) +          except Exception:              self.fail(_("Failed to find the URL")) +          else:              self.urls = [f.group(1)]              self.log_debug("The file URL is %s" % self.urls[0]) diff --git a/module/plugins/crypter/CloudzillaToFolder.py b/module/plugins/crypter/CloudzillaToFolder.py index 09b4d4c08..6c8ce5917 100644 --- a/module/plugins/crypter/CloudzillaToFolder.py +++ b/module/plugins/crypter/CloudzillaToFolder.py @@ -1,7 +1,6 @@  # -*- coding: utf-8 -*-  import re -import urlparse  from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo @@ -9,7 +8,7 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo  class CloudzillaToFolder(SimpleHoster):      __name__    = "CloudzillaToFolder"      __type__    = "crypter" -    __version__ = "0.03" +    __version__ = "0.04"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?cloudzilla\.to/share/folder/(?P<ID>[\w^_]+)' @@ -33,7 +32,7 @@ class CloudzillaToFolder(SimpleHoster):              self.html = self.load(self.pyfile.url, get={'key': self.get_password()})          if re.search(self.PASSWORD_PATTERN, self.html): -            self.retry(reason="Wrong password") +            self.retry(msg="Wrong password")  getInfo = create_getInfo(CloudzillaToFolder) diff --git a/module/plugins/crypter/Go4UpCom.py b/module/plugins/crypter/Go4UpCom.py index 026982014..2d423a1a9 100644..100755 --- a/module/plugins/crypter/Go4UpCom.py +++ b/module/plugins/crypter/Go4UpCom.py @@ -4,18 +4,20 @@ import re  import urlparse  from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo +import json  class Go4UpCom(SimpleCrypter):      __name__    = "Go4UpCom"      __type__    = "crypter" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __pattern__ = r'http://go4up\.com/(dl/\w{12}|rd/\w{12}/\d+)'      __config__  = [("use_premium"       , "bool", "Use premium account if available"   , True),                     ("use_subfolder"     , "bool", "Save package to subfolder"          , True), -                   ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] +                   ("subfolder_per_pack", "bool", "Create a subfolder for each package", True), +                   ("preferred_hoster"  , "int" , "Id of preferred hoster or 0 for all", 0)]      __description__ = """Go4Up.com decrypter plugin"""      __license__     = "GPLv3" @@ -32,19 +34,20 @@ class Go4UpCom(SimpleCrypter):      def get_links(self):          links = [] - -        m = re.search(r'(/download/gethosts/.+?)"', self.html) -        if m: -            self.html = self.load(urlparse.urljoin("http://go4up.com/", m.group(1))) -            pages = [self.load(url) for url in re.findall(self.LINK_PATTERN, self.html)] -        else: -            pages = [self.html] - -        for html in pages: -            try: -                links.append(re.search(r'<b><a href="(.+?)"', html).group(1)) -            except Exception: -                continue +        preference = self.get_config("preferred_hoster") + +        hosterslink_re = re.search(r'(/download/gethosts/.+?)"', self.html) +        if hosterslink_re: +            hosters = self.load(urlparse.urljoin("http://go4up.com/", hosterslink_re.group(1))) +            for hoster in json.loads(hosters): +                if preference != 0 and preference != int(hoster["hostId"]): +                    continue +                pagelink_re = re.search(self.LINK_PATTERN, hoster["link"]) +                if pagelink_re: +                    page = self.load(pagelink_re.group(1)) +                    link_re = re.search(r'<b><a href="(.+?)"', page) +                    if link_re: +                        links.append(link_re.group(1))          return links diff --git a/module/plugins/crypter/GoogledriveComFolder.py b/module/plugins/crypter/GoogledriveComFolder.py index 88c7ebab2..e7a5bae2c 100644 --- a/module/plugins/crypter/GoogledriveComFolder.py +++ b/module/plugins/crypter/GoogledriveComFolder.py @@ -6,11 +6,11 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo  class GoogledriveComFolder(SimpleCrypter):      __name__    = "GoogledriveCom"      __type__    = "crypter" -    __version__ = "0.02" +    __version__ = "0.03"      __status__  = "testing"      __pattern__ = r'https?://(?:www\.)?drive\.google\.com/folderview\?.*id=\w+' -    __config__  = [("use_subfolder"     , "bool", "Save package to subfolder"          , True),  #: Overrides pyload.config['general']['folder_per_package'] +    __config__  = [("use_subfolder"     , "bool", "Save package to subfolder"          , True),                     ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]      __description__ = """Drive.google.com folder decrypter plugin""" diff --git a/module/plugins/crypter/LinkCryptWs.py b/module/plugins/crypter/LinkCryptWs.py index af13f55f6..0d8590860 100644 --- a/module/plugins/crypter/LinkCryptWs.py +++ b/module/plugins/crypter/LinkCryptWs.py @@ -14,7 +14,7 @@ from module.utils import html_unescape  class LinkCryptWs(Crypter):      __name__    = "LinkCryptWs"      __type__    = "crypter" -    __version__ = "0.10" +    __version__ = "0.12"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?linkcrypt\.ws/(dir|container)/(?P<ID>\w+)' @@ -31,7 +31,6 @@ class LinkCryptWs(Crypter):      def setup(self): -        self.captcha = False          self.links   = []          self.sources = ['cnl', 'web', 'dlc', 'rsdf', 'ccf'] @@ -45,6 +44,7 @@ class LinkCryptWs(Crypter):          #: Request package          self.req.http.c.setopt(pycurl.USERAGENT, "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko")  #: Better chance to not get those key-captchas          self.html = self.load(self.pyfile.url) +        self.html = self.load(self.pyfile.url)      def decrypt(self, pyfile): @@ -60,7 +60,6 @@ class LinkCryptWs(Crypter):              self.retry(8, 15, _("Can't handle Key-Captcha"))          if self.is_captcha_protected(): -            self.captcha = True              self.unlock_captcha_protection()              self.handle_captcha_errors() @@ -154,7 +153,7 @@ class LinkCryptWs(Crypter):          unrarpw = sitein[indexi:indexe] -        if not (unrarpw == "Password" or "Dateipasswort") : +        if unrarpw not in ("Password", "Dateipasswort"):              self.log_debug("File password set to: [%s]"% unrarpw)              self.pyfile.package().password = unrarpw @@ -165,12 +164,11 @@ class LinkCryptWs(Crypter):      def handle_captcha_errors(self): -        if self.captcha: -            if "Your choice was wrong!" in self.html: -                self.captcha.invalid() -                self.retry() -            else: -                self.captcha.correct() +        if "Your choice was wrong!" in self.html: +            self.captcha.invalid() +            self.retry() +        else: +            self.captcha.correct()      def handle_link_source(self, type): @@ -275,6 +273,7 @@ class LinkCryptWs(Crypter):              (vcrypted, vjk) = self._get_cipher_params(cnl_section)              for (crypted, jk) in zip(vcrypted, vjk):                  package_links.extend(self._get_links(crypted, jk)) +          except Exception:              self.log_error(_("Unable to decrypt CNL links (JS Error) try to get over links"))              return self.handle_web_links() diff --git a/module/plugins/crypter/MultiUpOrg.py b/module/plugins/crypter/MultiUpOrg.py index 23e6dfa4a..fb228c3cd 100644 --- a/module/plugins/crypter/MultiUpOrg.py +++ b/module/plugins/crypter/MultiUpOrg.py @@ -9,10 +9,10 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo  class MultiUpOrg(SimpleCrypter):      __name__    = "MultiUpOrg"      __type__    = "crypter" -    __version__ = "0.04" +    __version__ = "0.05"      __status__  = "testing" -    __pattern__ = r'http://(?:www\.)?multiup\.org/(en|fr)/(?P<TYPE>project|download|miror)/\w+(/\w+)?' +    __pattern__ = r'http://(?:www\.)?multiup\.org/(en|fr)/(?P<TYPE>project|download|mirror)/\w+(/\w+)?'      __config__  = [("use_premium"       , "bool", "Use premium account if available"   , True),                     ("use_subfolder"     , "bool", "Save package to subfolder"          , True),                     ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] @@ -34,8 +34,8 @@ class MultiUpOrg(SimpleCrypter):              pattern = r'style="width:97%;text-align:left".*\n.*href="(.*)"'              if m_type == "download":                  dl_pattern = r'href="(.*)">.*\n.*<h5>DOWNLOAD</h5>' -                miror_page = urlparse.urljoin("http://www.multiup.org/", re.search(dl_pattern, self.html).group(1)) -                self.html = self.load(miror_page) +                mirror_page = urlparse.urljoin("http://www.multiup.org/", re.search(dl_pattern, self.html).group(1)) +                self.html = self.load(mirror_page)          return re.findall(pattern, self.html) diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py index d483be323..32c9283f7 100644 --- a/module/plugins/crypter/NCryptIn.py +++ b/module/plugins/crypter/NCryptIn.py @@ -229,6 +229,7 @@ class NCryptIn(Crypter):                  (vcrypted, vjk) = self._get_cipher_params()                  for (crypted, jk) in zip(vcrypted, vjk):                      package_links.extend(self._get_links(crypted, jk)) +              except Exception:                  self.fail(_("Unable to decrypt CNL2 links")) @@ -270,6 +271,7 @@ class NCryptIn(Crypter):              url = link.replace("link-", "frame-")              link = self.load(url, just_header=True)['location']              return link +          except Exception, detail:              self.log_debug("Error decrypting link %s, %s" % (link, detail)) diff --git a/module/plugins/crypter/RelinkUs.py b/module/plugins/crypter/RelinkUs.py index b3c13db5d..641353865 100644 --- a/module/plugins/crypter/RelinkUs.py +++ b/module/plugins/crypter/RelinkUs.py @@ -205,8 +205,10 @@ class RelinkUs(Crypter):                  (vcrypted, vjk) = self._get_cipher_params(cnl2_form)                  for (crypted, jk) in zip(vcrypted, vjk):                      package_links.extend(self._get_links(crypted, jk)) +              except Exception:                  self.log_debug("Unable to decrypt CNL2 links") +          return package_links diff --git a/module/plugins/crypter/SexuriaCom.py b/module/plugins/crypter/SexuriaCom.py index 7942d5e42..24a5060b9 100644 --- a/module/plugins/crypter/SexuriaCom.py +++ b/module/plugins/crypter/SexuriaCom.py @@ -1,25 +1,23 @@  # -*- coding: utf-8 -*-  import re -  from module.plugins.internal.Crypter import Crypter -  class SexuriaCom(Crypter):      __name__    = "SexuriaCom"      __type__    = "crypter" -    __version__ = "0.04" +    __version__ = "0.10"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?sexuria\.com/(v1/)?(Pornos_Kostenlos_.+?_(\d+)\.html|dl_links_\d+_\d+\.html|id=\d+\&part=\d+\&link=\d+)' -    __config__  = [("use_subfolder"     , "bool", "Save package to subfolder"          , True), -                   ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] +    __config__  = [("use_subfolder"       , "bool", "Save package to subfolder"          , True), +                  ("subfolder_per_package", "bool", "Create a subfolder for each package", True)]      __description__ = """Sexuria.com decrypter plugin"""      __license__     = "GPLv3"      __authors__     = [("NETHead", "NETHead.AT.gmx.DOT.net")] - +    #: Constants      PATTERN_SUPPORTED_MAIN     = r'http://(www\.)?sexuria\.com/(v1/)?Pornos_Kostenlos_.+?_(\d+)\.html'      PATTERN_SUPPORTED_CRYPT    = r'http://(www\.)?sexuria\.com/(v1/)?dl_links_\d+_(?P<ID>\d+)\.html'      PATTERN_SUPPORTED_REDIRECT = r'http://(www\.)?sexuria\.com/out\.php\?id=(?P<ID>\d+)\&part=\d+\&link=\d+' @@ -27,15 +25,17 @@ class SexuriaCom(Crypter):      PATTERN_PASSWORD           = r'<strong>Passwort: </strong></div></td>.*?bgcolor="#EFEFEF">(?P<PWD>.*?)</td>'      PATTERN_DL_LINK_PAGE       = r'"(dl_links_\d+_\d+\.html)"'      PATTERN_REDIRECT_LINKS     = r'value="(http://sexuria\.com/out\.php\?id=\d+\&part=\d+\&link=\d+)" readonly' - +    LIST_PWDIGNORE             = ["Kein Passwort", "-"]      def decrypt(self, pyfile):          #: Init          self.pyfile = pyfile          self.package = pyfile.package() -        #: Get package links +        #: Decrypt and add links          package_name, self.links, folder_name, package_pwd = self.decrypt_links(self.pyfile.url) +        if package_pwd: +            self.pyfile.package().password = package_pwd          self.packages = [(package_name, self.links, folder_name)] @@ -62,34 +62,45 @@ class SexuriaCom(Crypter):              #: Extract info from main file              id = re.search(self.PATTERN_SUPPORTED_CRYPT, url, re.I).group('ID')              html = self.load("http://sexuria.com/v1/Pornos_Kostenlos_info_%s.html" % id) +            #: Webpage title / Package name +            titledata = re.search(self.PATTERN_TITLE, html, re.I) +            if not titledata: +                self.log_warning("No title data found, has site changed?") +            else: +                title = titledata.group('TITLE').strip() +                if title: +                    name = folder = title +                    self.log_debug("Package info found, name [%s] and folder [%s]" % (name, folder)) +            #: Password +            pwddata = re.search(self.PATTERN_PASSWORD, html, re.I | re.S) +            if not pwddata: +                self.log_warning("No password data found, has site changed?") +            else: +                pwd = pwddata.group('PWD').strip() +                if pwd and not (pwd in self.LIST_PWDIGNORE): +                    password = pwd +                    self.log_debug("Package info found, password [%s]" % password) -            title = re.search(self.PATTERN_TITLE, html, re.I).group('TITLE').strip() -            if title: -                name = folder = title -                self.log_debug("Package info found, name [%s] and folder [%s]" % (name, folder)) - -            pwd = re.search(self.PATTERN_PASSWORD, html, re.I | re.S).group('PWD') -            if pwd and pwd not in ("Kein Passwort", "-"): -                password = pwd.strip() -                self.log_debug("Password info [%s] found" % password) - -            #: Process link (dl_link) +            #: Process links (dl_link)              html = self.load(url)              links = re.findall(self.PATTERN_REDIRECT_LINKS, html, re.I) -            if len(links) == 0: +            if not links:                  self.log_error(_("Broken for link: %s") % link)              else:                  for link in links:                      link = link.replace("http://sexuria.com/", "http://www.sexuria.com/")                      finallink = self.load(link, just_header=True)['location'] -                    if not finallink or "sexuria.com/" in finallink: +                    if not finallink or ("sexuria.com/" in finallink):                          self.log_error(_("Broken for link: %s") % link)                      else:                          linklist.append(finallink) -        #: Debug log -        self.log_debug("%d supported links" % len(linklist)) -        for i, link in enumerate(linklist): -            self.log_debug("Supported link %d, %s" % (i + 1, link)) +        #: Log result +        if not linklist: +            self.fail(_("Unable to extract links (maybe plugin out of date?)")) +        else: +            for i, link in enumerate(linklist): +                self.log_debug("Supported link %d/%d: %s" % (i+1, len(linklist), link)) +        #: All done, return to caller          return name, linklist, folder, password diff --git a/module/plugins/crypter/ShareLinksBiz.py b/module/plugins/crypter/ShareLinksBiz.py index 712b4fff2..2e9abff61 100644 --- a/module/plugins/crypter/ShareLinksBiz.py +++ b/module/plugins/crypter/ShareLinksBiz.py @@ -216,8 +216,10 @@ class ShareLinksBiz(Crypter):                  self.log_debug("JsEngine returns value [%s] for redirection link" % dlLink)                  package_links.append(dlLink) +              except Exception, detail:                  self.log_debug("Error decrypting Web link [%s], %s" % (ID, detail)) +          return package_links @@ -242,8 +244,10 @@ class ShareLinksBiz(Crypter):              try:                  (crypted, jk) = self._get_cipher_params()                  package_links.extend(self._get_links(crypted, jk)) +              except Exception:                  self.fail(_("Unable to decrypt CNL2 links")) +          return package_links diff --git a/module/plugins/crypter/TNTVillageScambioeticoOrg.py b/module/plugins/crypter/TNTVillageScambioeticoOrg.py index 6ba1ee19b..e85a8fbb7 100644 --- a/module/plugins/crypter/TNTVillageScambioeticoOrg.py +++ b/module/plugins/crypter/TNTVillageScambioeticoOrg.py @@ -6,11 +6,11 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo  class TNTVillageScambioeticoOrg(SimpleCrypter):      __name__    = "TNTVillageScambioeticoOrg"      __type__    = "crypter" -    __version__ = "0.02" +    __version__ = "0.03"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?forum\.tntvillage\.scambioetico\.org/index\.php\?.*showtopic=\d+' -    __config__  = [("use_subfolder"     , "bool", "Save package to subfolder"          , True),  #: Overrides pyload.config['general']['folder_per_package'] +    __config__  = [("use_subfolder"     , "bool", "Save package to subfolder"          , True),                     ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]      __description__ = """TNTVillage.scambioetico.org decrypter plugin""" diff --git a/module/plugins/crypter/UploadedToFolder.py b/module/plugins/crypter/UploadedToFolder.py index 381d744fe..53fb5e4b9 100644 --- a/module/plugins/crypter/UploadedToFolder.py +++ b/module/plugins/crypter/UploadedToFolder.py @@ -1,7 +1,6 @@  # -*- coding: utf-8 -*-  import re -import urlparse  from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo diff --git a/module/plugins/hooks/CaptchaBrotherhood.py b/module/plugins/hooks/CaptchaBrotherhood.py index 0df1ab8a9..838c220f0 100644 --- a/module/plugins/hooks/CaptchaBrotherhood.py +++ b/module/plugins/hooks/CaptchaBrotherhood.py @@ -79,6 +79,7 @@ class CaptchaBrotherhood(Hook):                  img.save(output, "JPEG")              data = output.getvalue()              output.close() +          except Exception, e:              raise CaptchaBrotherhoodException("Reading or converting captcha image failed: %s" % e) @@ -98,6 +99,7 @@ class CaptchaBrotherhood(Hook):          try:              req.c.perform()              res = req.getResponse() +          except Exception, e:              raise CaptchaBrotherhoodException("Submit captcha image failed") diff --git a/module/plugins/hooks/Checksum.py b/module/plugins/hooks/Checksum.py index da4d35df1..2a650768e 100644 --- a/module/plugins/hooks/Checksum.py +++ b/module/plugins/hooks/Checksum.py @@ -38,7 +38,7 @@ def compute_checksum(local_file, algorithm):  class Checksum(Addon):      __name__    = "Checksum"      __type__    = "hook" -    __version__ = "0.20" +    __version__ = "0.22"      __status__  = "testing"      __config__ = [("check_checksum", "bool"             , "Check checksum? (If False only size will be verified)", True   ), @@ -114,7 +114,7 @@ class Checksum(Addon):              api_size  = int(data['size'])              file_size = os.path.getsize(local_file) -            if api_size is not file_size: +            if api_size != file_size:                  self.log_warning(_("File %s has incorrect size: %d B (%d expected)") % (pyfile.name, file_size, api_size))                  self.check_failed(pyfile, local_file, "Incorrect file size") @@ -160,7 +160,7 @@ class Checksum(Addon):                  return          elif check_action == "nothing":              return -        pyfile.plugin.fail(reason=msg) +        pyfile.plugin.fail(msg=msg)      def package_finished(self, pypack): diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index eab196160..7d3d9237e 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -51,7 +51,7 @@ except ImportError:      pass  from module.plugins.internal.Addon import Addon, Expose, threaded -from module.plugins.internal.Plugin import replace_patterns +from module.plugins.internal.Plugin import exists, replace_patterns  from module.plugins.internal.Extractor import ArchiveError, CRCError, PasswordError  from module.utils import fs_encode, save_join as fs_join, uniqify @@ -66,6 +66,7 @@ class ArchiveQueue(object):      def get(self):          try:              return [int(pid) for pid in self.plugin.retrieve("ExtractArchive:%s" % self.storage, "").decode('base64').split()] +          except Exception:              return [] @@ -107,7 +108,7 @@ class ArchiveQueue(object):  class ExtractArchive(Addon):      __name__    = "ExtractArchive"      __type__    = "hook" -    __version__ = "1.49" +    __version__ = "1.51"      __status__  = "testing"      __config__ = [("activated"      , "bool"              , "Activated"                                 , True                                                                     ), @@ -115,7 +116,6 @@ class ExtractArchive(Addon):                    ("overwrite"      , "bool"              , "Overwrite files"                           , False                                                                    ),                    ("keepbroken"     , "bool"              , "Try to extract broken archives"            , False                                                                    ),                    ("repair"         , "bool"              , "Repair broken archives (RAR required)"     , False                                                                    ), -                  ("test"           , "bool"              , "Test archive before extracting"            , False                                                                    ),                    ("usepasswordfile", "bool"              , "Use password file"                         , True                                                                     ),                    ("passwordfile"   , "file"              , "Password file"                             , "passwords.txt"                                                          ),                    ("delete"         , "bool"              , "Delete archive after extraction"           , True                                                                     ), @@ -288,7 +288,7 @@ class ExtractArchive(Addon):              if subfolder:                  out = fs_join(out, pypack.folder) -            if not os.path.exists(out): +            if not exists(out):                  os.makedirs(out)              matched   = False @@ -313,7 +313,7 @@ class ExtractArchive(Addon):                      for fname, fid, fout in targets:                          name = os.path.basename(fname) -                        if not os.path.exists(fname): +                        if not exists(fname):                              self.log_debug(name, "File not found")                              continue @@ -348,7 +348,7 @@ class ExtractArchive(Addon):                          #: Remove processed file and related multiparts from list                          files_ids = [(fname, fid, fout) for fname, fid, fout in files_ids \ -                                    if fname not in archive.get_delete_files()] +                                    if fname not in archive.items()]                          self.log_debug("Extracted files: %s" % new_files)                          for file in new_files: @@ -356,7 +356,7 @@ class ExtractArchive(Addon):                          for filename in new_files:                              file = fs_encode(fs_join(os.path.dirname(archive.filename), filename)) -                            if not os.path.exists(file): +                            if not exists(file):                                  self.log_debug("New file %s does not exists" % filename)                                  continue @@ -403,18 +403,10 @@ class ExtractArchive(Addon):              passwords = uniqify([password] + self.get_passwords(False)) if self.get_config('usepasswordfile') else [password]              for pw in passwords:                  try: -                    if self.get_config('test') or self.repair: -                        pyfile.setCustomStatus(_("archive testing")) -                        if pw: -                            self.log_debug("Testing with password: %s" % pw) -                        pyfile.setProgress(0) -                        archive.verify(pw) -                        pyfile.setProgress(100) -                    else: -                        archive.check(pw) - -                    self.add_password(pw) -                    break +                    pyfile.setCustomStatus(_("archive testing")) +                    pyfile.setProgress(0) +                    archive.verify(pw) +                    pyfile.setProgress(100)                  except PasswordError:                      if not encrypted: @@ -425,9 +417,11 @@ class ExtractArchive(Addon):                      self.log_debug(name, e)                      self.log_info(name, _("CRC Error")) -                    if self.repair: -                        self.log_warning(name, _("Repairing...")) +                    if not self.repair: +                        raise CRCError("Archive damaged") +                    else: +                        self.log_warning(name, _("Repairing..."))                          pyfile.setCustomStatus(_("archive repairing"))                          pyfile.setProgress(0)                          repaired = archive.repair() @@ -436,15 +430,18 @@ class ExtractArchive(Addon):                          if not repaired and not self.get_config('keepbroken'):                              raise CRCError("Archive damaged") -                        self.add_password(pw) -                        break - -                    raise CRCError("Archive damaged") +                        else: +                            self.add_password(pw) +                            break                  except ArchiveError, e:                      raise ArchiveError(e) -            pyfile.setCustomStatus(_("extracting")) +                else: +                    self.add_password(pw) +                    break + +            pyfile.setCustomStatus(_("archive extracting"))              pyfile.setProgress(0)              if not encrypted or not self.get_config('usepasswordfile'): @@ -467,7 +464,7 @@ class ExtractArchive(Addon):              pyfile.setProgress(100)              pyfile.setStatus("processing") -            delfiles = archive.get_delete_files() +            delfiles = archive.items()              self.log_debug("Would delete: " + ", ".join(delfiles))              if self.get_config('delete'): @@ -476,7 +473,7 @@ class ExtractArchive(Addon):                  deltotrash = self.get_config('deltotrash')                  for f in delfiles:                      file = fs_encode(f) -                    if not os.path.exists(file): +                    if not exists(file):                          continue                      if not deltotrash: diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py index 08b1bad0c..020939805 100644 --- a/module/plugins/hooks/IRCInterface.py +++ b/module/plugins/hooks/IRCInterface.py @@ -18,7 +18,7 @@ from module.utils import formatSize  class IRCInterface(Thread, Addon):      __name__    = "IRCInterface"      __type__    = "hook" -    __version__ = "0.15" +    __version__ = "0.16"      __status__  = "testing"      __config__ = [("host"     , "str" , "IRC-Server Address"                           , "Enter your server here!"), @@ -40,7 +40,7 @@ class IRCInterface(Thread, Addon):      def __init__(self, core, manager):          Thread.__init__(self)          Addon.__init__(self, core, manager) -        self.set_daemon(True) +        self.setDaemon(True)      def activate(self): @@ -55,6 +55,7 @@ class IRCInterface(Thread, Addon):          try:              if self.get_config('info_pack'):                  self.response(_("Package finished: %s") % pypack.name) +          except Exception:              pass @@ -64,6 +65,7 @@ class IRCInterface(Thread, Addon):              if self.get_config('info_file'):                  self.response(                      _("Download finished: %(name)s @ %(plugin)s ") % {'name': pyfile.name, 'plugin': pyfile.pluginname}) +          except Exception:              pass @@ -177,6 +179,7 @@ class IRCInterface(Thread, Addon):              trigger = temp[0]              if len(temp) > 1:                  args = temp[1:] +          except Exception:              pass @@ -185,6 +188,7 @@ class IRCInterface(Thread, Addon):              res = handler(args)              for line in res:                  self.response(line, msg['origin']) +          except Exception, e:              self.log_error(e) diff --git a/module/plugins/hooks/ImageTyperz.py b/module/plugins/hooks/ImageTyperz.py index 42ab99027..85c22f1da 100644 --- a/module/plugins/hooks/ImageTyperz.py +++ b/module/plugins/hooks/ImageTyperz.py @@ -61,6 +61,7 @@ class ImageTyperz(Hook):          try:              balance = float(res) +          except Exception:              raise ImageTyperzException("Invalid response") diff --git a/module/plugins/hooks/SkipRev.py b/module/plugins/hooks/SkipRev.py index a1ddc3094..5f9cfa452 100644 --- a/module/plugins/hooks/SkipRev.py +++ b/module/plugins/hooks/SkipRev.py @@ -2,7 +2,6 @@  import re  import urllib -import urlparse  from types import MethodType @@ -13,7 +12,7 @@ from module.plugins.internal.Addon import Addon  class SkipRev(Addon):      __name__    = "SkipRev"      __type__    = "hook" -    __version__ = "0.33" +    __version__ = "0.34"      __status__  = "testing"      __config__ = [("mode"     , "Auto;Manual", "Choose recovery archives to skip"               , "Auto"), @@ -24,13 +23,6 @@ class SkipRev(Addon):      __authors__     = [("Walter Purcaro", "vuolter@gmail.com")] -    @staticmethod -    def _init(self): -        self.pyfile.plugin._init() -        if self.pyfile.hasStatus("skipped"): -            self.skip(self.pyfile.statusname or self.pyfile.pluginname) - -      def _name(self, pyfile):          return pyfile.pluginclass.get_info(pyfile.url)['name'] @@ -68,11 +60,6 @@ class SkipRev(Addon):          pyfile.setCustomStatus("SkipRev", "skipped") -        if not hasattr(pyfile.plugin, "_init"): -            #: Work-around: inject status checker inside the preprocessing routine of the plugin -            pyfile.plugin._init = pyfile.plugin.init -            pyfile.plugin.init  = MethodType(self._init, pyfile.plugin) -      def download_failed(self, pyfile):          #: Check if pyfile is still "failed", maybe might has been restarted in meantime diff --git a/module/plugins/hooks/TransmissionRPC.py b/module/plugins/hooks/TransmissionRPC.py new file mode 100644 index 000000000..715f82edb --- /dev/null +++ b/module/plugins/hooks/TransmissionRPC.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +import random +import re + +import pycurl + +from module.common.json_layer import json_loads, json_dumps +from module.network.HTTPRequest import BadHeader +from module.network.RequestFactory import getRequest as get_request +from module.plugins.internal.Addon import Addon + + +class TransmissionRPC(Addon): +    __name__    = "TransmissionRPC" +    __type__    = "hook" +    __version__ = "0.12" +    __status__  = "testing" + +    __pattern__ = r"https?://.+\.torrent|magnet:\?.+" +    __config__  = [("rpc_url", "str", "Transmission RPC URL", "http://127.0.0.1:9091/transmission/rpc")] + +    __description__ = """Send torrent and magnet URLs to Transmission Bittorent daemon via RPC""" +    __license__     = "GPLv3" +    __authors__     = [("GammaC0de", None)] + + +    def init(self): +        self.event_map = {'linksAdded': "links_added"} + + +    def links_added(self, links, pid): +        pattern = re.compile(self.__pattern__) +        urls = [link for link in links if pattern.match(link)] + +        for url in urls: +            self.log_debug("Sending link: %s" % url) +            self.send_to_transmission(url) +            links.remove(url) + + +    def send_to_transmission(self, url): +        transmission_rpc_url = self.get_config('rpc_url') +        client_request_id = self.__name__ + "".join(random.choice('0123456789ABCDEF') for _i in xrange(4)) +        req = get_request() + +        try: +            response = self.load(transmission_rpc_url, +                                 post=json_dumps({'arguments': {'filename': url}, +                                                  'method'   : 'torrent-add', +                                                  'tag'      : client_request_id}), +                                 req=req) + +        except BadHeader, e: +            if e.code == 409: +                headers = dict(re.findall(r"(?P<name>.+?): (?P<value>.+?)\r?\n", req.header)) +                session_id = headers['X-Transmission-Session-Id'] +                req.c.setopt(pycurl.HTTPHEADER, ["X-Transmission-Session-Id: %s" % session_id]) +                try: +                    response = self.load(transmission_rpc_url, +                                         post=json_dumps({'arguments': {'filename': url}, +                                                          'method'   : 'torrent-add', +                                                          'tag'      : client_request_id}), +                                         req=req) + +                except Exception, e: +                     self.log_error(e) +                     return + +            else: +                 self.log_error(e) +                 return + +        except Exception, e: +             self.log_error(e) +             return + +        try: +            res = json_loads(response) +            if "result" in res: +                self.log_debug("Result: %s" % res['result']) + +        except Exception, e: +            self.log_error(e) diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py index 7567a31a3..9b9c7f0ad 100644 --- a/module/plugins/hooks/XFileSharingPro.py +++ b/module/plugins/hooks/XFileSharingPro.py @@ -29,18 +29,20 @@ class XFileSharingPro(Hook):                                r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:user|folder)s?/\w+')}      HOSTER_BUILTIN  = [#WORKING HOSTERS: -                       "ani-stream.com", "backin.net", "cloudsix.me", "eyesfile.ca", "file4safe.com", -                       "fileband.com", "filedwon.com", "fileparadox.in", "filevice.com", -                       "hostingbulk.com", "junkyvideo.com", "linestorage.com", "ravishare.com", +                       "ani-stream.com", "backin.net", "cloudsix.me", "eyesfile.ca", +                       "file4safe.com", "fileband.com", "filedwon.com", "fileparadox.in", +                       "filevice.com", "hostingbulk.com", "junkyvideo.com", "ravishare.com",                         "ryushare.com", "salefiles.com", "sendmyway.com", "sharebeast.com", -                       "sharesix.com", "thefile.me", "verzend.be", "worldbytez.com", "xvidstage.com", +                       "sharesix.com", "thefile.me", "verzend.be", "worldbytez.com", +                       "xvidstage.com",                         #: NOT TESTED:                         "101shared.com", "4upfiles.com", "filemaze.ws", "filenuke.com",                         "linkzhost.com", "mightyupload.com", "rockdizfile.com", "sharerepo.com",                         "shareswift.com", "uploadbaz.com", "uploadc.com", "vidbull.com",                         "zalaa.com", "zomgupload.com",                         #: NOT WORKING: -                       "amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", "laoupload.com", "rd-fs.com"] +                       "amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", +                       "laoupload.com", "rd-fs.com"]      CRYPTER_BUILTIN = ["junocloud.me", "rapidfileshare.net"] diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py index 50dd40774..77e20cdd4 100644 --- a/module/plugins/hooks/XMPPInterface.py +++ b/module/plugins/hooks/XMPPInterface.py @@ -70,6 +70,7 @@ class XMPPInterface(IRCInterface, JabberClient):          try:              if self.get_config('info_pack'):                  self.announce(_("Package finished: %s") % pypack.name) +          except Exception:              pass @@ -79,6 +80,7 @@ class XMPPInterface(IRCInterface, JabberClient):              if self.get_config('info_file'):                  self.announce(                      _("Download finished: %(name)s @ %(plugin)s") % {'name': pyfile.name, 'plugin': pyfile.pluginname}) +          except Exception:              pass @@ -88,6 +90,7 @@ class XMPPInterface(IRCInterface, JabberClient):          self.connect()          try:              self.loop() +          except Exception, ex:              self.log_error(ex) @@ -159,6 +162,7 @@ class XMPPInterface(IRCInterface, JabberClient):                  trigger = temp[0]                  if len(temp) > 1:                      args = temp[1:] +              except Exception:                  pass @@ -174,6 +178,7 @@ class XMPPInterface(IRCInterface, JabberClient):                          body=line)                      messages.append(m) +              except Exception, e:                  self.log_error(e) diff --git a/module/plugins/hoster/BasePlugin.py b/module/plugins/hoster/BasePlugin.py index 2e9ae4e48..d64834a7c 100644 --- a/module/plugins/hoster/BasePlugin.py +++ b/module/plugins/hoster/BasePlugin.py @@ -23,18 +23,6 @@ class BasePlugin(Hoster):                         ("Walter Purcaro", "vuolter@gmail.com")] -    @classmethod -    def get_info(cls, url="", html=""):  #@TODO: Move to hoster class in 0.4.10 -        url   = urllib.unquote(url) -        url_p = urlparse.urlparse(url) -        return {'name'  : (url_p.path.split('/')[-1] -                           or url_p.query.split('=', 1)[::-1][0].split('&', 1)[0] -                           or url_p.netloc.split('.', 1)[0]), -                'size'  : 0, -                'status': 3 if url else 8, -                'url'   : url} - -      def setup(self):          self.chunk_limit     = -1          self.multiDL        = True @@ -95,6 +83,7 @@ class BasePlugin(Hoster):          try:              errmsg += " | " + self.last_check.group(1).strip() +          except Exception:              pass diff --git a/module/plugins/hoster/CloudzillaTo.py b/module/plugins/hoster/CloudzillaTo.py index 60c66960d..d9466c954 100644 --- a/module/plugins/hoster/CloudzillaTo.py +++ b/module/plugins/hoster/CloudzillaTo.py @@ -8,7 +8,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo  class CloudzillaTo(SimpleHoster):      __name__    = "CloudzillaTo"      __type__    = "hoster" -    __version__ = "0.08" +    __version__ = "0.09"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?cloudzilla\.to/share/file/(?P<ID>[\w^_]+)' @@ -34,7 +34,7 @@ class CloudzillaTo(SimpleHoster):                  self.fail(_("Missing password"))          if re.search(self.PASSWORD_PATTERN, self.html): -            self.retry(reason="Wrong password") +            self.retry(msg="Wrong password")          else:              return super(CloudzillaTo, self).check_errors() @@ -49,7 +49,7 @@ class CloudzillaTo(SimpleHoster):          if 'error' in ticket:              if "File is password protected" in ticket['error']: -                self.retry(reason="Wrong password") +                self.retry(msg="Wrong password")              else:                  self.fail(ticket['error']) diff --git a/module/plugins/hoster/CzshareCom.py b/module/plugins/hoster/CzshareCom.py index 3d2de5f7f..6afd9fa2d 100644 --- a/module/plugins/hoster/CzshareCom.py +++ b/module/plugins/hoster/CzshareCom.py @@ -58,6 +58,7 @@ class CzshareCom(SimpleHoster):              if credit < self.pyfile.size:                  self.log_info(_("Not enough credit to download file: %s") % self.pyfile.name)                  return False +          except Exception, e:              #: let's continue and see what happens...              self.log_error(e) @@ -70,6 +71,7 @@ class CzshareCom(SimpleHoster):          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) diff --git a/module/plugins/hoster/EuroshareEu.py b/module/plugins/hoster/EuroshareEu.py index 53ac9ff06..70df8e354 100644 --- a/module/plugins/hoster/EuroshareEu.py +++ b/module/plugins/hoster/EuroshareEu.py @@ -8,7 +8,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo  class EuroshareEu(SimpleHoster):      __name__    = "EuroshareEu"      __type__    = "hoster" -    __version__ = "0.30" +    __version__ = "0.31"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?euroshare\.(eu|sk|cz|hu|pl)/file/.+' @@ -33,7 +33,7 @@ class EuroshareEu(SimpleHoster):      def handle_premium(self, pyfile):          if self.ERROR_PATTERN in self.html:              self.account.relogin(self.user) -            self.retry(reason=_("User not logged in")) +            self.retry(msg=_("User not logged in"))          self.link = pyfile.url.rstrip('/') + "/download/" @@ -42,7 +42,7 @@ class EuroshareEu(SimpleHoster):          if check == "login" or (check == "json" and self.last_check.group(1) == "Access token expired"):              self.account.relogin(self.user) -            self.retry(reason=_("Access token expired")) +            self.retry(msg=_("Access token expired"))          elif check == "json":              self.fail(self.last_check.group(1)) diff --git a/module/plugins/hoster/FastixRu.py b/module/plugins/hoster/FastixRu.py index 0019cf3c2..f00dded3f 100644 --- a/module/plugins/hoster/FastixRu.py +++ b/module/plugins/hoster/FastixRu.py @@ -10,7 +10,7 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo  class FastixRu(MultiHoster):      __name__    = "FastixRu"      __type__    = "hoster" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?fastix\.(ru|it)/file/\w{24}' @@ -27,13 +27,11 @@ class FastixRu(MultiHoster):      def handle_premium(self, pyfile): -        api_key = self.account.get_data(self.user) -        api_key = api_key['api'] - -        self.html = self.load("http://fastix.ru/api_v2/", -                         get={'apikey': api_key, 'sub': "getdirectlink", 'link': pyfile.url}) - -        data = json_loads(self.html) +        self.html = json_loads(self.load("http://fastix.ru/api_v2/", +                                         get={'apikey': self.account.get_data()['apikey'], +                                              'sub'   : "getdirectlink", +                                              'link'  : pyfile.url}) +        data = self.html)          self.log_debug("Json data", data) diff --git a/module/plugins/hoster/FastshareCz.py b/module/plugins/hoster/FastshareCz.py index 485d69d15..62cf3889b 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.32" +    __version__ = "0.33"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?fastshare\.cz/\d+/.+' @@ -70,7 +70,7 @@ class FastshareCz(SimpleHoster):              self.retry(6, 10 * 60, _("Paralell download"))          elif check == "wrong captcha": -            self.retry(max_tries=5, reason=_("Wrong captcha")) +            self.retry(max_tries=5, msg=_("Wrong captcha"))          elif check == "credit":              self.restart(nopremium=True) diff --git a/module/plugins/hoster/FileSharkPl.py b/module/plugins/hoster/FileSharkPl.py index 978861dd6..94e2d25ab 100644 --- a/module/plugins/hoster/FileSharkPl.py +++ b/module/plugins/hoster/FileSharkPl.py @@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo  class FileSharkPl(SimpleHoster):      __name__    = "FileSharkPl"      __type__    = "hoster" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?fileshark\.pl/pobierz/\d+/\w+' @@ -92,13 +92,13 @@ class FileSharkPl(SimpleHoster):          m = re.search(self.TOKEN_PATTERN, self.html)          if m is None: -            self.retry(reason=_("Captcha form not found")) +            self.retry(msg=_("Captcha form not found"))          inputs['form[_token]'] = m.group(1)          m = re.search(self.CAPTCHA_PATTERN, self.html)          if m is None: -            self.retry(reason=_("Captcha image not found")) +            self.retry(msg=_("Captcha image not found"))          inputs['form[captcha]'] = self.captcha._decrypt(m.group(1).decode('base64'), input_type='jpeg')          inputs['form[start]'] = "" diff --git a/module/plugins/hoster/FileboomMe.py b/module/plugins/hoster/FileboomMe.py index 3c11f1d16..4328565f4 100644 --- a/module/plugins/hoster/FileboomMe.py +++ b/module/plugins/hoster/FileboomMe.py @@ -1,8 +1,7 @@  # -*- coding: utf-8 -*-  import re - -from urlparse import urljoin +import urlparse  from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo @@ -37,7 +36,7 @@ class FileboomMe(SimpleHoster):      def handle_free(self, pyfile): -        post_url = urljoin(pyfile.url, "file/" + self.info['pattern']['ID']) +        post_url = urlparse.urljoin(pyfile.url, "file/" + self.info['pattern']['ID'])          m = re.search(r'data-slow-id="(\w+)"', self.html)          if m: @@ -46,7 +45,7 @@ class FileboomMe(SimpleHoster):              m = re.search(self.LINK_PATTERN, self.html)              if m: -                self.link = urljoin(pyfile.url, m.group(0)) +                self.link = urlparse.urljoin(pyfile.url, m.group(0))              else:                  for _i in xrange(5): @@ -56,7 +55,7 @@ class FileboomMe(SimpleHoster):                          m = re.search(self.CAPTCHA_PATTERN, self.html)                          if m: -                            captcha = self.captcha.decrypt(urljoin(pyfile.url, m.group(1))) +                            captcha = self.captcha.decrypt(urlparse.urljoin(pyfile.url, m.group(1)))                              self.html = self.load(post_url,                                                    post={'CaptchaForm[code]'  : captcha, @@ -76,7 +75,7 @@ class FileboomMe(SimpleHoster):                                  m = re.search(self.LINK_PATTERN, self.html)                                  if m: -                                    self.link = urljoin(pyfile.url, m.group(0)) +                                    self.link = urlparse.urljoin(pyfile.url, m.group(0))                                  else:                                      self.captcha.invalid() diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index 325b4bb27..b13a7c793 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -1,7 +1,6 @@  # -*- coding: utf-8 -*-  import re -import urlparse  from module.network.RequestFactory import getURL as get_url  from module.plugins.internal.SimpleHoster import SimpleHoster, parse_fileInfo @@ -20,7 +19,7 @@ def get_info(urls):  class FilefactoryCom(SimpleHoster):      __name__    = "FilefactoryCom"      __type__    = "hoster" -    __version__ = "0.57" +    __version__ = "0.58"      __status__  = "testing"      __pattern__ = r'https?://(?:www\.)?filefactory\.com/(file|trafficshare/\w+)/\w+' @@ -66,7 +65,7 @@ class FilefactoryCom(SimpleHoster):          if check == "multiple":              self.log_debug("Parallel downloads detected; waiting 15 minutes") -            self.retry(wait_time=15 * 60, reason=_("Parallel downloads")) +            self.retry(wait_time=15 * 60, msg=_("Parallel downloads"))          elif check == "error":              self.error(_("Unknown error")) diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py index f8c41f4d1..af755e0a6 100644 --- a/module/plugins/hoster/FilerNet.py +++ b/module/plugins/hoster/FilerNet.py @@ -6,7 +6,6 @@  import pycurl  import re -import urlparse  from module.plugins.captcha.ReCaptcha import ReCaptcha  from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo diff --git a/module/plugins/hoster/FilesMailRu.py b/module/plugins/hoster/FilesMailRu.py index a6dd56152..a1c30be7b 100644 --- a/module/plugins/hoster/FilesMailRu.py +++ b/module/plugins/hoster/FilesMailRu.py @@ -21,6 +21,7 @@ def get_info(urls):                      url_pattern = '<a href="(.+?)" onclick="return Act\(this\, \'dlink\'\, event\)">(.+?)</a>'                      file_name = re.search(url_pattern, html).group(0).split(', event)">')[1].split('</a>')[0]                      result.append((file_name, 0, 2, url)) +                  except Exception:                      pass diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py index a74589cff..c35fab3fc 100644 --- a/module/plugins/hoster/FileserveCom.py +++ b/module/plugins/hoster/FileserveCom.py @@ -24,6 +24,7 @@ def check_file(plugin, urls):                      parse_size(cols[2]) if cols[2] != '--' else 0,                      2 if cols[3].startswith('Available') else 1,                      cols[0])) +          except Exception, e:              continue @@ -33,7 +34,7 @@ def check_file(plugin, urls):  class FileserveCom(Hoster):      __name__    = "FileserveCom"      __type__    = "hoster" -    __version__ = "0.58" +    __version__ = "0.59"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?fileserve\.com/file/(?P<ID>[^/]+)' @@ -94,7 +95,7 @@ class FileserveCom(Hoster):              elif action['fail'] == "parallelDownload":                  self.log_warning(_("Parallel download error, now waiting 60s")) -                self.retry(wait_time=60, reason=_("parallelDownload")) +                self.retry(wait_time=60, msg=_("parallelDownload"))              else:                  self.fail(_("Download check returned: %s") % action['fail']) @@ -206,7 +207,7 @@ class FileserveCom(Hoster):          if not premium_url and self.check_download({'login': re.compile(self.NOT_LOGGED_IN_PATTERN)}):              self.account.relogin(self.user) -            self.retry(reason=_("Not logged in")) +            self.retry(msg=_("Not logged in"))  def get_info(urls): diff --git a/module/plugins/hoster/FourSharedCom.py b/module/plugins/hoster/FourSharedCom.py index e5b309dc1..212eadb3b 100644 --- a/module/plugins/hoster/FourSharedCom.py +++ b/module/plugins/hoster/FourSharedCom.py @@ -55,6 +55,7 @@ class FourSharedCom(SimpleHoster):              m = re.search(self.ID_PATTERN, self.html)              res = self.load('http://www.4shared.com/web/d2/getFreeDownloadLimitInfo?fileId=%s' % m.group(1))              self.log_debug(res) +          except Exception:              pass diff --git a/module/plugins/hoster/Ftp.py b/module/plugins/hoster/Ftp.py index 25eb44604..c9f5fa6b6 100644 --- a/module/plugins/hoster/Ftp.py +++ b/module/plugins/hoster/Ftp.py @@ -35,6 +35,7 @@ class Ftp(Hoster):          pyfile.name = parsed_url.path.rpartition('/')[2]          try:              pyfile.name = urllib.unquote(str(pyfile.name)).decode('utf8') +          except Exception:              pass @@ -63,16 +64,22 @@ class Ftp(Hoster):          if m:              pyfile.size = int(m.group(1))              self.download(pyfile.url) +          else:              #: Naive ftp directory listing              if re.search(r'^25\d.*?"', self.req.http.header, re.M):                  pyfile.url = pyfile.url.rstrip('/')                  pkgname = "/".join([pyfile.package().name, urlparse.urlparse(pyfile.url).path.rpartition('/')[2]]) +                  pyfile.url += '/' +                  self.req.http.c.setopt(48, 1)  #: CURLOPT_DIRLISTONLY                  res = self.load(pyfile.url, decode=False) +                  links = [pyfile.url + x for x in res.splitlines()]                  self.log_debug("LINKS", links) +                  self.pyload.api.addPackage(pkgname, links) +              else:                  self.fail(_("Unexpected server response")) diff --git a/module/plugins/hoster/GoogledriveCom.py b/module/plugins/hoster/GoogledriveCom.py index 903b5361e..381bd24dc 100644 --- a/module/plugins/hoster/GoogledriveCom.py +++ b/module/plugins/hoster/GoogledriveCom.py @@ -44,11 +44,9 @@ class GoogledriveCom(SimpleHoster):                  self.error(_("Free download link not found"))              else: -                link = html_unescape(m.group(1).decode('unicode-escape')) -                if not urlparse.urlparse(link).scheme: -                    link = urlparse.urljoin("https://docs.google.com/", link) - +                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: diff --git a/module/plugins/hoster/HellshareCz.py b/module/plugins/hoster/HellshareCz.py index eab819ad9..012b6be63 100644 --- a/module/plugins/hoster/HellshareCz.py +++ b/module/plugins/hoster/HellshareCz.py @@ -1,7 +1,5 @@  # -*- coding: utf-8 -*- -import urlparse -  from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo diff --git a/module/plugins/hoster/HighWayMe.py b/module/plugins/hoster/HighWayMe.py index 119ddb70e..f8dc27eec 100644 --- a/module/plugins/hoster/HighWayMe.py +++ b/module/plugins/hoster/HighWayMe.py @@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import seconds_to_midnight  class HighWayMe(MultiHoster):      __name__    = "HighWayMe"      __type__    = "hoster" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __pattern__ = r'https?://.+high-way\.my' @@ -39,7 +39,7 @@ class HighWayMe(MultiHoster):          elif "trafficlimit" in self.html:              self.log_warning(_("Reached daily limit")) -            self.retry(wait_time=seconds_to_midnight(gmt=2), reason="Daily limit for this host reached") +            self.retry(wait_time=seconds_to_midnight(gmt=2), 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/Keep2ShareCc.py b/module/plugins/hoster/Keep2ShareCc.py index bf4b157cb..b8275e84b 100644 --- a/module/plugins/hoster/Keep2ShareCc.py +++ b/module/plugins/hoster/Keep2ShareCc.py @@ -10,7 +10,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo  class Keep2ShareCc(SimpleHoster):      __name__    = "Keep2ShareCc"      __type__    = "hoster" -    __version__ = "0.24" +    __version__ = "0.25"      __status__  = "testing"      __pattern__ = r'https?://(?:www\.)?(keep2share|k2s|keep2s)\.cc/file/(?P<ID>\w+)' @@ -45,7 +45,7 @@ class Keep2ShareCc(SimpleHoster):          if m:              self.info['error'] = m.group(1)              self.wantReconnect = True -            self.retry(wait_time=30 * 60, reason=m.group(0)) +            self.retry(wait_time=30 * 60, msg=m.group(0))          m = re.search(self.ERROR_PATTERN, self.html)          if m: @@ -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(wait_time=wait_time, reason="Please wait to download this file") +            self.retry(wait_time=wait_time, msg="Please wait to download this file")          self.info.pop('error', None) diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py index 788c1aca8..5d9bf52c0 100644 --- a/module/plugins/hoster/LuckyShareNet.py +++ b/module/plugins/hoster/LuckyShareNet.py @@ -10,7 +10,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo  class LuckyShareNet(SimpleHoster):      __name__    = "LuckyShareNet"      __type__    = "hoster" -    __version__ = "0.08" +    __version__ = "0.09"      __status__  = "testing"      __pattern__ = r'https?://(?:www\.)?luckyshare\.net/(?P<ID>\d{10,})' @@ -36,7 +36,7 @@ class LuckyShareNet(SimpleHoster):              else:                  self.error(_("Unable to detect wait time between free downloads"))          elif 'Hash expired' in rep: -            self.retry(reason=_("Hash expired")) +            self.retry(msg=_("Hash expired"))          return json_loads(rep) diff --git a/module/plugins/hoster/MegaRapidCz.py b/module/plugins/hoster/MegaRapidCz.py index 13f462585..4d6d0171a 100644 --- a/module/plugins/hoster/MegaRapidCz.py +++ b/module/plugins/hoster/MegaRapidCz.py @@ -22,7 +22,7 @@ def get_info(urls):  class MegaRapidCz(SimpleHoster):      __name__    = "MegaRapidCz"      __type__    = "hoster" -    __version__ = "0.57" +    __version__ = "0.58"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?(share|mega)rapid\.cz/soubor/\d+/.+' @@ -59,7 +59,7 @@ class MegaRapidCz(SimpleHoster):          else:              if re.search(self.ERR_LOGIN_PATTERN, self.html):                  self.relogin(self.user) -                self.retry(wait_time=60, reason=_("User login failed")) +                self.retry(wait_time=60, msg=_("User login failed"))              elif re.search(self.ERR_CREDIT_PATTERN, self.html):                  self.fail(_("Not enough credit left")) diff --git a/module/plugins/hoster/MegasharesCom.py b/module/plugins/hoster/MegasharesCom.py index b6692263f..8b87dbd68 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.29" +    __version__ = "0.30"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?(d\d{2}\.)?megashares\.com/((index\.php)?\?d\d{2}=|dl/)\w+' @@ -82,7 +82,7 @@ class MegasharesCom(SimpleHoster):              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(wait_time=renew, reason=_("Passport renewal")) +            self.retry(wait_time=renew, msg=_("Passport renewal"))          #: Check traffic left on passport          m = re.search(self.PASSPORT_LEFT_PATTERN, self.html, re.M | re.S) @@ -94,7 +94,7 @@ 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(wait_time=600, reason=_("Passport renewal")) +            self.retry(wait_time=600, msg=_("Passport renewal"))          self.handle_download(False) diff --git a/module/plugins/hoster/NowDownloadSx.py b/module/plugins/hoster/NowDownloadSx.py index 876a7bcb5..e03ec2789 100644 --- a/module/plugins/hoster/NowDownloadSx.py +++ b/module/plugins/hoster/NowDownloadSx.py @@ -29,7 +29,7 @@ class NowDownloadSx(SimpleHoster):      WAIT_PATTERN = r'\.countdown\(\{until: \+(\d+),'      LINK_FREE_PATTERN = r'(http://s\d+(?:\.coolcdn\.info|\.mighycdndelivery\.com)/nowdownload/.+?)["\']' -    NAME_REPLACEMENTS = [("&#?\w+;", fixup), (r'<.*?>', '')] +    NAME_REPLACEMENTS = [(r'<.*?>', '')]      def setup(self): diff --git a/module/plugins/hoster/OboomCom.py b/module/plugins/hoster/OboomCom.py index 8420c6f02..1ee342de5 100644 --- a/module/plugins/hoster/OboomCom.py +++ b/module/plugins/hoster/OboomCom.py @@ -13,7 +13,7 @@ from module.plugins.captcha.ReCaptcha import ReCaptcha  class OboomCom(Hoster):      __name__    = "OboomCom"      __type__    = "hoster" -    __version__ = "0.36" +    __version__ = "0.37"      __status__  = "testing"      __pattern__ = r'https?://(?:www\.)?oboom\.com/(?:#(?:id=|/)?)?(?P<ID>\w{8})' @@ -141,6 +141,6 @@ class OboomCom(Hoster):              self.download_domain = result[1]              self.download_ticket = result[2]          elif result[0] == 421: -            self.retry(wait_time=result[2] + 60, reason=_("Connection limit exceeded")) +            self.retry(wait_time=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 cba67b26c..70229a6ef 100644 --- a/module/plugins/hoster/OneFichierCom.py +++ b/module/plugins/hoster/OneFichierCom.py @@ -2,13 +2,14 @@  import re +from module.network.RequestFactory import getURL as get_url  from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo  class OneFichierCom(SimpleHoster):      __name__    = "OneFichierCom"      __type__    = "hoster" -    __version__ = "0.88" +    __version__ = "0.90"      __status__  = "testing"      __pattern__ = r'https?://(?:www\.)?(?:(?P<ID1>\w+)\.)?(?P<HOST>1fichier\.com|alterupload\.com|cjoint\.net|d(es)?fichiers\.com|dl4free\.com|megadl\.fr|mesfichiers\.org|piecejointe\.net|pjointe\.com|tenvoi\.com)(?:/\?(?P<ID2>\w+))?' @@ -28,6 +29,8 @@ class OneFichierCom(SimpleHoster):      COOKIES     = [("1fichier.com", "LG", "en")] +    DIRECT_LINK = True +      NAME_PATTERN    = r'>File\s*Name :</td>\s*<td.*>(?P<N>.+?)<'      SIZE_PATTERN    = r'>Size :</td>\s*<td.*>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'      OFFLINE_PATTERN = r'File not found !\s*<' @@ -40,7 +43,61 @@ class OneFichierCom(SimpleHoster):          self.resume_download = True +    @classmethod +    def get_info(cls, url="", html=""): +        redirect = url +        for i in xrange(10): +            try: +                headers = dict(re.findall(r"(?P<name>.+?): (?P<value>.+?)\r?\n", get_url(redirect, just_header=True).lower())) +                if 'location' in headers and headers['location']: +                    redirect = headers['location'] +                else: +                    if 'content-type' in headers and headers['content-type'] == "application/octet-stream": +                        if "filename=" in headers.get('content-disposition'): +                            name = dict(_i.split("=") for _i in map(str.strip, headers['content-disposition'].split(";"))[1:])['filename'].strip("\"'") +                        else: +                            name = url + +                        info = {'name'  : name, +                                'size'  : long(headers.get('content-length')), +                                'status': 3, +                                'url'   : url} + +                    else: +                        info = super(OneFichierCom, cls).get_info(url, html) + +                    break + +            except Exception, e: +                info = {'status' : 8, +                        'error'  : e.message} + +        else: +            info = {'status' : 8, +                    'error'    : _("Too many redirects")} + +        return info + + +    def handle_direct(self, pyfile): +        redirect = pyfile.url +        for i in xrange(self.get_config("maxredirs", plugin="UserAgentSwitcher")): + +            headers = self.load(redirect, just_header=True) +            if 'location' in headers and headers['location']: +                self.log_debug("Redirect #%d to: %s" % (i, redirect)) +                redirect = headers['location'] +            else: +                if 'content-type' in headers and headers['content-type'] == "application/octet-stream": +                    self.link = pyfile.url +                break +        else: +            self.fail(_("Too many redirects")) + +      def handle_free(self, pyfile): +        self.check_errors() +          id = self.info['pattern']['ID1'] or self.info['pattern']['ID2']          url, inputs = self.parse_html_form('action="https://1fichier.com/\?%s' % id) diff --git a/module/plugins/hoster/OpenloadIo.py b/module/plugins/hoster/OpenloadIo.py index c46462344..f5d677bb2 100644 --- a/module/plugins/hoster/OpenloadIo.py +++ b/module/plugins/hoster/OpenloadIo.py @@ -1,31 +1,72 @@  # -*- coding: utf-8 -*- +import json +import re +from time import sleep  from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.network.RequestFactory import getURL  class OpenloadIo(SimpleHoster):      __name__    = "OpenloadIo"      __type__    = "hoster" -    __version__ = "0.04" +    __version__ = "0.06"      __status__  = "testing" -    __pattern__ = r'https?://(?:www\.)?openload\.io/f/[\w_-]{11}' +    _FILE_ID_PATTERN = '/f/([\w\-_]+)/?' +    __pattern__ = r'https?://(?:www\.)?openload\.(?:co|io)' + _FILE_ID_PATTERN -    __description__ = """Openload.io hoster plugin""" +    __description__ = """Openload.co hoster plugin"""      __license__     = "GPLv3"      __authors__     = [(None, None)] -    NAME_PATTERN    = r'<span id="filename">(?P<N>.+?)</' -    SIZE_PATTERN    = r'<span class="count">(?P<S>[\d.,]+) (?P<U>[\w^_]+)<' -    OFFLINE_PATTERN = r">(We can't find the file you are looking for)" - -    LINK_FREE_PATTERN = r'id="real\w*download"><a href="(https?://[\w\.]+\.openload\.io/dl/.*?)"' +    # The API reference, that this implementation uses is available at https://openload.co/api +    _API_BASE_URL = 'https://api.openload.co/1' +    _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}'      def setup(self): -        self.multiDL = True +        self.multiDL     = True          self.chunk_limit = 1 +    @classmethod +    def get_info(cls, url="", html=""): +        file_id = re.findall(cls._FILE_ID_PATTERN, url, re.I) +        if not file_id: +            return super(OpenloadIo, cls).get_info(url) + +        file_id = file_id[0] +        info_json = cls._load_json(cls._FILE_INFO_URI_PATTERN.format(file_id)) +        file_info = info_json['result'][file_id] +        return {'name': file_info['name'], +                'size': file_info['size'], +                'status': 3 if url.strip() else 8, +                'url': url} + + +    def handle_free(self, pyfile): +        # If the link is being handled here, then it matches the file_id_pattern, +        # therefore, we can call [0] safely. +        file_id = re.findall(self._FILE_ID_PATTERN, pyfile.url, re.I)[0] + +        ticket_json = self._load_json(self._DOWNLOAD_TICKET_URI_PATTERN.format(file_id)) + +        wait_time = ticket_json['result']['wait_time'] +        sleep(wait_time + 0.1) + +        ticket = ticket_json['result']['ticket'] + +        download_json = self._load_json(self._DOWNLOAD_FILE_URI_PATTERN.format(file_id, ticket)) +        self.link = download_json['result']['url'] + + +    @classmethod +    def _load_json(cls, uri): +        return json.loads( +            getURL(cls._API_BASE_URL + uri)) +  getInfo = create_getInfo(OpenloadIo) diff --git a/module/plugins/hoster/PremiumizeMe.py b/module/plugins/hoster/PremiumizeMe.py index d968eccec..e682a5a4c 100644 --- a/module/plugins/hoster/PremiumizeMe.py +++ b/module/plugins/hoster/PremiumizeMe.py @@ -7,7 +7,7 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo  class PremiumizeMe(MultiHoster):      __name__    = "PremiumizeMe"      __type__    = "hoster" -    __version__ = "0.20" +    __version__ = "0.21"      __status__  = "testing"      __pattern__ = r'^unmatchable$'  #: Since we want to allow the user to specify the list of hoster to use we let MultiHoster.activate @@ -44,6 +44,12 @@ class PremiumizeMe(MultiHoster):          status = data['status']          if status == 200: +            if 'filename' in data['result']: +                self.pyfile.name = data['result']['filename'] + +            if 'filesize' in data['result']: +                self.pyfile.size = data['result']['filesize'] +              self.link = data['result']['location']              return diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py index b5af3ea35..bba4bf6ad 100644 --- a/module/plugins/hoster/ShareonlineBiz.py +++ b/module/plugins/hoster/ShareonlineBiz.py @@ -3,7 +3,6 @@  import re  import time  import urllib -import urlparse  from module.network.RequestFactory import getURL as get_url  from module.plugins.captcha.ReCaptcha import ReCaptcha @@ -13,7 +12,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo  class ShareonlineBiz(SimpleHoster):      __name__    = "ShareonlineBiz"      __type__    = "hoster" -    __version__ = "0.55" +    __version__ = "0.56"      __status__  = "testing"      __pattern__ = r'https?://(?:www\.)?(share-online\.biz|egoshare\.com)/(download\.php\?id=|dl/)(?P<ID>\w+)' @@ -79,7 +78,7 @@ class ShareonlineBiz(SimpleHoster):                              post={'dl_free'                  : "1",                                    'recaptcha_challenge_field': challenge,                                    'recaptcha_response_field' : response}) -            if not res == "0": +            if res != "0":                  self.captcha.correct()                  return res              else: @@ -136,7 +135,7 @@ class ShareonlineBiz(SimpleHoster):          self.log_debug(dlinfo) -        if not dlinfo['status'] == "online": +        if dlinfo['status'] != "online":              self.offline()          else:              pyfile.name = dlinfo['name'] @@ -160,6 +159,7 @@ class ShareonlineBiz(SimpleHoster):          try:              self.log_error(errmsg, re.search(self.ERROR_PATTERN, self.html).group(1)) +          except Exception:              self.log_error(_("Unknown error occurred"), errmsg) @@ -170,7 +170,7 @@ class ShareonlineBiz(SimpleHoster):              self.fail(_("Premium account needed"))          elif errmsg in ("expired", "server"): -            self.retry(wait_time=600, reason=errmsg) +            self.retry(wait_time=600, msg=errmsg)          elif errmsg == "full":              self.retry(10, 600, _("Server is full")) @@ -181,7 +181,7 @@ class ShareonlineBiz(SimpleHoster):          else:              self.wantReconnect = True -            self.retry(wait_time=60, reason=errmsg) +            self.retry(wait_time=60, msg=errmsg)  getInfo = create_getInfo(ShareonlineBiz) diff --git a/module/plugins/hoster/SimplyPremiumCom.py b/module/plugins/hoster/SimplyPremiumCom.py index be1578bfb..be9b89f24 100644 --- a/module/plugins/hoster/SimplyPremiumCom.py +++ b/module/plugins/hoster/SimplyPremiumCom.py @@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import seconds_to_midnight  class SimplyPremiumCom(MultiHoster):      __name__    = "SimplyPremiumCom"      __type__    = "hoster" -    __version__ = "0.10" +    __version__ = "0.11"      __status__  = "testing"      __pattern__ = r'https?://.+simply-premium\.com' @@ -40,7 +40,7 @@ class SimplyPremiumCom(MultiHoster):          elif "trafficlimit" in self.html:              self.log_warning(_("Reached daily limit for this host")) -            self.retry(wait_time=seconds_to_midnight(gmt=2), reason="Daily limit for this host reached") +            self.retry(wait_time=seconds_to_midnight(gmt=2), 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/SpeedyshareCom.py b/module/plugins/hoster/SpeedyshareCom.py index 7d7a60f04..4a71c179d 100644 --- a/module/plugins/hoster/SpeedyshareCom.py +++ b/module/plugins/hoster/SpeedyshareCom.py @@ -4,7 +4,6 @@  # http://speedy.sh/ep2qY/Zapp-Brannigan.jpg  import re -import urlparse  from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py index b402433a4..ab96f65a1 100644 --- a/module/plugins/hoster/UlozTo.py +++ b/module/plugins/hoster/UlozTo.py @@ -15,7 +15,7 @@ def convert_decimal_prefix(m):  class UlozTo(SimpleHoster):      __name__    = "UlozTo"      __type__    = "hoster" -    __version__ = "1.13" +    __version__ = "1.15"      __status__  = "testing"      __pattern__ = r'http://(?:www\.)?(uloz\.to|ulozto\.(cz|sk|net)|bagruj\.cz|zachowajto\.pl)/(?:live/)?(?P<ID>\w+/[^/?]*)' @@ -26,8 +26,7 @@ class UlozTo(SimpleHoster):      __authors__     = [("zoidberg", "zoidberg@mujmail.cz")] -    INFO_PATTERN    = r'<p>File <strong>(?P<N>[^<]+)</strong> is password protected</p>' -    NAME_PATTERN    = r'<title>(?P<N>[^<]+) \| Uloz\.to</title>' +    NAME_PATTERN    = r'(<p>File <strong>|<title>)(?P<N>.+?)(<| \|)'      SIZE_PATTERN    = r'<span id="fileSize">.*?(?P<S>[\d.,]+\s[kMG]?B)</span>'      OFFLINE_PATTERN = r'<title>404 - Page not found</title>|<h1 class="h1">File (has been deleted|was banned)</h1>' @@ -68,7 +67,9 @@ class UlozTo(SimpleHoster):              #: New version - better to get new parameters (like captcha reload) because of image url - since 6.12.2013              self.log_debug('Using "new" version') -            xapca = self.load("http://www.ulozto.net/reloadXapca.php", get={'rnd': str(int(time.time()))}) +            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))              data = json_loads(xapca) @@ -121,7 +122,7 @@ class UlozTo(SimpleHoster):      def check_file(self):          check = self.check_download({ -            'wrong_captcha': re.compile(r'<ul class="error">\s*<li>Error rewriting the text.</li>'), +            'wrong_captcha': ">An error ocurred while verifying the user",              'offline'      : re.compile(self.OFFLINE_PATTERN),              'passwd'       : self.PASSWD_PATTERN,              'server_error' : 'src="http://img.ulozto.cz/error403/vykricnik.jpg"',  #: Paralell dl, server overload etc. @@ -130,7 +131,7 @@ class UlozTo(SimpleHoster):          if check == "wrong_captcha":              self.captcha.invalid() -            self.retry(reason=_("Wrong captcha code")) +            self.retry(msg=_("Wrong captcha code"))          elif check == "offline":              self.offline() diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py index 697f1febd..a3b9fbc2f 100644 --- a/module/plugins/hoster/UploadedTo.py +++ b/module/plugins/hoster/UploadedTo.py @@ -2,7 +2,6 @@  import re  import time -import urlparse  from module.network.RequestFactory import getURL as get_url  from module.plugins.captcha.ReCaptcha import ReCaptcha diff --git a/module/plugins/hoster/UserscloudCom.py b/module/plugins/hoster/UserscloudCom.py new file mode 100644 index 000000000..ebaed4859 --- /dev/null +++ b/module/plugins/hoster/UserscloudCom.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class UserscloudCom(SimpleHoster): +    __name__    = "UserscloudCom" +    __type__    = "hoster" +    __version__ = "0.01" +    __status__  = "testing" + +    __pattern__ = r'https?://(?:www\.)?userscloud\.com/\w{12}' + +    __description__ = """Userscloud.com hoster plugin""" +    __license__     = "GPLv3" +    __authors__     = [("GammaC0de", None)] + + +    NAME_PATTERN    = r'<h2 class="strong margin-none">(?P<N>.+?)<' +    SIZE_PATTERN    = r'<div class="ribbon">(?P<S>[\d.,]+) (?P<U>[\w^_]+)<' +    OFFLINE_PATTERN = r'The file you are trying to download is no longer available' + + +    def setup(self): +        self.multiDL         = True +        self.resume_download = False +        self.chunk_limit     = 1 + + +    def handle_free(self, pyfile): +        self.download(pyfile.url, +                      post=dict(re.findall(r'<input type="hidden" name="(.+?)" value="(.*?)">', self.html))) + + +getInfo = create_getInfo(UserscloudCom) diff --git a/module/plugins/hoster/YibaishiwuCom.py b/module/plugins/hoster/YibaishiwuCom.py index 0c1a028f8..b68e87ba6 100644 --- a/module/plugins/hoster/YibaishiwuCom.py +++ b/module/plugins/hoster/YibaishiwuCom.py @@ -52,8 +52,9 @@ class YibaishiwuCom(SimpleHoster):                  self.link = mr['url'].replace("\\", "")                  self.log_debug("Trying URL: " + self.link)                  break +              except Exception: -                continue +                pass          else:              self.fail(_("No working link found")) diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py index 86cca7cf1..5c7c13962 100644 --- a/module/plugins/hoster/YoutubeCom.py +++ b/module/plugins/hoster/YoutubeCom.py @@ -6,37 +6,17 @@ import subprocess  import urllib  from module.plugins.internal.Hoster import Hoster -from module.plugins.internal.Plugin import replace_patterns +from module.plugins.internal.Plugin import replace_patterns, which  from module.utils import html_unescape -def which(program): -    """ -    Works exactly like the unix command which -    Courtesy of http://stackoverflow.com/a/377028/675646 -    """ -    isExe = lambda x: os.path.isfile(x) and os.access(x, os.X_OK) - -    fpath, fname = os.path.split(program) - -    if fpath: -        if isExe(program): -            return program -    else: -        for path in os.environ['PATH'].split(os.pathsep): -            path = path.strip('"') -            exe_file = os.path.join(path, program) -            if isExe(exe_file): -                return exe_file - -  class YoutubeCom(Hoster):      __name__    = "YoutubeCom"      __type__    = "hoster" -    __version__ = "0.45" +    __version__ = "0.46"      __status__  = "testing" -    __pattern__ = r'https?://(?:[^/]*\.)?(youtube\.com|youtu\.be)/watch\?(?:.*&)?v=.+' +    __pattern__ = r'https?://(?:[^/]*\.)?(youtu\.be/|youtube\.com/watch\?(?:.*&)?v=)\w+'      __config__  = [("quality", "sd;hd;fullhd;240p;360p;480p;720p;1080p;3072p", "Quality Setting"             , "hd" ),                     ("fmt"    , "int"                                         , "FMT/ITAG Number (0 for auto)", 0    ),                     (".mp4"   , "bool"                                        , "Allow .mp4"                  , True ), @@ -51,7 +31,7 @@ class YoutubeCom(Hoster):                         ("zoidberg", "zoidberg@mujmail.cz")] -    URL_REPLACEMENTS = [(r'youtu\.be/', 'youtube.com/')] +    URL_REPLACEMENTS = [(r'youtu\.be/', 'youtube.com/watch?v=')]      #: Invalid characters that must be removed from the file name      invalid_chars = u'\u2605:?><"|\\' diff --git a/module/plugins/hoster/ZeveraCom.py b/module/plugins/hoster/ZeveraCom.py index ff3a43e6d..47286fca1 100644 --- a/module/plugins/hoster/ZeveraCom.py +++ b/module/plugins/hoster/ZeveraCom.py @@ -1,7 +1,6 @@  # -*- coding: utf-8 -*-  import re -import urlparse  from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo diff --git a/module/plugins/internal/Account.py b/module/plugins/internal/Account.py index 2713e8da4..de338cd33 100644 --- a/module/plugins/internal/Account.py +++ b/module/plugins/internal/Account.py @@ -13,7 +13,7 @@ from module.utils import compare_time, lock, parseFileSize as parse_size  class Account(Plugin):      __name__    = "Account"      __type__    = "account" -    __version__ = "0.17" +    __version__ = "0.18"      __status__  = "testing"      __description__ = """Base account plugin""" @@ -190,7 +190,7 @@ class Account(Plugin):      def get_info(self, user, reload=False):          """          Retrieve account infos for an user, do **not** overwrite this method!\\ -        just use it to retrieve infos in hoster plugins. see `parse_info` +        just use it to retrieve infos in hoster plugins. see `grab_info`          :param user: username          :param reload: reloads cached account information @@ -235,7 +235,7 @@ class Account(Plugin):          try:              self.req   = self.get_request(user) -            extra_info = self.parse_info(user, info['login']['password'], info, self.req) +            extra_info = self.grab_info(user, info['login']['password'], info, self.req)              if extra_info and isinstance(extra_info, dict):                  info['data'].update(extra_info) @@ -253,7 +253,7 @@ class Account(Plugin):              return info -    def parse_info(self, user, password, info, req): +    def grab_info(self, user, password, info, req):          """          This should be overwritten in account plugin          and retrieving account information for user @@ -270,8 +270,8 @@ class Account(Plugin):          return [self.getAccountData(user, *args, **kwargs) for user, info in self.info.items()] -    def login_fail(self, reason=_("Login handshake has failed")): -        return self.fail(reason) +    def fail_login(self, msg=_("Login handshake has failed")): +        return self.fail(msg)      def get_request(self, user=None): diff --git a/module/plugins/internal/Addon.py b/module/plugins/internal/Addon.py index 45ca98eac..5150e88f6 100644 --- a/module/plugins/internal/Addon.py +++ b/module/plugins/internal/Addon.py @@ -1,7 +1,5 @@  # -*- coding: utf-8 -*- -import traceback -  from module.plugins.internal.Plugin import Plugin @@ -25,7 +23,7 @@ def threaded(fn):  class Addon(Plugin):      __name__    = "Addon"      __type__    = "hook"  #@TODO: Change to `addon` in 0.4.10 -    __version__ = "0.04" +    __version__ = "0.06"      __status__  = "testing"      __config__   = []  #: [("name", "type", "desc", "default")] @@ -57,6 +55,12 @@ class Addon(Plugin):          self.init_events() +    #@TODO: Remove in 0.4.10 +    def _log(self, level, plugintype, pluginname, messages): +        plugintype = "addon" if plugintype is "hook" else plugintype +        return super(Addon, self)._log(level, plugintype, pluginname, messages) + +      def init_events(self):          if self.event_map:              for event, funcs in self.event_map.items(): @@ -97,8 +101,6 @@ class Addon(Plugin):          except Exception, e:              self.log_error(_("Error executing periodical task: %s") % e) -            if self.pyload.debug: -                traceback.print_exc()          self.cb = self.pyload.scheduler.addJob(self.interval, self._periodical, [threaded], threaded=threaded) @@ -107,20 +109,17 @@ class Addon(Plugin):          pass -    def __repr__(self): -        return "<Addon %s>" % self.__name__ - - -    def is_activated(self): +    @property +    def activated(self):          """          Checks if addon is activated          """          return self.get_config("activated") -    #: Deprecated method, use `is_activated` instead (Remove in 0.4.10) +    #: Deprecated method, use `activated` property instead (Remove in 0.4.10)      def isActivated(self, *args, **kwargs): -        return self.is_activated(*args, **kwargs) +        return self.activated      def deactivate(self): diff --git a/module/plugins/internal/Captcha.py b/module/plugins/internal/Captcha.py index c08050ee8..d2be21a58 100644 --- a/module/plugins/internal/Captcha.py +++ b/module/plugins/internal/Captcha.py @@ -4,7 +4,6 @@ from __future__ import with_statement  import os  import time -import traceback  from module.plugins.internal.Plugin import Plugin @@ -12,7 +11,7 @@ from module.plugins.internal.Plugin import Plugin  class Captcha(Plugin):      __name__    = "Captcha"      __type__    = "captcha" -    __version__ = "0.42" +    __version__ = "0.44"      __status__  = "testing"      __description__ = """Base anti-captcha plugin""" @@ -50,18 +49,18 @@ class Captcha(Plugin):          pass -    def decrypt(self, url, get={}, post={}, ref=False, cookies=False, decode=False, +    def decrypt(self, url, get={}, post={}, ref=False, cookies=True, decode=False,                  input_type='jpg', output_type='textual', ocr=True, timeout=120):          img = self.load(url, get=get, post=post, ref=ref, cookies=cookies, decode=decode)          return self._decrypt(img, input_type, output_type, ocr, timeout)      #@TODO: Definitely choose a better name for this method! -    def _decrypt(self, raw, input_type='jpg', output_type='textual', ocr=False, timeout=120): +    def _decrypt(self, data, input_type='jpg', output_type='textual', ocr=False, timeout=120):          """          Loads a captcha and decrypts it with ocr, plugin, user input -        :param raw: image raw data +        :param data: image raw data          :param get: get part for request          :param post: post part for request          :param cookies: True if cookies should be enabled @@ -77,7 +76,7 @@ class Captcha(Plugin):          time_ref = ("%.2f" % time.time())[-6:].replace(".", "")          with open(os.path.join("tmp", "captcha_image_%s_%s.%s" % (self.plugin.__name__, time_ref, input_type)), "wb") as tmp_img: -            tmp_img.write(raw) +            tmp_img.write(data)          if ocr:              if isinstance(ocr, basestring): @@ -90,14 +89,13 @@ class Captcha(Plugin):              captchaManager = self.pyload.captchaManager              try: -                self.task = captchaManager.newTask(raw, input_type, tmp_img.name, output_type) +                self.task = captchaManager.newTask(data, input_type, tmp_img.name, output_type)                  captchaManager.handleCaptcha(self.task)                  self.task.setWaiting(max(timeout, 50))  #@TODO: Move to `CaptchaManager` in 0.4.10                  while self.task.isWaiting(): -                    if self.plugin.pyfile.abort: -                        self.plugin.abort() +                    self.plugin.check_abort()                      time.sleep(1)              finally: @@ -108,7 +106,7 @@ class Captcha(Plugin):              elif not self.task.result:                  self.invalid() -                self.plugin.retry(reason=_("No captcha result obtained in appropiate time")) +                self.plugin.retry(msg=_("No captcha result obtained in appropiate time"))              result = self.task.result @@ -118,9 +116,8 @@ class Captcha(Plugin):              except OSError, e:                  self.log_warning(_("Error removing: %s") % tmp_img.name, e) -                traceback.print_exc() -        self.log_info(_("Captcha result: ") + result)  #@TODO: Remove from here? +        #self.log_info(_("Captcha result: ") + result)  #@TODO: Remove from here?          return result diff --git a/module/plugins/internal/Container.py b/module/plugins/internal/Container.py index 729592a0d..430590421 100644 --- a/module/plugins/internal/Container.py +++ b/module/plugins/internal/Container.py @@ -4,7 +4,6 @@ from __future__ import with_statement  import os  import re -import traceback  from module.plugins.internal.Crypter import Crypter  from module.plugins.internal.Plugin import exists @@ -14,7 +13,7 @@ from module.utils import save_join as fs_join  class Container(Crypter):      __name__    = "Container"      __type__    = "container" -    __version__ = "0.06" +    __version__ = "0.07"      __status__  = "testing"      __pattern__ = r'^unmatchable$' @@ -44,11 +43,6 @@ class Container(Crypter):          self._create_packages() -    #: Deprecated method, use `_load2disk` instead (Remove in 0.4.10) -    def loadToDisk(self, *args, **kwargs): -        return self._load2disk(*args, **kwargs) - -      def _load2disk(self):          """          Loads container to disk if its stored remotely and overwrite url, @@ -63,20 +57,18 @@ class Container(Crypter):                      f.write(content)              except IOError, e: -                self.fail(str(e))  #@TODO: Remove `str` in 0.4.10 +                self.fail(e)          else:              self.pyfile.name = os.path.basename(self.pyfile.url) +              if not exists(self.pyfile.url):                  if exists(fs_join(pypath, self.pyfile.url)):                      self.pyfile.url = fs_join(pypath, self.pyfile.url)                  else:                      self.fail(_("File not exists")) - - -    #: Deprecated method, use `delete_tmp` instead (Remove in 0.4.10) -    def deleteTmp(self, *args, **kwargs): -        return self.delete_tmp(*args, **kwargs) +            else: +                self.data = self.pyfile.url      def delete_tmp(self): @@ -87,5 +79,3 @@ class Container(Crypter):              os.remove(self.pyfile.url)          except OSError, e:              self.log_warning(_("Error removing: %s") % self.pyfile.url, e) -            if self.pyload.debug: -                traceback.print_exc() diff --git a/module/plugins/internal/Crypter.py b/module/plugins/internal/Crypter.py index d0e8eb1b4..2033b67df 100644 --- a/module/plugins/internal/Crypter.py +++ b/module/plugins/internal/Crypter.py @@ -1,15 +1,13 @@  # -*- coding: utf-8 -*- -import urlparse - -from module.plugins.internal.Hoster import Hoster, _fixurl +from module.plugins.internal.Hoster import Hoster, parse_name  from module.utils import save_path as safe_filename  class Crypter(Hoster):      __name__    = "Crypter"      __type__    = "crypter" -    __version__ = "0.07" +    __version__ = "0.08"      __status__  = "testing"      __pattern__ = r'^unmatchable$' @@ -78,13 +76,14 @@ class Crypter(Hoster):                            "%d links" % len(links),                            "Saved to folder: %s" % folder if folder else "Saved to download folder") -            pid = self.pyload.api.addPackage(name, map(self.fixurl, links), package_queue) +            links = map(self.fixurl, links) +            pid = self.pyload.api.addPackage(name, links, package_queue)              if package_password:                  self.pyload.api.setPackageData(pid, {'password': package_password})              #: Workaround to do not break API addPackage method -            set_folder = lambda x: self.pyload.api.setPackageData(pid, {'folder': x or ""}) +            set_folder = lambda x: self.pyload.api.setPackageData(pid, {'folder': safe_filename(x) or ""})              if use_subfolder:                  if not subfolder_per_package: @@ -93,9 +92,9 @@ class Crypter(Hoster):                  elif not folder_per_package or name is not folder:                      if not folder: -                        folder = urlparse.urlparse(_fixurl(name)).path.split("/")[-1] +                        folder = parse_name(name) -                    set_folder(safe_filename(folder)) +                    set_folder(folder)                      self.log_debug("Set package %(name)s folder to: %(folder)s" % {'name': name, 'folder': folder})              elif folder_per_package: diff --git a/module/plugins/internal/Extractor.py b/module/plugins/internal/Extractor.py index 7f5212090..f21fe473c 100644 --- a/module/plugins/internal/Extractor.py +++ b/module/plugins/internal/Extractor.py @@ -22,7 +22,7 @@ class PasswordError(Exception):  class Extractor(Plugin):      __name__    = "Extractor"      __type__    = "extractor" -    __version__ = "0.33" +    __version__ = "0.34"      __status__  = "testing"      __description__ = """Base extractor plugin""" @@ -43,15 +43,9 @@ class Extractor(Plugin):      @classmethod -    def is_multipart(cls, filename): -        return False - - -    @classmethod      def find(cls):          """          Check if system statisfy dependencies -        :return: boolean          """          pass @@ -72,9 +66,15 @@ class Extractor(Plugin):                  if pname not in processed:                      processed.append(pname)                      targets.append((fname, id, fout)) +          return targets +    @property +    def target(self): +        return fs_encode(self.filename) + +      def __init__(self, plugin, filename, out,                   fullpath=True,                   overwrite=False, @@ -119,53 +119,29 @@ class Extractor(Plugin):                                  (self.__name__,) + messages) -    def check(self): +    def verify(self, password=None):          """ -        Quick Check by listing content of archive. -        Raises error if password is needed, integrity is questionable or else. - -        :raises PasswordError -        :raises CRCError -        :raises ArchiveError +        Testing with Extractors built-in method +        Raise error if password is needed, integrity is questionable or else          """ -        raise NotImplementedError - - -    def verify(self): -        """ -        Testing with Extractors buildt-in method -        Raises error if password is needed, integrity is questionable or else. - -        :raises PasswordError -        :raises CRCError -        :raises ArchiveError -        """ -        raise NotImplementedError +        pass      def repair(self): -        return None +        return False      def extract(self, password=None):          """ -        Extract the archive. Raise specific errors in case of failure. - -        :param progress: Progress function, call this to update status -        :param password password to use -        :raises PasswordError -        :raises CRCError -        :raises ArchiveError -        :return: +        Extract the archive +        Raise specific errors in case of failure          """          raise NotImplementedError -    def get_delete_files(self): +    def items(self):          """ -        Return list of files to delete, do *not* delete them here. - -        :return: List with paths of files to delete +        Return list of archive parts          """          return [self.filename] diff --git a/module/plugins/internal/Hoster.py b/module/plugins/internal/Hoster.py index b397a92a6..5d0a64f1a 100644 --- a/module/plugins/internal/Hoster.py +++ b/module/plugins/internal/Hoster.py @@ -7,21 +7,21 @@ import mimetypes  import os  import random  import time -import traceback  import urlparse  from module.plugins.internal.Captcha import Captcha  from module.plugins.internal.Plugin import (Plugin, Abort, Fail, Reconnect, Retry, Skip, -                                            chunks, encode, exists, fixurl as _fixurl, replace_patterns, -                                            seconds_to_midnight, set_cookie, set_cookies, parse_html_form, -                                            parse_html_tag_attr_value, timestamp) +                                            chunks, decode, encode, exists, parse_html_form, +                                            parse_html_tag_attr_value, parse_name, +                                            replace_patterns, seconds_to_midnight, +                                            set_cookie, set_cookies, timestamp)  from module.utils import fs_decode, fs_encode, save_join as fs_join, save_path as safe_filename  #@TODO: Remove in 0.4.10  def parse_fileInfo(klass, url="", html=""):      info = klass.get_info(url, html) -    return info['name'], info['size'], info['status'], info['url'] +    return encode(info['name']), info['size'], info['status'], info['url']  #@TODO: Remove in 0.4.10 @@ -44,7 +44,7 @@ def create_getInfo(klass):  class Hoster(Plugin):      __name__    = "Hoster"      __type__    = "hoster" -    __version__ = "0.20" +    __version__ = "0.28"      __status__  = "testing"      __pattern__ = r'^unmatchable$' @@ -74,7 +74,6 @@ class Hoster(Plugin):          #: Account handler instance, see :py:class:`Account`          self.account = None -        self.user    = None          self.req     = None  #: Browser instance, see `network.Browser`          #: Associated pyfile instance, see `PyFile` @@ -105,15 +104,21 @@ class Hoster(Plugin):          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) -        url_p = urlparse.urlparse(url) -        return {'name'  : (url_p.path.split('/')[-1] or -                            url_p.query.split('=', 1)[::-1][0].split('&', 1)[0] or -                                url_p.netloc.split('.', 1)[0]), +        return {'name'  : parse_name(url),                  'size'  : 0, -                'status': 3 if url else 8, +                'status': 3 if url.strip() else 8,                  'url'   : url} @@ -132,34 +137,26 @@ class Hoster(Plugin):      def _setup(self): +        #@TODO: Remove in 0.4.10 +        self.html          = "" +        self.last_download = "" +        self.pyfile.error  = "" +          if self.account: -            self.req             = self.pyload.requestFactory.getRequest(self.__name__, self.user) +            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.is_premium(self.user) +            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 +        return self.setup() -    def load_account(self): -        if self.req: -            self.req.close() - -        if not self.account: -            self.account = self.pyload.accountManager.getAccountPlugin(self.__name__) -        if self.account: -            if not self.user: -                self.user = self.account.select()[0] - -            if not self.user or not self.account.is_logged(self.user, True): -                self.account = False - - -    def preprocessing(self, thread): +    def _process(self, thread):          """          Handles important things to do before starting          """ @@ -172,19 +169,36 @@ class Hoster(Plugin):              self.retry_free = False          self._setup() -        self.setup() +        self.pyfile.setStatus("starting")          self.pyload.hookManager.downloadPreparing(self.pyfile)  #@TODO: Recheck in 0.4.10 -        if self.pyfile.abort: -            self.abort() +        self.check_abort() -        self.pyfile.setStatus("starting")          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 self.req: +            self.req.close() + +        if not self.account: +            self.account = self.pyload.accountManager.getAccountPlugin(self.__name__) + +        if self.account: +            if not hasattr(self.account, 'user'):  #@TODO: Move to `Account` in 0.4.10 +                self.account.user = self.account.select()[0] + +            if not hasattr(self.account, 'logged'): +                self.account = False + +      def process(self, pyfile):          """          The 'main' method of every plugin, you **have to** overwrite it @@ -193,12 +207,13 @@ class Hoster(Plugin):      def set_reconnect(self, reconnect): -        reconnect = bool(reconnect) +        if reconnect: +            self.log_info(_("Requesting line reconnection...")) +        else: +            self.log_debug("Reconnect: %s" % reconnect) -        self.log_info(_("RECONNECT ") + ("enabled" if reconnect else "disabled"))          self.log_debug("Previous wantReconnect: %s" % self.wantReconnect) - -        self.wantReconnect = reconnect +        self.wantReconnect = bool(reconnect)      def set_wait(self, seconds, reconnect=None): @@ -211,7 +226,7 @@ class Hoster(Plugin):          wait_time  = max(int(seconds), 1)          wait_until = time.time() + wait_time + 1 -        self.log_info(_("WAIT %d seconds") % wait_time) +        self.log_info(_("Waiting %d seconds...") % wait_time)          self.log_debug("Previous waitUntil: %f" % self.pyfile.waitUntil)          self.pyfile.waitUntil = wait_until @@ -242,15 +257,12 @@ class Hoster(Plugin):                  self.log_warning("Ignore reconnection due logged account")              while pyfile.waitUntil > time.time(): -                if pyfile.abort: -                    self.abort() - +                self.check_abort()                  time.sleep(2)          else:              while pyfile.waitUntil > time.time(): -                if pyfile.abort: -                    self.abort() +                self.check_abort()                  if self.thread.m.reconnecting.isSet():                      self.waiting = False @@ -264,91 +276,113 @@ class Hoster(Plugin):          pyfile.status = status  #@NOTE: Remove in 0.4.10 -    def skip(self, reason=""): +    def skip(self, msg=""):          """ -        Skip and give reason +        Skip and give msg          """ -        raise Skip(encode(reason))  #@TODO: Remove `encode` in 0.4.10 +        raise Skip(encode(msg or self.pyfile.error))  #@TODO: Remove `encode` in 0.4.10 -    def abort(self, reason=""): +    #@TODO: Remove in 0.4.10 +    def fail(self, msg):          """ -        Abort and give reason +        Fail and give msg          """ -        #@TODO: Remove in 0.4.10 -        if reason: -            self.pyfile.error = encode(reason) +        msg = msg.strip() + +        if msg: +            self.pyfile.error = msg +        else: +            msg = self.pyfile.error + +        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 -    def offline(self, reason=""): +    #@TODO: Recheck in 0.4.10 +    def offline(self, msg=""):          """          Fail and indicate file is offline          """ -        #@TODO: Remove in 0.4.10 -        if reason: -            self.pyfile.error = encode(reason) - -        raise Fail("offline") +        self.fail("offline") -    def temp_offline(self, reason=""): +    #@TODO: Recheck in 0.4.10 +    def temp_offline(self, msg=""):          """          Fail and indicates file ist temporary offline, the core may take consequences          """ -        #@TODO: Remove in 0.4.10 -        if reason: -            self.pyfile.error = encode(reason) +        self.fail("temp. offline") -        raise Fail("temp. offline") - -    def retry(self, max_tries=5, wait_time=1, reason=""): +    def retry(self, attemps=5, delay=1, msg=""):          """          Retries and begin again from the beginning -        :param max_tries: number of maximum retries -        :param wait_time: time to wait in seconds -        :param reason: reason for retrying, will be passed to fail if max_tries reached +        :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 -        if 0 < max_tries <= self.retries[id]: -            self.fail(reason or _("Max retries reached")) +        if 0 < attemps <= self.retries[id]: +            self.fail(msg or _("Max retries reached")) -        self.wait(wait_time, False) +        self.wait(delay, False)          self.retries[id] += 1 -        raise Retry(encode(reason))  #@TODO: Remove `encode` in 0.4.10 +        raise Retry(encode(msg))  #@TODO: Remove `encode` in 0.4.10 -    def restart(self, reason=None, nopremium=False): -        if not reason: -            reason = _("Fallback to free download") if nopremium else _("Restart") +    def restart(self, msg=None, nopremium=False): +        if not msg: +            msg = _("Fallback to free download") if nopremium else _("Restart")          if nopremium:              if self.premium:                  self.retry_free = True              else: -                self.fail("%s | %s" % (reason, _("Download was already free"))) +                self.fail("%s | %s" % (msg, _("Download was already free"))) -        raise Retry(encode(reason))  #@TODO: Remove `encode` in 0.4.10 +        raise Retry(encode(msg))  #@TODO: Remove `encode` in 0.4.10 -    def fixurl(self, url): -        url = _fixurl(url) +    def fixurl(self, url, baseurl=None): +        if not baseurl: +            baseurl = self.pyfile.url          if not urlparse.urlparse(url).scheme: -            url_p = urlparse.urlparse(self.pyfile.url) +            url_p = urlparse.urlparse(baseurl)              baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)              url = urlparse.urljoin(baseurl, url)          return url +    def load(self, *args, **kwargs): +        self.check_abort() +        return super(Hoster, self).load(*args, **kwargs) + +      def download(self, url, get={}, post={}, ref=True, cookies=True, disposition=True):          """          Downloads the content at url to download folder @@ -362,20 +396,13 @@ class Hoster(Plugin):          the filename will be changed if needed          :return: The location where the file was saved          """ -        if self.pyfile.abort: -            self.abort() - -        url = self.fixurl(url) - -        if not url or not isinstance(url, basestring): -            self.fail(_("No url given")) +        self.check_abort()          if self.pyload.debug:              self.log_debug("DOWNLOAD URL " + url,                             *["%s=%s" % (key, val) for key, val in locals().items() if key not in ("self", "url")]) -        name = _fixurl(self.pyfile.name) -        self.pyfile.name = urlparse.urlparse(name).path.split('/')[-1] or name +        self.pyfile.name = parse_name(self.pyfile.name)  #: Safe check          self.captcha.correct()          self.check_for_same_files() @@ -388,6 +415,7 @@ class Hoster(Plugin):          if not exists(download_location):              try:                  os.makedirs(download_location) +              except Exception, e:                  self.fail(e) @@ -398,8 +426,7 @@ class Hoster(Plugin):          self.pyload.hookManager.dispatchEvent("download_start", self.pyfile, url, filename) -        if self.pyfile.abort: -            self.abort() +        self.check_abort()          try:              newname = self.req.httpDownload(url, filename, get=get, post=post, ref=ref, cookies=cookies, @@ -410,9 +437,9 @@ class Hoster(Plugin):          #@TODO: Recheck in 0.4.10          if disposition and newname: -            finalname = urlparse.urlparse(newname).path.split('/')[-1].split(' filename*=')[0] +            finalname = parse_name(newname).split(' filename*=')[0] -            if finalname != newname != self.pyfile.name: +            if finalname != newname:                  try:                      os.rename(fs_join(location, newname), fs_join(location, finalname)) @@ -421,8 +448,9 @@ class Hoster(Plugin):                      finalname = newname                  self.log_info(_("`%s` saved as `%s`") % (self.pyfile.name, finalname)) -                self.pyfile.name = finalname -                filename = os.path.join(location, finalname) + +            self.pyfile.name = finalname +            filename = os.path.join(location, finalname)          self.set_permissions(fs_encode(filename)) @@ -431,9 +459,55 @@ class Hoster(Plugin):          return self.last_download -    def check_download(self, rules, delete=False, file_size=0, size_tolerance=1024, read_size=1048576): +    def check_abort(self): +        if not self.pyfile.abort: +            return + +        if self.pyfile.hasStatus("failed"): +            self.fail() + +        elif self.pyfile.hasStatus("skipped"): +            self.skip(self.pyfile.statusname) + +        elif self.pyfile.hasStatus("offline"): +            self.offline() + +        elif self.pyfile.hasStatus("temp. offline"): +            self.temp_offline() + +        else: +            self.abort() + + +    def check_filesize(self, file_size, size_tolerance=1024): +        """ +        Checks the file size of the last downloaded file + +        :param file_size: expected file size +        :param size_tolerance: size check tolerance +        """ +        if not self.last_download: +            return + +        download_size = os.stat(fs_encode(self.last_download)).st_size + +        if download_size < 1: +            self.fail(_("Empty file")) + +        elif file_size > 0: +            diff = abs(file_size - download_size) + +            if diff > size_tolerance: +                self.fail(_("File size mismatch | Expected file size: %s | Downloaded file size: %s") +                          % (file_size, download_size)) + +            elif diff != 0: +                self.log_warning(_("File size is not equal to expected size")) + + +    def check_download(self, rules, delete=False, read_size=1048576, file_size=0, size_tolerance=1024):          """ -        Checks the content of the last downloaded file, re match is saved to `lastCheck` +        Checks the content of the last downloaded file, re match is saved to `last_check`          :param rules: dict with names and rules to match (compiled regexp or strings)          :param delete: delete if matched @@ -446,26 +520,10 @@ class Hoster(Plugin):          last_download = fs_encode(self.last_download)          if not self.last_download or not exists(last_download): -            self.last_download = ""              self.fail(self.pyfile.error or _("No file downloaded"))          try: -            download_size = os.stat(last_download).st_size - -            if download_size < 1: -                do_delete = True -                self.fail(_("Empty file")) - -            elif file_size > 0: -                diff = abs(file_size - download_size) - -                if diff > size_tolerance: -                    do_delete = True -                    self.fail(_("File size mismatch | Expected file size: %s | Downloaded file size: %s") -                              % (file_size, download_size)) - -                elif diff != 0: -                    self.log_warning(_("File size is not equal to expected size")) +            self.check_filesize(file_size, size_tolerance)              with open(last_download, "rb") as f:                  content = f.read(read_size) @@ -491,12 +549,10 @@ class Hoster(Plugin):                  except OSError, e:                      self.log_warning(_("Error removing: %s") % last_download, e) -                    if self.pyload.debug: -                        traceback.print_exc()                  else: +                    self.log_info(_("File deleted: ") + self.last_download)                      self.last_download = "" -                    self.log_info(_("File deleted"))      def direct_link(self, url, follow_location=None): @@ -519,7 +575,7 @@ class Hoster(Plugin):              except Exception:  #: Bad bad bad... rewrite this part in 0.4.10                  res = self.load(url,                                  just_header=True, -                                req=self.pyload.requestFactory.getRequest()) +                                req=self.pyload.requestFactory.getRequest(self.__name__))                  header = {'code': req.code}                  for line in res.splitlines(): @@ -543,12 +599,7 @@ class Hoster(Plugin):                  link = url              elif 'location' in header and header['location']: -                location = header['location'] - -                if not urlparse.urlparse(location).scheme: -                    url_p    = urlparse.urlparse(url) -                    baseurl  = "%s://%s" % (url_p.scheme, url_p.netloc) -                    location = urlparse.urljoin(baseurl, location) +                location = self.fixurl(header['location'], url)                  if 'code' in header and header['code'] == 302:                      link = location @@ -558,7 +609,7 @@ class Hoster(Plugin):                      continue              else: -                extension = os.path.splitext(urlparse.urlparse(url).path.split('/')[-1])[-1] +                extension = os.path.splitext(parse_name(url))[-1]                  if 'content-type' in header and header['content-type']:                      mimetype = header['content-type'].split(';')[0].strip() @@ -579,6 +630,7 @@ class Hoster(Plugin):          else:              try:                  self.log_error(_("Too many redirects")) +              except Exception:                  pass @@ -593,15 +645,17 @@ class Hoster(Plugin):          if not self.account:              return True -        traffic = self.account.get_data(self.user, True)['trafficleft'] +        traffic = self.account.get_data(self.account.user, True)['trafficleft']          if traffic is None:              return False +          elif traffic == -1:              return True +          else:              size = self.pyfile.size / 1024 -            self.log_info(_("Filesize: %s KiB, Traffic left for user %s: %s KiB") % (size, self.user, traffic)) +            self.log_info(_("Filesize: %s KiB, Traffic left for user %s: %s KiB") % (size, self.account.user, traffic))              return size <= traffic diff --git a/module/plugins/internal/OCR.py b/module/plugins/internal/OCR.py index b24b3058b..3e5afae69 100644 --- a/module/plugins/internal/OCR.py +++ b/module/plugins/internal/OCR.py @@ -12,7 +12,6 @@ import logging  import os  import subprocess  # import tempfile -import traceback  from module.plugins.internal.Plugin import Plugin  from module.utils import save_join as fs_join @@ -128,6 +127,7 @@ class OCR(Plugin):          try:              with open(tmpTxt.name, 'r') as f:                  self.result_captcha = f.read().replace("\n", "") +          except Exception:              self.result_captcha = "" @@ -137,10 +137,9 @@ class OCR(Plugin):              os.remove(tmpTxt.name)              if subset and (digits or lowercase or uppercase):                  os.remove(tmpSub.name) +          except OSError, e:              self.log_warning(e) -            if self.pyload.debug: -                traceback.print_exc()      def recognize(self, name): @@ -194,6 +193,7 @@ class OCR(Plugin):                          count += 1                      if pixels[x, y - 1] != 255:                          count += 1 +                  except Exception:                      pass diff --git a/module/plugins/internal/Plugin.py b/module/plugins/internal/Plugin.py index 7b45c40a8..51192d8c9 100644 --- a/module/plugins/internal/Plugin.py +++ b/module/plugins/internal/Plugin.py @@ -6,7 +6,10 @@ import datetime  import inspect  import os  import re +import sys +import traceback  import urllib +import urlparse  if os.name != "nt":      import grp @@ -22,7 +25,7 @@ def decode(string, encoding='utf8'):      if type(string) is str:          return string.decode(encoding, "replace")      else: -        return string +        return unicode(string)  #@TODO: Move to utils in 0.4.10 @@ -31,7 +34,7 @@ def encode(string, encoding='utf8'):      if type(string) is unicode:          return string.encode(encoding, "replace")      else: -        return string +        return str(string)  #@TODO: Move to utils in 0.4.10 @@ -47,8 +50,19 @@ def exists(path):  #@TODO: Move to utils in 0.4.10 -def fixurl(url): -    return html_unescape(urllib.unquote(url.decode('unicode-escape'))).strip().rstrip('/') +def parse_name(url): +    url = urllib.unquote(url) +    url = url.decode('unicode-escape') +    url = html_unescape(url) +    url = urllib.quote(url) + +    url_p = urlparse.urlparse(url.strip().rstrip('/')) + +    name = (url_p.path.split('/')[-1] or +            url_p.query.split('=', 1)[::-1][0].split('&', 1)[0] or +            url_p.netloc.split('.', 1)[0]) + +    return urllib.unquote(name)  #@TODO: Move to utils in 0.4.10 @@ -56,22 +70,35 @@ def timestamp():      return int(time.time() * 1000) -def seconds_to_midnight(gmt=0): -    now = datetime.datetime.utcnow() + datetime.timedelta(hours=gmt) - -    if now.hour == 0 and now.minute < 10: -        midnight = now +#@TODO: Move to utils in 0.4.10 +def which(program): +    """ +    Works exactly like the unix command which +    Courtesy of http://stackoverflow.com/a/377028/675646 +    """ +    isExe = lambda x: os.path.isfile(x) and os.access(x, os.X_OK) + +    fpath, fname = os.path.split(program) + +    if fpath: +        if isExe(program): +            return program      else: -        midnight = now + datetime.timedelta(days=1) +        for path in os.environ['PATH'].split(os.pathsep): +            exe_file = os.path.join(path.strip('"'), program) +            if isExe(exe_file): +                return exe_file -    td = midnight.replace(hour=0, minute=10, second=0, microsecond=0) - now -    if hasattr(td, 'total_seconds'): -        res = td.total_seconds() -    else:  #@NOTE: work-around for python 2.5 and 2.6 missing datetime.timedelta.total_seconds -        res = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 +def seconds_to_midnight(utc=None): +    if utc is None: +        now = datetime.datetime.today() +    else: +        now = datetime.datetime.utcnow() + datetime.timedelta(hours=utc) -    return int(res) +    midnight = now.replace(hour=0, minute=10, second=0, microsecond=0) + datetime.timedelta(days=1) + +    return (midnight - now).seconds  def replace_patterns(string, ruleslist): @@ -145,8 +172,8 @@ def chunks(iterable, size):  class Plugin(object):      __name__    = "Plugin" -    __type__    = "hoster" -    __version__ = "0.30" +    __type__    = "plugin" +    __version__ = "0.37"      __status__  = "testing"      __pattern__ = r'^unmatchable$' @@ -165,6 +192,11 @@ class Plugin(object):          self.init() +    def __repr__(self): +        return "<%(type)s %(name)s>" % {'type': self.__type__.capitalize(), +                                        'name': self.__name__} + +      def _init(self, core):          self.pyload = core          self.info   = {}  #: Provide information in dict here @@ -180,33 +212,39 @@ class Plugin(object):      def _log(self, level, plugintype, pluginname, messages):          log = getattr(self.pyload.log, level) -        msg = encode(" | ".join((a if isinstance(a, basestring) else str(a)).strip() for a in messages if a)) -        log("%(plugintype)s %(pluginname)s%(id)s: %(msg)s" +        msg = u" | ".join(decode(a).strip() for a in messages if a) +        log("%(plugintype)s %(pluginname)s: %(msg)s"              % {'plugintype': plugintype.upper(),                 'pluginname': pluginname, -               'id'        : ("[%s]" % self.pyfile.id) if hasattr(self, 'pyfile') else "",                 'msg'       : msg})      def log_debug(self, *args): -        if self.pyload.debug: -            return self._log("debug", self.__type__, self.__name__, args) +        if not self.pyload.debug: +            return +        self._log("debug", self.__type__, self.__name__, args)      def log_info(self, *args): -        return self._log("info", self.__type__, self.__name__, args) +        self._log("info", self.__type__, self.__name__, args)      def log_warning(self, *args): -        return self._log("warning", self.__type__, self.__name__, args) +        self._log("warning", self.__type__, self.__name__, args) +        if self.pyload.debug: +            traceback.print_exc()      def log_error(self, *args): -        return self._log("error", self.__type__, self.__name__, args) +        self._log("error", self.__type__, self.__name__, args) +        if self.pyload.debug: +            traceback.print_exc()      def log_critical(self, *args):          return self._log("critical", self.__type__, self.__name__, args) +        if self.pyload.debug: +            traceback.print_exc()      def set_permissions(self, path): @@ -287,21 +325,10 @@ class Plugin(object):          self.pyload.db.delStorage(self.__name__, key) -    def fail(self, reason): +    def fail(self, msg):          """ -        Fail and give reason +        Fail and give msg          """ -        raise Fail(encode(reason))  #@TODO: Remove `encode` in 0.4.10 - - -    def error(self, reason="", type=_("Parse")): -        if not reason: -            type = _("Unknown") - -        msg  = _("%s error") % type.strip().capitalize() if type else _("Error") -        msg += (": %s" % reason.strip()) if reason else "" -        msg += _(" | Plugin may be out of date") -          raise Fail(encode(msg))  #@TODO: Remove `encode` in 0.4.10 @@ -318,14 +345,6 @@ class Plugin(object):          :param decode: Wether to decode the output according to http header, should be True in most cases          :return: Loaded content          """ -        if hasattr(self, 'pyfile') and self.pyfile.abort: -            self.abort() - -        url = fixurl(url) - -        if not url or not isinstance(url, basestring): -            self.fail(_("No url given")) -          if self.pyload.debug:              self.log_debug("LOAD URL " + url,                             *["%s=%s" % (key, val) for key, val in locals().items() if key not in ("self", "url")]) @@ -345,7 +364,7 @@ class Plugin(object):          #@TODO: Move to network in 0.4.10          if isinstance(decode, basestring): -            res = decode(res, decode) +            res = sys.modules[self.__name__].decode(res, decode)  #@TODO: See #1787, use utils.decode() in 0.4.10          if self.pyload.debug:              frame = inspect.currentframe() @@ -391,6 +410,7 @@ class Plugin(object):          """          try:              self.req.close() +          except Exception:              pass diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py index 5811c28de..b79256536 100644 --- a/module/plugins/internal/SevenZip.py +++ b/module/plugins/internal/SevenZip.py @@ -10,7 +10,7 @@ from module.utils import fs_encode, save_join as fs_join  class SevenZip(UnRar):      __name__    = "SevenZip" -    __version__ = "0.14" +    __version__ = "0.15"      __status__  = "testing"      __description__ = """7-Zip extractor plugin""" @@ -55,42 +55,28 @@ class SevenZip(UnRar):              return True -    def verify(self, password): +    def verify(self, password=None):          #: 7z can't distinguish crc and pw error in test -        p = self.call_cmd("l", "-slt", fs_encode(self.filename)) +        p = self.call_cmd("l", "-slt", self.target)          out, err = p.communicate()          if self.re_wrongpwd.search(out):              raise PasswordError -        if self.re_wrongpwd.search(err): +        elif self.re_wrongpwd.search(err):              raise PasswordError -        if self.re_wrongcrc.search(err): -            raise CRCError(err) - - - -    def check(self, password): -        p = self.call_cmd("l", "-slt", fs_encode(self.filename)) -        out, err = p.communicate() - -        #: Check if output or error macthes the 'wrong password'-Regexp -        if self.re_wrongpwd.search(out): -            raise PasswordError - -        if self.re_wrongcrc.search(out): +        elif self.re_wrongcrc.search(out):              raise CRCError(_("Header protected")) - -    def repair(self): -        return False +        elif self.re_wrongcrc.search(err): +            raise CRCError(err)      def extract(self, password=None):          command = "x" if self.fullpath else "e" -        p = self.call_cmd(command, '-o' + self.out, fs_encode(self.filename), password=password) +        p = self.call_cmd(command, '-o' + self.out, self.target, password=password)          renice(p.pid, self.renice) @@ -117,7 +103,7 @@ class SevenZip(UnRar):      def list(self, password=None):          command = "l" if self.fullpath else "l" -        p = self.call_cmd(command, fs_encode(self.filename), password=password) +        p = self.call_cmd(command, self.target, password=password)          out, err = p.communicate()          if "Can not open" in err: diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index 6a3f91a5b..8c5d3599d 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -4,17 +4,16 @@ import re  from module.plugins.internal.Crypter import Crypter  from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns, set_cookie, set_cookies -from module.utils import fixup, html_unescape  class SimpleCrypter(Crypter, SimpleHoster):      __name__    = "SimpleCrypter"      __type__    = "crypter" -    __version__ = "0.60" +    __version__ = "0.62"      __status__  = "testing"      __pattern__ = r'^unmatchable$' -    __config__  = [("use_subfolder"     , "bool", "Save package to subfolder"          , True),  #: Overrides pyload.config['general']['folder_per_package'] +    __config__  = [("use_subfolder"     , "bool", "Save package to subfolder"          , True),                     ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]      __description__ = """Simple decrypter plugin""" @@ -90,6 +89,11 @@ class SimpleCrypter(Crypter, SimpleHoster):              self.log_error(_("Too many redirects")) +    def prepare(self): +        self.links = [] +        return super(SimpleCrypter, self).prepare() + +      def decrypt(self, pyfile):          self.prepare()          self.check_info()  #@TODO: Remove in 0.4.10 @@ -132,7 +136,8 @@ class SimpleCrypter(Crypter, SimpleHoster):      def handle_pages(self, pyfile):          try:              pages = int(re.search(self.PAGES_PATTERN, self.html).group(1)) -        except Exception: + +        except AttributeError:              pages = 1          for p in xrange(2, pages + 1): diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index 69f88081a..0f030e000 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -5,13 +5,12 @@ from __future__ import with_statement  import os  import re  import time -import urlparse  from module.PyFile import statusMap as _statusMap  from module.network.HTTPRequest import BadHeader  from module.network.RequestFactory import getURL as get_url  from module.plugins.internal.Hoster import Hoster, create_getInfo, parse_fileInfo -from module.plugins.internal.Plugin import Fail, encode, fixurl, replace_patterns, seconds_to_midnight, set_cookie, set_cookies +from module.plugins.internal.Plugin import Fail, encode, parse_name, replace_patterns, seconds_to_midnight, set_cookie, set_cookies  from module.utils import fixup, fs_encode, parseFileSize as parse_size @@ -22,12 +21,13 @@ statusMap = dict((v, k) for k, v in _statusMap.items())  class SimpleHoster(Hoster):      __name__    = "SimpleHoster"      __type__    = "hoster" -    __version__ = "1.81" +    __version__ = "1.86"      __status__  = "testing"      __pattern__ = r'^unmatchable$' -    __config__  = [("use_premium", "bool", "Use premium account if available"          , True), -                   ("fallback"   , "bool", "Fallback to free download if premium fails", True)] +    __config__  = [("use_premium"     , "bool", "Use premium account if available"          , True), +                   ("premium_fallback", "bool", "Fallback to free download if premium fails", True), +                   ("chk_filesize"    , "bool", "Check file size"                           , True)]      __description__ = """Simple hoster plugin"""      __license__     = "GPLv3" @@ -90,7 +90,7 @@ class SimpleHoster(Hoster):          LINK_PREMIUM_PATTERN: (optional) group(1) should be the direct link for premium download            example: LINK_PREMIUM_PATTERN = r'<div class="link"><a href="(.+?)"'      """ -    NAME_REPLACEMENTS = [("&#?\w+;", fixup)] +    NAME_REPLACEMENTS = []      SIZE_REPLACEMENTS = []      URL_REPLACEMENTS  = [] @@ -124,7 +124,7 @@ class SimpleHoster(Hoster):          try:              info['pattern'] = re.match(cls.__pattern__, url).groupdict()  #: Pattern groups will be saved here -        except Exception: +        except AttributeError:              info['pattern'] = {}          if not html and not online: @@ -174,8 +174,8 @@ class SimpleHoster(Hoster):              info['status'] = 2              if 'N' in info['pattern']: -                info['name'] = replace_patterns(fixurl(info['pattern']['N']), -                                                cls.NAME_REPLACEMENTS) +                name = replace_patterns(info['pattern']['N'], cls.NAME_REPLACEMENTS) +                info['name'] = parse_name(name)              if 'S' in info['pattern']:                  size = replace_patterns(info['pattern']['S'] + info['pattern']['U'] if 'U' in info['pattern'] else info['pattern']['S'], @@ -201,19 +201,15 @@ class SimpleHoster(Hoster):      def prepare(self): -        self.pyfile.error  = ""  #@TODO: Remove in 0.4.10 -        self.html          = ""  #@TODO: Recheck in 0.4.10 -        self.link          = ""  #@TODO: Recheck in 0.4.10 -        self.last_download = "" -        self.direct_dl     = False -        self.leech_dl      = False - -        if not self.get_config('use_premium', True): +        self.link      = "" +        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")) -            self.LOGIN_ACCOUNT = True          if self.LOGIN_ACCOUNT and not self.account:              self.fail(_("Required account not found")) @@ -294,7 +290,7 @@ class SimpleHoster(Hoster):              self.check_file()          except Fail, e:  #@TODO: Move to PluginThread in 0.4.10 -            if self.get_config('fallback', True) and self.premium: +            if self.get_config('premium_fallback', True) and self.premium:                  self.log_warning(_("Premium download failed"), e)                  self.restart(nopremium=True) @@ -307,17 +303,18 @@ class SimpleHoster(Hoster):          if self.captcha.task and not self.last_download:              self.captcha.invalid() -            self.retry(10, reason=_("Wrong captcha")) +            self.retry(10, msg=_("Wrong captcha")) -        # 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          elif self.check_download({'Empty file': re.compile(r'\A((.|)(\2|\s)*)\Z')}, -                                 file_size=self.info['size'] if 'size' in self.info else 0, -                                 size_tolerance=10485760, -                                 delete=False):  #@TODO: Make `delete` settable in 0.4.10 +                                 delete=True):              self.error(_("Empty file"))          else: +            if self.get_config('chk_filesize', False) and 'size' in self.info: +                # 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_download({r: re.compile(p)}) @@ -326,12 +323,13 @@ class SimpleHoster(Hoster):                      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(wait_time=60, reason=errmsg) +                    self.retry(delay=60, msg=errmsg)              else:                  if self.CHECK_FILE:                      self.log_debug("Using custom check rules...") @@ -340,7 +338,7 @@ class SimpleHoster(Hoster):                      self.check_errors()          self.log_info(_("No errors found")) -        self.pyfile.error = "" +        self.pyfile.error = ""  #@TODO: Recheck in 0.4.10      def check_errors(self): @@ -362,14 +360,15 @@ class SimpleHoster(Hoster):                  m = re.search(self.DL_LIMIT_PATTERN, self.html)                  try:                      errmsg = m.group(1).strip() -                except Exception: + +                except AttributeError:                      errmsg = m.group(0).strip()                  self.info['error'] = re.sub(r'<.*?>', " ", errmsg)                  self.log_warning(self.info['error'])                  if re.search('da(il)?y|today', errmsg, re.I): -                    wait_time = seconds_to_midnight(gmt=2) +                    wait_time = seconds_to_midnight()                  else:                      wait_time = sum(int(v) * {'hr': 3600, 'hour': 3600, 'min': 60, 'sec': 1, "": 1}[u.lower()] for v, u in                                  re.findall(r'(\d+)\s*(hr|hour|min|sec|)', errmsg, re.I)) @@ -385,7 +384,8 @@ class SimpleHoster(Hoster):              if m:                  try:                      errmsg = m.group(1).strip() -                except Exception: + +                except AttributeError:                      errmsg = m.group(0).strip()                  self.info['error'] = re.sub(r'<.*?>', " ", errmsg) @@ -393,7 +393,7 @@ class SimpleHoster(Hoster):                  if re.search('limit|wait|slot', errmsg, re.I):                      if re.search("da(il)?y|today", errmsg): -                        wait_time = seconds_to_midnight(gmt=2) +                        wait_time = seconds_to_midnight()                      else:                          wait_time = sum(int(v) * {'hr': 3600, 'hour': 3600, 'min': 60, 'sec': 1, "": 1}[u.lower()] for v, u in                                      re.findall(r'(\d+)\s*(hr|hour|min|sec|)', errmsg, re.I)) @@ -406,7 +406,7 @@ class SimpleHoster(Hoster):                  elif re.search('captcha|code', errmsg, re.I):                      self.captcha.invalid() -                    self.retry(10, reason=_("Wrong captcha")) +                    self.retry(10, msg=_("Wrong captcha"))                  elif re.search('countdown|expired', errmsg, re.I):                      self.retry(10, 60, _("Link expired")) @@ -421,23 +421,22 @@ class SimpleHoster(Hoster):                      self.offline()                  elif re.search('filename', errmsg, re.I): -                    url_p = urlparse.urlparse(self.pyfile.url) -                    self.pyfile.url = "%s://%s/%s" % (url_p.scheme, url_p.netloc, url_p.path.split('/')[0]) -                    self.retry(1, reason=_("Wrong url")) +                    self.fail(_("Wrong url"))                  elif re.search('premium', errmsg, re.I):                      self.fail(_("File can be downloaded by premium users only"))                  else:                      self.wantReconnect = True -                    self.retry(wait_time=60, reason=errmsg) +                    self.retry(delay=60, msg=errmsg)          elif hasattr(self, 'WAIT_PATTERN'):              m = re.search(self.WAIT_PATTERN, self.html)              if m:                  try:                      waitmsg = m.group(1).strip() -                except Exception: + +                except AttributeError:                      waitmsg = m.group(0).strip()                  wait_time = sum(int(v) * {'hr': 3600, 'hour': 3600, 'min': 60, 'sec': 1, "": 1}[u.lower()] for v, u in @@ -483,8 +482,8 @@ class SimpleHoster(Hoster):              self.log_debug("Previous file info: %s" % old_info)          try: -            url  = self.info['url'].strip() -            name = self.info['name'].strip() +            url  = self.info['url'] +            name = self.info['name']          except KeyError:              pass diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py index 0386991d9..88c490750 100644 --- a/module/plugins/internal/UnRar.py +++ b/module/plugins/internal/UnRar.py @@ -22,7 +22,7 @@ def renice(pid, value):  class UnRar(Extractor):      __name__    = "UnRar" -    __version__ = "1.25" +    __version__ = "1.26"      __status__  = "testing"      __description__ = """Rar extractor plugin""" @@ -84,20 +84,8 @@ class UnRar(Extractor):          return True if cls.re_multipart.search(filename) else False -    def verify(self, password): -        p = self.call_cmd("t", "-v", fs_encode(self.filename), password=password) -        self._progress(p) -        err = p.stderr.read().strip() - -        if self.re_wrongpwd.search(err): -            raise PasswordError - -        if self.re_wrongcrc.search(err): -            raise CRCError(err) - - -    def check(self, password): -        p = self.call_cmd("l", "-v", fs_encode(self.filename), password=password) +    def verify(self, password=None): +        p = self.call_cmd("l", "-v", self.target, password=password)          out, err = p.communicate()          if self.re_wrongpwd.search(err): @@ -113,13 +101,28 @@ class UnRar(Extractor):      def repair(self): -        p = self.call_cmd("rc", fs_encode(self.filename)) +        p = self.call_cmd("rc", self.target)          #: Communicate and retrieve stderr          self._progress(p)          err = p.stderr.read().strip() +          if err or p.returncode: -            return False +            p = self.call_cmd("r", self.target) + +            # communicate and retrieve stderr +            self._progress(p) +            err = p.stderr.read().strip() + +            if err or p.returncode: +                return False + +            else: +                dir  = os.path.dirname(filename) +                name = re_filefixed.search(out).group(1) + +                self.filename = os.path.join(dir, name) +          return True @@ -145,7 +148,7 @@ class UnRar(Extractor):      def extract(self, password=None):          command = "x" if self.fullpath else "e" -        p = self.call_cmd(command, fs_encode(self.filename), self.out, password=password) +        p = self.call_cmd(command, self.target, self.out, password=password)          renice(p.pid, self.renice) @@ -169,7 +172,7 @@ class UnRar(Extractor):          self.files = self.list(password) -    def get_delete_files(self): +    def items(self):          dir, name = os.path.split(self.filename)          #: Actually extracted file @@ -185,7 +188,7 @@ class UnRar(Extractor):      def list(self, password=None):          command = "vb" if self.fullpath else "lb" -        p = self.call_cmd(command, "-v", fs_encode(self.filename), password=password) +        p = self.call_cmd(command, "-v", self.target, password=password)          out, err = p.communicate()          if "Cannot open" in err: diff --git a/module/plugins/internal/UnZip.py b/module/plugins/internal/UnZip.py index 9a01611bf..ac197a80d 100644 --- a/module/plugins/internal/UnZip.py +++ b/module/plugins/internal/UnZip.py @@ -12,7 +12,7 @@ from module.utils import fs_encode  class UnZip(Extractor):      __name__    = "UnZip" -    __version__ = "1.15" +    __version__ = "1.16"      __status__  = "testing"      __description__ = """Zip extractor plugin""" @@ -30,17 +30,13 @@ class UnZip(Extractor):      def list(self, password=None): -        with zipfile.ZipFile(fs_encode(self.filename), 'r', allowZip64=True) as z: +        with zipfile.ZipFile(self.target, 'r', allowZip64=True) as z:              z.setpassword(password)              return z.namelist() -    def check(self, password): -        pass - - -    def verify(self): -        with zipfile.ZipFile(fs_encode(self.filename), 'r', allowZip64=True) as z: +    def verify(self, password=None): +        with zipfile.ZipFile(self.target, 'r', allowZip64=True) as z:              badfile = z.testzip()              if badfile: @@ -51,7 +47,7 @@ class UnZip(Extractor):      def extract(self, password=None):          try: -            with zipfile.ZipFile(fs_encode(self.filename), 'r', allowZip64=True) as z: +            with zipfile.ZipFile(self.target, 'r', allowZip64=True) as z:                  z.setpassword(password)                  badfile = z.testzip() diff --git a/module/plugins/internal/XFSAccount.py b/module/plugins/internal/XFSAccount.py index 5a4cc35fb..bb5cbcf50 100644 --- a/module/plugins/internal/XFSAccount.py +++ b/module/plugins/internal/XFSAccount.py @@ -4,6 +4,7 @@ import re  import time  import urlparse +from module.common.json_layer import json_loads  from module.plugins.internal.Account import Account  from module.plugins.internal.Plugin import parse_html_form, set_cookie @@ -11,7 +12,7 @@ from module.plugins.internal.Plugin import parse_html_form, set_cookie  class XFSAccount(Account):      __name__    = "XFSAccount"      __type__    = "account" -    __version__ = "0.43" +    __version__ = "0.46"      __status__  = "testing"      __description__ = """XFileSharing account plugin""" @@ -39,7 +40,7 @@ class XFSAccount(Account):      LOGIN_FAIL_PATTERN = r'Incorrect Login or Password|account was banned|Error<' -    def parse_info(self, user, password, data, req): +    def grab_info(self, user, password, data, req):          validuntil   = None          trafficleft  = None          leechtraffic = None @@ -144,13 +145,13 @@ class XFSAccount(Account):                  self.HOSTER_URL = "http://www.%s/" % self.HOSTER_DOMAIN              if self.COOKIES: -                if isinstance(self.COOKIES, list) and not self.COOKIES.count((self.HOSTER_DOMAIN, "lang", "english")): +                if isinstance(self.COOKIES, list) and (self.HOSTER_DOMAIN, "lang", "english") not in self.COOKIES:                      self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))                  else:                      set_cookie(self.req.cj, self.HOSTER_DOMAIN, "lang", "english")          if not self.HOSTER_URL: -            self.login_fail(_("Missing HOSTER_URL")) +            self.fail_login(_("Missing HOSTER_URL"))          else:              self.HOSTER_URL = self.HOSTER_URL.rstrip('/') + "/" @@ -174,5 +175,13 @@ class XFSAccount(Account):          html = self.load(url, post=inputs, cookies=self.COOKIES) -        if re.search(self.LOGIN_FAIL_PATTERN, html): -            self.login_fail() +        try: +            json = json_loads(html) + +        except ValueError: +            if re.search(self.LOGIN_FAIL_PATTERN, html): +                self.fail_login() + +        else: +            if not 'success' in json or not json['success']: +                self.fail_login() diff --git a/module/plugins/internal/XFSCrypter.py b/module/plugins/internal/XFSCrypter.py index 4c059d647..12a48d4a3 100644 --- a/module/plugins/internal/XFSCrypter.py +++ b/module/plugins/internal/XFSCrypter.py @@ -7,7 +7,7 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo  class XFSCrypter(SimpleCrypter):      __name__    = "XFSCrypter"      __type__    = "crypter" -    __version__ = "0.13" +    __version__ = "0.14"      __status__  = "testing"      __pattern__ = r'^unmatchable$' @@ -42,7 +42,7 @@ class XFSCrypter(SimpleCrypter):                  self.fail(_("Missing HOSTER_DOMAIN"))          if self.COOKIES: -            if isinstance(self.COOKIES, list) and not self.COOKIES.count((self.HOSTER_DOMAIN, "lang", "english")): +            if isinstance(self.COOKIES, list) and (self.HOSTER_DOMAIN, "lang", "english") not in self.COOKIES:                  self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))              else:                  set_cookie(self.req.cj, self.HOSTER_DOMAIN, "lang", "english") diff --git a/module/plugins/internal/XFSHoster.py b/module/plugins/internal/XFSHoster.py index 5e0830dc6..729c9a0ee 100644 --- a/module/plugins/internal/XFSHoster.py +++ b/module/plugins/internal/XFSHoster.py @@ -14,7 +14,7 @@ from module.utils import html_unescape  class XFSHoster(SimpleHoster):      __name__    = "XFSHoster"      __type__    = "hoster" -    __version__ = "0.57" +    __version__ = "0.60"      __status__  = "testing"      __pattern__ = r'^unmatchable$' @@ -73,7 +73,7 @@ class XFSHoster(SimpleHoster):                  self.fail(_("Missing HOSTER_DOMAIN"))          if self.COOKIES: -            if isinstance(self.COOKIES, list) and not self.COOKIES.count((self.HOSTER_DOMAIN, "lang", "english")): +            if isinstance(self.COOKIES, list) and (self.HOSTER_DOMAIN, "lang", "english") not in self.COOKIES:                  self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))              else:                  set_cookie(self.req.cj, self.HOSTER_DOMAIN, "lang", "english") @@ -150,7 +150,7 @@ class XFSHoster(SimpleHoster):          action, inputs = self.parse_html_form('F1')          if not inputs: -            self.retry(reason=self.info['error'] if 'error' in self.info else _("TEXTAREA F1 not found")) +            self.retry(msg=self.info['error'] if 'error' in self.info else _("TEXTAREA F1 not found"))          self.log_debug(inputs) @@ -163,7 +163,7 @@ class XFSHoster(SimpleHoster):              self.retry(20, 3 * 60, _("Can not leech file"))          elif 'today' in stmsg: -            self.retry(wait_time=seconds_to_midnight(gmt=2), reason=_("You've used all Leech traffic today")) +            self.retry(delay=seconds_to_midnight(), msg=_("You've used all Leech traffic today"))          else:              self.fail(stmsg) @@ -188,7 +188,7 @@ class XFSHoster(SimpleHoster):          if not inputs:              action, inputs = self.parse_html_form('F1')              if not inputs: -                self.retry(reason=self.info['error'] if 'error' in self.info else _("TEXTAREA F1 not found")) +                self.retry(msg=self.info['error'] if 'error' in self.info else _("TEXTAREA F1 not found"))          self.log_debug(inputs) @@ -244,7 +244,7 @@ class XFSHoster(SimpleHoster):          try:              captcha_key = re.search(self.RECAPTCHA_PATTERN, self.html).group(1) -        except Exception: +        except AttributeError:              captcha_key = recaptcha.detect_key()          else: @@ -258,7 +258,7 @@ class XFSHoster(SimpleHoster):          try:              captcha_key = re.search(self.SOLVEMEDIA_PATTERN, self.html).group(1) -        except Exception: +        except AttributeError:              captcha_key = solvemedia.detect_key()          else:  | 
