diff options
37 files changed, 156 insertions, 141 deletions
diff --git a/module/plugins/accounts/CzshareCom.py b/module/plugins/accounts/CzshareCom.py index 209a94f60..0c60e64d0 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.23" + __version__ = "0.24" __status__ = "testing" __description__ = """Czshare.com account plugin, now Sdilej.cz""" @@ -30,7 +30,7 @@ class CzshareCom(Account): try: m = re.search(self.CREDIT_LEFT_PATTERN, html) - trafficleft = self.parse_traffic(m.group(1), m.group(2) + trafficleft = self.parse_traffic(m.group(1), m.group(2)) validuntil = time.mktime(time.strptime(m.group(3), '%d.%m.%y %H:%M')) except Exception, e: diff --git a/module/plugins/accounts/HellshareCz.py b/module/plugins/accounts/HellshareCz.py index a552a03b6..5423b212f 100644 --- a/module/plugins/accounts/HellshareCz.py +++ b/module/plugins/accounts/HellshareCz.py @@ -59,7 +59,7 @@ class HellshareCz(Account): self.log_debug("Switch lang - URL: %s" % self.req.lastEffectiveURL) json = self.load("%s?do=locRouter-show" % self.req.lastEffectiveURL) - hash = re.search(r"(\-\-[0-9a-f]+\-)", json).group(1) + hash = re.search(r"(--[0-9a-f]+-)", json).group(1) self.log_debug("Switch lang - HASH: %s" % hash) diff --git a/module/plugins/accounts/UploadedTo.py b/module/plugins/accounts/UploadedTo.py index 9c3369bd8..1e92195a1 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.37" + __version__ = "0.38" __status__ = "testing" __description__ = """Uploaded.to account plugin""" @@ -51,12 +51,7 @@ class UploadedTo(Account): traffic = m.groupdict() size = traffic['S'].replace('.', '') unit = traffic['U'].lower() - - if unit.startswith('t'): #@NOTE: Remove in 0.4.10 - trafficleft = float(size.replace(',', '.')) / 1024 - trafficleft *= 1 << 40 - else: - trafficleft = self.parse_traffic(size, unit) + trafficleft = self.parse_traffic(size, unit) return {'validuntil' : validuntil, 'trafficleft': trafficleft, diff --git a/module/plugins/captcha/AdsCaptcha.py b/module/plugins/captcha/AdsCaptcha.py index 66f6e2993..613283e53 100644 --- a/module/plugins/captcha/AdsCaptcha.py +++ b/module/plugins/captcha/AdsCaptcha.py @@ -18,7 +18,7 @@ class AdsCaptcha(CaptchaService): CAPTCHAID_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?.*?CaptchaId=(\d+)' - PUBLICKEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?.*?PublicKey=([\w\-]+)' + PUBLICKEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?.*?PublicKey=([\w-]+)' def detect_key(self, data=None): diff --git a/module/plugins/captcha/ReCaptcha.py b/module/plugins/captcha/ReCaptcha.py index 379956be6..a3ac52cb1 100644 --- a/module/plugins/captcha/ReCaptcha.py +++ b/module/plugins/captcha/ReCaptcha.py @@ -23,8 +23,8 @@ class ReCaptcha(CaptchaService): ("zapp-brannigan", "fuerst.reinje@web.de")] - KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w\-]+)' - KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w\-]+)' + KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)' + KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)' def detect_key(self, data=None): diff --git a/module/plugins/crypter/Dereferer.py b/module/plugins/crypter/Dereferer.py index 8ecc635ec..0a1c1a918 100644 --- a/module/plugins/crypter/Dereferer.py +++ b/module/plugins/crypter/Dereferer.py @@ -11,7 +11,7 @@ class Dereferer(SimpleCrypter): __version__ = "0.19" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/.*?(?P<LINK>(?:ht|f)tps?://.+)' + __pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w-]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/.*?(?P<LINK>(?:ht|f)tps?://.+)' __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] diff --git a/module/plugins/crypter/FilecryptCc.py b/module/plugins/crypter/FilecryptCc.py index 51fdcd30b..70f9bc088 100644 --- a/module/plugins/crypter/FilecryptCc.py +++ b/module/plugins/crypter/FilecryptCc.py @@ -31,7 +31,7 @@ class FilecryptCc(Crypter): # URL_REPLACEMENTS = [(r'.html$', ""), (r'$', ".html")] #@TODO: Extend SimpleCrypter DLC_LINK_PATTERN = r'onclick="DownloadDLC\(\'(.+)\'\);">' - WEBLINK_PATTERN = r"openLink.?'([\w\-]*)'," + WEBLINK_PATTERN = r"openLink.?'([\w-]*)'," CAPTCHA_PATTERN = r'class="safety">Sicherheitsabfrage<' INTERNAL_CAPTCHA_PATTERN = r'<img id="nc" src="(.+?)"' diff --git a/module/plugins/crypter/TinyurlCom.py b/module/plugins/crypter/TinyurlCom.py index 2b9a8041f..bff1efa12 100644 --- a/module/plugins/crypter/TinyurlCom.py +++ b/module/plugins/crypter/TinyurlCom.py @@ -9,7 +9,7 @@ class TinyurlCom(SimpleCrypter): __version__ = "0.03" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?(preview\.)?tinyurl\.com/[\w\-]+' + __pattern__ = r'https?://(?:www\.)?(preview\.)?tinyurl\.com/[\w-]+' __description__ = """Tinyurl.com decrypter plugin""" __license__ = "GPLv3" diff --git a/module/plugins/crypter/XFileSharingProFolder.py b/module/plugins/crypter/XFileSharingProFolder.py index f693698bc..ca5c3ba96 100644 --- a/module/plugins/crypter/XFileSharingProFolder.py +++ b/module/plugins/crypter/XFileSharingProFolder.py @@ -11,7 +11,7 @@ class XFileSharingProFolder(XFSCrypter): __version__ = "0.14" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:user|folder)s?/\w+' + __pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:user|folder)s?/\w+' __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] @@ -33,7 +33,7 @@ class XFileSharingProFolder(XFSCrypter): self.__pattern__ = self.pyload.pluginManager.crypterPlugins[self.__name__]['pattern'] self.PLUGIN_DOMAIN = re.match(self.__pattern__, self.pyfile.url).group("DOMAIN").lower() - self.PLUGIN_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+|\-)', self.PLUGIN_DOMAIN) if part != '.') + self.PLUGIN_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+|-)', self.PLUGIN_DOMAIN) if part != '.') def _setup(self): diff --git a/module/plugins/crypter/YoutubeComFolder.py b/module/plugins/crypter/YoutubeComFolder.py index 302f18ac0..ea09c63f9 100644 --- a/module/plugins/crypter/YoutubeComFolder.py +++ b/module/plugins/crypter/YoutubeComFolder.py @@ -14,7 +14,7 @@ class YoutubeComFolder(Crypter): __version__ = "1.03" __status__ = "testing" - __pattern__ = r'https?://(?:www\.|m\.)?youtube\.com/(?P<TYPE>user|playlist|view_play_list)(/|.*?[?&](?:list|p)=)(?P<ID>[\w\-]+)' + __pattern__ = r'https?://(?:www\.|m\.)?youtube\.com/(?P<TYPE>user|playlist|view_play_list)(/|.*?[?&](?:list|p)=)(?P<ID>[\w-]+)' __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True ), ("subfolder_per_pack", "bool", "Create a subfolder for each package", True ), ("likes" , "bool", "Grab user (channel) liked videos" , False), diff --git a/module/plugins/hooks/AntiVirus.py b/module/plugins/hooks/AntiVirus.py index d7ec69031..536675a41 100644 --- a/module/plugins/hooks/AntiVirus.py +++ b/module/plugins/hooks/AntiVirus.py @@ -17,7 +17,7 @@ from module.utils import fs_encode, save_join as fs_join class AntiVirus(Addon): __name__ = "AntiVirus" __type__ = "hook" - __version__ = "0.13" + __version__ = "0.14" __status__ = "testing" #@TODO: add trash option (use Send2Trash lib) @@ -84,7 +84,7 @@ class AntiVirus(Addon): if scanfolder: if action is "Antivirus default": - self.log_warning(_("Delete/Quarantine task skipped in folder scan mode") + self.log_warning(_("Delete/Quarantine task skipped in folder scan mode")) return pyfile.error = _("Infected file") diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py index 475234689..aef014d1a 100644 --- a/module/plugins/hooks/ClickAndLoad.py +++ b/module/plugins/hooks/ClickAndLoad.py @@ -29,13 +29,13 @@ def forward(source, destination): class ClickAndLoad(Addon): __name__ = "ClickAndLoad" __type__ = "hook" - __version__ = "0.47" + __version__ = "0.48" __status__ = "testing" - __config__ = [("activated", "bool", "Activated" , True ), - ("port" , "int" , "Port" , 9666 ), - ("extern" , "bool", "Listen on the public network interface", True ), - ("queue" , "bool", "Add packages to queue" , False)] + __config__ = [("activated", "bool" , "Activated" , True ), + ("port" , "int" , "Port" , 9666 ), + ("extern" , "bool" , "Listen for external connections", True ), + ("dest" , "queue;collector", "Add packages to" , "collector")] __description__ = """Click'n'Load hook plugin""" __license__ = "GPLv3" @@ -55,7 +55,7 @@ class ClickAndLoad(Addon): @threaded - def forward(source, destination, queue=False): + def forward(self, source, destination, queue=False): if queue: old_ids = set(pack.id for pack in self.pyload.api.getCollector()) @@ -109,7 +109,7 @@ class ClickAndLoad(Addon): server_socket.connect(("127.0.0.1", webport)) - self.forward(client_socket, server_socket, self.get_config('queue')) + self.forward(client_socket, server_socket, self.get_config('dest') is "queue") self.forward(server_socket, client_socket) except socket.timeout: diff --git a/module/plugins/hooks/DeleteFinished.py b/module/plugins/hooks/DeleteFinished.py index 75a282808..a38966476 100644 --- a/module/plugins/hooks/DeleteFinished.py +++ b/module/plugins/hooks/DeleteFinished.py @@ -7,7 +7,7 @@ from module.plugins.internal.Addon import Addon class DeleteFinished(Addon): __name__ = "DeleteFinished" __type__ = "hook" - __version__ = "1.14" + __version__ = "1.15" __status__ = "testing" __config__ = [("interval" , "int" , "Check interval in hours" , 72 ), @@ -21,10 +21,9 @@ class DeleteFinished(Addon): MIN_CHECK_INTERVAL = 1 * 60 * 60 #: 1 hour - ## overwritten methods ## - def init(self): - # self.event_map = {'pluginConfigChanged': "plugin_config_changed"} + def activate(self): self.interval = self.MIN_CHECK_INTERVAL + self.init_periodical() def periodical(self): diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py index 5a65146b9..d556537aa 100644 --- a/module/plugins/hooks/HotFolder.py +++ b/module/plugins/hooks/HotFolder.py @@ -14,22 +14,22 @@ from module.utils import fs_encode, save_join as fs_join class HotFolder(Addon): __name__ = "HotFolder" __type__ = "hook" - __version__ = "0.17" + __version__ = "0.18" __status__ = "testing" - __config__ = [("folder" , "str" , "Folder to observe" , "container"), - ("watch_file", "bool", "Observe link file" , False ), - ("keep" , "bool", "Keep added containers", True ), - ("file" , "str" , "Link file" , "links.txt")] + __config__ = [("folder" , "str" , "Folder to watch" , "watchdir" ), + ("watchfile", "bool", "Watch link file" , False ), + ("delete" , "bool", "Delete added containers", False ), + ("file" , "str" , "Link file" , "links.txt")] __description__ = """Observe folder and file for changes and add container and links""" __license__ = "GPLv3" __authors__ = [("RaNaN", "RaNaN@pyload.de")] - def init(self): + def activate(self): self.interval = 30 - self.init_periodical() + self.init_periodical(threaded=True) def periodical(self): @@ -40,7 +40,7 @@ class HotFolder(Addon): if not os.path.isdir(os.path.join(folder, "finished")): os.makedirs(os.path.join(folder, "finished")) - if self.get_config('watch_file'): + if self.get_config('watchfile'): with open(file, "a+") as f: f.seek(0) content = f.read().strip() @@ -62,7 +62,7 @@ class HotFolder(Addon): if not os.path.isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."): continue - newpath = os.path.join(folder, "finished", f if self.get_config('keep') else "tmp_" + f) + newpath = os.path.join(folder, "finished", "tmp_" + f if self.get_config('delete') else f) move(path, newpath) self.log_info(_("Added %s from HotFolder") % f) diff --git a/module/plugins/hooks/LinkdecrypterComHook.py b/module/plugins/hooks/LinkdecrypterComHook.py index bd3b03aab..7d39656d3 100644 --- a/module/plugins/hooks/LinkdecrypterComHook.py +++ b/module/plugins/hooks/LinkdecrypterComHook.py @@ -23,7 +23,7 @@ class LinkdecrypterComHook(Addon): def get_hosters(self): - list = re.search(r'>Supported\(\d+\)</b>: <i>(.[\w.\-, ]+)', + list = re.search(r'>Supported\(\d+\)</b>: <i>(.[\w.-, ]+)', self.load("http://linkdecrypter.com/").replace("(g)", "")).group(1).split(', ') try: list.remove("download.serienjunkies.org") diff --git a/module/plugins/hooks/RestartFailed.py b/module/plugins/hooks/RestartFailed.py index 6c3388e3a..812b68f76 100644 --- a/module/plugins/hooks/RestartFailed.py +++ b/module/plugins/hooks/RestartFailed.py @@ -6,7 +6,7 @@ from module.plugins.internal.Addon import Addon class RestartFailed(Addon): __name__ = "RestartFailed" __type__ = "hook" - __version__ = "1.60" + __version__ = "1.61" __status__ = "testing" __config__ = [("interval", "int", "Check interval in minutes", 90)] @@ -19,27 +19,11 @@ class RestartFailed(Addon): MIN_CHECK_INTERVAL = 15 * 60 #: 15 minutes - # def plugin_config_changed(self, plugin, name, value): - # if name == "interval": - # interval = value * 60 - # if self.MIN_CHECK_INTERVAL <= interval is not self.interval: - # self.pyload.scheduler.removeJob(self.cb) - # self.interval = interval - # self.init_periodical() - # else: - # self.log_debug("Invalid interval value, kept current") - - def periodical(self): self.log_debug("Restart failed downloads") self.pyload.api.restartFailed() - def init(self): - # self.event_map = {'pluginConfigChanged': "plugin_config_changed"} - self.interval = self.MIN_CHECK_INTERVAL - - def activate(self): - # self.plugin_config_changed(self.__name__, "interval", self.get_config('interval')) self.interval = max(self.MIN_CHECK_INTERVAL, self.get_config('interval') * 60) + self.init_periodical() diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py index 70bafba67..04438519b 100644 --- a/module/plugins/hooks/XFileSharingPro.py +++ b/module/plugins/hooks/XFileSharingPro.py @@ -23,9 +23,9 @@ class XFileSharingPro(Hook): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - regexp = {'hoster' : (r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', + regexp = {'hoster' : (r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:embed-)?\w+'), - 'crypter': (r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:user|folder)s?/\w+', + 'crypter': (r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:user|folder)s?/\w+', r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:user|folder)s?/\w+')} BUILTIN_HOSTERS = [#WORKING HOSTERS: diff --git a/module/plugins/hoster/FastixRu.py b/module/plugins/hoster/FastixRu.py index d932bb22e..83d91e8c3 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.15" + __version__ = "0.16" __status__ = "testing" __pattern__ = r'http://(?:www\.)?fastix\.(ru|it)/file/\w{24}' @@ -27,11 +27,11 @@ class FastixRu(MultiHoster): def handle_premium(self, pyfile): - 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.html = self.load("http://fastix.ru/api_v2/", + get={'apikey': self.account.get_data('apikey'), + 'sub' : "getdirectlink", + 'link' : pyfile.url}) + data = json_loads(self.html) self.log_debug("Json data", data) diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py index fb1b7c631..9ccc5df86 100644 --- a/module/plugins/hoster/FileserveCom.py +++ b/module/plugins/hoster/FileserveCom.py @@ -190,16 +190,16 @@ class FileserveCom(Hoster): res = json_loads(res) if res['error_code'] == "302": premium_url = res['next'] - + elif res['error_code'] in ["305", "500"]: self.temp_offline() - + elif res['error_code'] in ["403", "605"]: self.restart(premium=False) - + elif res['error_code'] in ["606", "607", "608"]: self.offline() - + else: self.log_error(res['error_code'], res['error_message']) diff --git a/module/plugins/hoster/FourSharedCom.py b/module/plugins/hoster/FourSharedCom.py index d767f4ca1..5b4efab00 100644 --- a/module/plugins/hoster/FourSharedCom.py +++ b/module/plugins/hoster/FourSharedCom.py @@ -11,7 +11,7 @@ class FourSharedCom(SimpleHoster): __version__ = "0.32" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?4shared(\-china)?\.com/(account/)?(download|get|file|document|photo|video|audio|mp3|office|rar|zip|archive|music)/.+' + __pattern__ = r'https?://(?:www\.)?4shared(-china)?\.com/(account/)?(download|get|file|document|photo|video|audio|mp3|office|rar|zip|archive|music)/.+' __config__ = [("use_premium", "bool", "Use premium account if available", True)] __description__ = """4Shared.com hoster plugin""" diff --git a/module/plugins/hoster/Keep2ShareCc.py b/module/plugins/hoster/Keep2ShareCc.py index 427dbbec7..d4a17610d 100644 --- a/module/plugins/hoster/Keep2ShareCc.py +++ b/module/plugins/hoster/Keep2ShareCc.py @@ -94,7 +94,7 @@ class Keep2ShareCc(SimpleHoster): 'uniqueId' : self.fid, 'yt0' : ''} - m = re.search(r'id="(captcha\-form)"', self.html) + m = re.search(r'id="(captcha-form)"', self.html) self.log_debug("Captcha form found", m) m = re.search(self.CAPTCHA_PATTERN, self.html) diff --git a/module/plugins/hoster/LinksnappyCom.py b/module/plugins/hoster/LinksnappyCom.py index 3301eda7c..f92681f60 100644 --- a/module/plugins/hoster/LinksnappyCom.py +++ b/module/plugins/hoster/LinksnappyCom.py @@ -46,7 +46,7 @@ class LinksnappyCom(MultiHoster): @staticmethod def _get_host(url): host = urlparse.urlsplit(url).netloc - return re.search(r'[\w\-]+\.\w+$', host).group(0) + return re.search(r'[\w-]+\.\w+$', host).group(0) getInfo = create_getInfo(LinksnappyCom) diff --git a/module/plugins/hoster/NitroflareCom.py b/module/plugins/hoster/NitroflareCom.py index ad0573960..431698596 100644 --- a/module/plugins/hoster/NitroflareCom.py +++ b/module/plugins/hoster/NitroflareCom.py @@ -24,7 +24,7 @@ class NitroflareCom(SimpleHoster): INFO_PATTERN = r'title="(?P<N>.+?)".+>(?P<S>[\d.,]+) (?P<U>[\w^_]+)' OFFLINE_PATTERN = r'>File doesn\'t exist' - LINK_PREMIUM_PATTERN = LINK_FREE_PATTERN = r'(https?://[\w\-]+\.nitroflare\.com/.+?)"' + LINK_PREMIUM_PATTERN = LINK_FREE_PATTERN = r'(https?://[\w-]+\.nitroflare\.com/.+?)"' RECAPTCHA_KEY = "6Lenx_USAAAAAF5L1pmTWvWcH73dipAEzNnmNLgy" PREMIUM_ONLY_PATTERN = r'This file is available with Premium only' diff --git a/module/plugins/hoster/OpenloadIo.py b/module/plugins/hoster/OpenloadIo.py index ee67be95b..842879203 100644 --- a/module/plugins/hoster/OpenloadIo.py +++ b/module/plugins/hoster/OpenloadIo.py @@ -10,10 +10,10 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class OpenloadIo(SimpleHoster): __name__ = "OpenloadIo" __type__ = "hoster" - __version__ = "0.08" + __version__ = "0.09" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?openload\.(?:co|io)/(?:f|embed)/([\w\-]+)' + __pattern__ = r'https?://(?:www\.)?openload\.(co|io)/(f|embed)/(?P<ID>[\w-]+)' __description__ = """Openload.co hoster plugin""" __license__ = "GPLv3" @@ -23,8 +23,6 @@ class OpenloadIo(SimpleHoster): # The API reference, that this implementation uses is available at https://openload.co/api API_URL = 'https://api.openload.co/1' - _FILE_ID_PATTERN = '/(?:f|embed)/([\w\-]+)' - _DOWNLOAD_TICKET_URI_PATTERN = '/file/dlticket?file={0}' _DOWNLOAD_FILE_URI_PATTERN = '/file/dl?file={0}&ticket={1}' _FILE_INFO_URI_PATTERN = '/file/info?file={0}' @@ -39,11 +37,7 @@ class OpenloadIo(SimpleHoster): @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] + file_id = self.info['pattern']['ID'] info_json = cls._load_json(cls._FILE_INFO_URI_PATTERN.format(file_id)) file_info = info_json['result'][file_id] @@ -61,8 +55,7 @@ class OpenloadIo(SimpleHoster): 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] - + file_id = self.info['pattern']['ID'] ticket_json = self._load_json(self._DOWNLOAD_TICKET_URI_PATTERN.format(file_id)) self.wait(ticket_json['result']['wait_time']) diff --git a/module/plugins/hoster/SoundcloudCom.py b/module/plugins/hoster/SoundcloudCom.py index a7a45d028..b189ee1ba 100644 --- a/module/plugins/hoster/SoundcloudCom.py +++ b/module/plugins/hoster/SoundcloudCom.py @@ -12,7 +12,7 @@ class SoundcloudCom(SimpleHoster): __version__ = "0.12" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?soundcloud\.com/[\w\-]+/[\w\-]+' + __pattern__ = r'https?://(?:www\.)?soundcloud\.com/[\w-]+/[\w-]+' __config__ = [("use_premium", "bool" , "Use premium account if available", True ), ("quality" , "Lower;Higher", "Quality" , "Higher")] diff --git a/module/plugins/hoster/XFileSharingPro.py b/module/plugins/hoster/XFileSharingPro.py index c7d8a7761..a5d76763d 100644 --- a/module/plugins/hoster/XFileSharingPro.py +++ b/module/plugins/hoster/XFileSharingPro.py @@ -11,7 +11,7 @@ class XFileSharingPro(XFSHoster): __version__ = "0.54" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)' + __pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)' __description__ = """XFileSharingPro dummy hoster plugin for hook""" __license__ = "GPLv3" @@ -32,7 +32,7 @@ class XFileSharingPro(XFSHoster): self.__pattern__ = self.pyload.pluginManager.hosterPlugins[self.__name__]['pattern'] self.PLUGIN_DOMAIN = re.match(self.__pattern__, self.pyfile.url).group("DOMAIN").lower() - self.PLUGIN_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+|\-)', self.PLUGIN_DOMAIN) if part != '.') + self.PLUGIN_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+|-)', self.PLUGIN_DOMAIN) if part != '.') def _setup(self): diff --git a/module/plugins/hoster/YadiSk.py b/module/plugins/hoster/YadiSk.py index 418f38926..354ba1b4c 100644 --- a/module/plugins/hoster/YadiSk.py +++ b/module/plugins/hoster/YadiSk.py @@ -13,7 +13,7 @@ class YadiSk(SimpleHoster): __version__ = "0.06" __status__ = "testing" - __pattern__ = r'https?://yadi\.sk/d/[\w\-]+' + __pattern__ = r'https?://yadi\.sk/d/[\w-]+' __description__ = """Yadi.sk hoster plugin""" __license__ = "GPLv3" diff --git a/module/plugins/internal/Account.py b/module/plugins/internal/Account.py index 724322a4c..2ca01de0e 100644 --- a/module/plugins/internal/Account.py +++ b/module/plugins/internal/Account.py @@ -13,7 +13,7 @@ from module.utils import compare_time, lock class Account(Plugin): __name__ = "Account" __type__ = "account" - __version__ = "0.54" + __version__ = "0.55" __status__ = "testing" __description__ = """Base account plugin""" @@ -21,8 +21,8 @@ class Account(Plugin): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - LOGIN_TIMEOUT = 10 * 60 #: Relogin accounts every 10 minutes - AUTO_TIMEOUT = True #: Automatically adjust relogin interval + LOGIN_TIMEOUT = 30 * 60 #: Relogin accounts every 30 minutes + AUTO_INTERVAL = True #: Automatically adjust relogin interval def __init__(self, manager, accounts): @@ -34,8 +34,11 @@ class Account(Plugin): self.accounts = accounts #@TODO: Recheck in 0.4.10 self.user = None - self.interval = self.LOGIN_TIMEOUT - self.auto_timeout = self.interval if self.AUTO_TIMEOUT else False + self.timeout = self.LOGIN_TIMEOUT + + #: Callback of periodical job task + self.cb = None + self.interval = self.LOGIN_TIMEOUT self.init() @@ -47,6 +50,28 @@ class Account(Plugin): pass + def init_periodical(self, delay=0, threaded=False): + self.cb = self.pyload.scheduler.addJob(max(0, delay), self._periodical, [threaded], threaded=threaded) + + + def _periodical(self, threaded): + if self.interval < 0: + self.cb = None + return + + try: + self.periodical() + + except Exception, e: + self.log_error(_("Error executing periodical task: %s") % e) + + self.init_periodical(self.interval, threaded) + + + def periodical(self): + raise NotImplementedError + + @property def logged(self): """ @@ -57,7 +82,7 @@ class Account(Plugin): self.sync() - if self.info['login']['timestamp'] + self.interval < time.time(): + if self.info['login']['timestamp'] + self.timeout < time.time(): self.log_debug("Reached login timeout for user `%s`" % self.user) return False else: @@ -87,15 +112,17 @@ class Account(Plugin): self.sync() + timestamp = time.time() + try: - self.info['login']['timestamp'] = time.time() #: Set timestamp for login self.signin(self.user, self.info['login']['password'], self.info['data']) except Skip: self.info['login']['valid'] = True - if self.auto_timeout: - self.auto_timeout *= 3 - self.interval = self.auto_timeout + + new_timeout = timestamp - self.info['login']['timestamp'] + if self.AUTO_INTERVAL and new_timeout > self.timeout: + self.timeout = new_timeout except Exception, e: self.log_error(_("Could not login user `%s`") % user, e) @@ -103,12 +130,12 @@ class Account(Plugin): else: self.info['login']['valid'] = True - if self.interval is self.auto_timeout: - self.interval = self.auto_timeout / 3 - self.auto_timeout = False finally: + self.info['login']['timestamp'] = timestamp #: Set timestamp for login + self.syncback() + return bool(self.info['login']['valid']) @@ -399,9 +426,19 @@ class Account(Plugin): ########################################################################### - def parse_traffic(self, size, unit="KB"): #@NOTE: Returns kilobytes in 0.4.9 - size = re.search(r'(\d*[\.,]?\d+)', size).group(1) #@TODO: Recjeck in 0.4.10 - return parse_size(size, unit) / 1024 #@TODO: Remove `/ 1024` in 0.4.10 + def parse_traffic(self, size, unit="byte"): #@NOTE: Returns kilobytes in 0.4.9 + unit = unit.lower().strip() #@TODO: Remove in 0.4.10 + size = re.search(r'(\d*[\.,]?\d+)', size).group(1) #@TODO: Recheck in 0.4.10 + + self.log_debug("Size: %s" % size, "Unit: %s" % unit) + + #@NOTE: Remove in 0.4.10 + if unit.startswith('t'): + traffic = float(size.replace(',', '.')) * 1 << 40 + else: + traffic = parse_size(size, unit) + + return traffic / 1024 #@TODO: Remove `/ 1024` in 0.4.10 def fail_login(self, msg=_("Login handshake has failed")): diff --git a/module/plugins/internal/Addon.py b/module/plugins/internal/Addon.py index 371f1da1b..cf3f01df1 100644 --- a/module/plugins/internal/Addon.py +++ b/module/plugins/internal/Addon.py @@ -23,7 +23,7 @@ def threaded(fn): class Addon(Plugin): __name__ = "Addon" __type__ = "hook" #@TODO: Change to `addon` in 0.4.10 - __version__ = "0.06" + __version__ = "0.07" __status__ = "testing" __threaded__ = [] #@TODO: Remove in 0.4.10 @@ -105,7 +105,7 @@ class Addon(Plugin): def periodical(self): - pass + raise NotImplementedError @property diff --git a/module/plugins/internal/Base.py b/module/plugins/internal/Base.py index bc9ef9158..28bc47556 100644 --- a/module/plugins/internal/Base.py +++ b/module/plugins/internal/Base.py @@ -52,7 +52,7 @@ def check_abort(fn): class Base(Plugin): __name__ = "Base" __type__ = "base" - __version__ = "0.02" + __version__ = "0.03" __status__ = "testing" __pattern__ = r'^unmatchable$' @@ -270,6 +270,8 @@ class Base(Plugin): if self.thread.m.reconnecting.isSet(): self.waiting = False self.wantReconnect = False + + self.req.clearCookies() raise Reconnect time.sleep(2) @@ -334,6 +336,21 @@ class Base(Plugin): self.fail("temp. offline") + def restart(self, msg="", premium=True): + if not msg: + msg = _("Restart plugin") if premium else _("Fallback to free processing") + + if not premium: + if self.premium: + self.rst_free = True + else: + self.fail("%s | %s" % (msg, _("Url was already processed as free"))) + + self.req.clearCookies() + + raise Retry(encode(msg)) #@TODO: Remove `encode` in 0.4.10 + + def retry(self, attemps=5, wait=1, msg=""): """ Retries and begin again from the beginning diff --git a/module/plugins/internal/Crypter.py b/module/plugins/internal/Crypter.py index a5c88aed9..cc1eeb5fd 100644 --- a/module/plugins/internal/Crypter.py +++ b/module/plugins/internal/Crypter.py @@ -7,7 +7,7 @@ from module.utils import save_path as safe_filename class Crypter(Base): __name__ = "Crypter" __type__ = "crypter" - __version__ = "0.11" + __version__ = "0.12" __status__ = "testing" __pattern__ = r'^unmatchable$' @@ -83,11 +83,12 @@ class Crypter(Base): subfolder_per_package = self.get_config('subfolder_per_package', True) for name, links, folder in self.packages: - self.log_debug("Parsed package: %s" % name, - "%d links" % len(links), - "Saved to folder: %s" % folder if folder else "Saved to download folder") + self.log_info(_("Parsed package: %s") % name, + _("Found %d links") % len(links), + _("Saved to folder: %s") % folder if folder else _("Saved to default download folder")) links = map(self.fixurl, links) + self.log_debug("LINKS for package " + name, *links) pid = self.pyload.api.addPackage(name, links, package_queue) diff --git a/module/plugins/internal/Hook.py b/module/plugins/internal/Hook.py index 8ae731a7f..6ead5cf0b 100644 --- a/module/plugins/internal/Hook.py +++ b/module/plugins/internal/Hook.py @@ -6,7 +6,7 @@ from module.plugins.internal.Addon import Addon, threaded class Hook(Addon): __name__ = "Hook" __type__ = "hook" - __version__ = "0.13" + __version__ = "0.14" __status__ = "testing" __description__ = """Base hook plugin""" @@ -24,3 +24,7 @@ class Hook(Addon): #@TODO: Remove in 0.4.10 def _log(self, level, plugintype, pluginname, messages): return super(Addon, self)._log(level, plugintype, pluginname.replace("Hook", ""), messages) + + + def periodical(self): + pass diff --git a/module/plugins/internal/Hoster.py b/module/plugins/internal/Hoster.py index 86b684414..b0458ca95 100644 --- a/module/plugins/internal/Hoster.py +++ b/module/plugins/internal/Hoster.py @@ -13,7 +13,7 @@ from module.utils import fs_decode, fs_encode, save_join as fs_join, save_path a class Hoster(Base): __name__ = "Hoster" __type__ = "hoster" - __version__ = "0.35" + __version__ = "0.36" __status__ = "testing" __pattern__ = r'^unmatchable$' @@ -93,19 +93,6 @@ class Hoster(Base): raise Fail(e) - def restart(self, msg="", premium=True): - if not msg: - msg = _("Simple restart") if premium else _("Fallback to free download") - - if not premium: - if self.premium: - self.rst_free = True - else: - self.fail("%s | %s" % (msg, _("Download was already free"))) - - raise Retry(encode(msg)) #@TODO: Remove `encode` in 0.4.10 - - @check_abort def download(self, url, get={}, post={}, ref=True, cookies=True, disposition=True): """ @@ -291,8 +278,10 @@ class Hoster(Base): return True else: - size = self.pyfile.size / 1024 #@TODO: Remove in 0.4.10 - self.log_info(_("Filesize: %s KiB, Traffic left for user %s: %s KiB") % (size, self.account.user, traffic)) #@TODO: Rewrite in 0.4.10 + #@TODO: Rewrite in 0.4.10 + size = self.pyfile.size / 1024 + self.log_info(_("Filesize: %s KiB") % size, + _("Traffic left for user %s: %s KiB") % (self.account.user, traffic)) return size <= traffic diff --git a/module/plugins/internal/Plugin.py b/module/plugins/internal/Plugin.py index cc35d919c..9d2aa8b50 100644 --- a/module/plugins/internal/Plugin.py +++ b/module/plugins/internal/Plugin.py @@ -109,10 +109,8 @@ def parse_time(string): time = seconds_to_midnight() else: - this = re.compile("this", re.I) - regex = re.compile(r'(\d+|[\w\-]+)\s*(hr|hour|min|sec|)', re.I) - - time = sum(1 if this.match(v) else str2int(v) * + regex = re.compile(r'(\d+| (?:this|an?) )\s*(hr|hour|min|sec|)', re.I) + time = sum((int(v) if v.strip() not in ("this", "a", "an") else 1) * {'hr': 3600, 'hour': 3600, 'min': 60, 'sec': 1, '': 1}[u.lower()] for v, u in regex.findall(string)) @@ -228,7 +226,7 @@ def chunks(iterable, size): class Plugin(object): __name__ = "Plugin" __type__ = "plugin" - __version__ = "0.46" + __version__ = "0.47" __status__ = "testing" __pattern__ = r'^unmatchable$' diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index 30b8ebfb0..d4ecd3117 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -10,7 +10,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class SimpleCrypter(Crypter, SimpleHoster): __name__ = "SimpleCrypter" __type__ = "crypter" - __version__ = "0.65" + __version__ = "0.66" __status__ = "testing" __pattern__ = r'^unmatchable$' @@ -139,8 +139,6 @@ class SimpleCrypter(Crypter, SimpleHoster): if self.PAGES_PATTERN: self.handle_pages(pyfile) - self.log_debug("Package has %d links" % len(self.links)) - if self.link: self.urls.append(self.link) diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index 8f1b3ac5d..7e759b593 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -385,7 +385,7 @@ class SimpleHoster(Hoster): elif re.search('countdown|expired', errmsg, re.I): self.retry(10, 60, _("Link expired")) - elif re.search('maintenance|maintainance|temp', errmsg, re.I): + elif re.search('maint(e|ai)nance|temp', errmsg, re.I): self.temp_offline() elif re.search('up to|size', errmsg, re.I): diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py index 908689109..39a919ec6 100644 --- a/module/plugins/internal/UnRar.py +++ b/module/plugins/internal/UnRar.py @@ -38,7 +38,7 @@ class UnRar(Extractor): re_multipart = re.compile(r'\.(part|r)(\d+)(?:\.rar)?(\.rev|\.bad)?', re.I) re_filefixed = re.compile(r'Building (.+)') - re_filelist = re.compile(r'^(.)(\s*[\w\.\-]+)\s+(\d+\s+)+(?:\d+\%\s+)?[\d\-]{8}\s+[\d\:]{5}', re.M|re.I) + re_filelist = re.compile(r'^(.)(\s*[\w.-]+)\s+(\d+\s+)+(?:\d+\%\s+)?[\d-]{8}\s+[\d\:]{5}', re.M|re.I) re_wrongpwd = re.compile(r'password', re.I) re_wrongcrc = re.compile(r'encrypted|damaged|CRC failed|checksum error|corrupt', re.I) |