diff options
Diffstat (limited to 'module')
29 files changed, 784 insertions, 54 deletions
diff --git a/module/plugins/hooks/AlldebridComHook.py b/module/plugins/hooks/AlldebridComHook.py index 3d05fb761..367181aa4 100644 --- a/module/plugins/hooks/AlldebridComHook.py +++ b/module/plugins/hooks/AlldebridComHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class AlldebridCom(MultiHook): - __name__ = "AlldebridCom" +class AlldebridComHook(MultiHook): + __name__ = "AlldebridComHook" __type__ = "hook" __version__ = "0.16" diff --git a/module/plugins/hooks/DebridItaliaComHook.py b/module/plugins/hooks/DebridItaliaComHook.py index e7760ba5a..c1452b520 100644 --- a/module/plugins/hooks/DebridItaliaComHook.py +++ b/module/plugins/hooks/DebridItaliaComHook.py @@ -5,8 +5,8 @@ import re from pyload.plugin.internal.MultiHook import MultiHook -class DebridItaliaCom(MultiHook): - __name__ = "DebridItaliaCom" +class DebridItaliaComHook(MultiHook): + __name__ = "DebridItaliaComHook" __type__ = "hook" __version__ = "0.12" diff --git a/module/plugins/hooks/EasybytezComHook.py b/module/plugins/hooks/EasybytezComHook.py index 79640a367..2f4ed72a8 100644 --- a/module/plugins/hooks/EasybytezComHook.py +++ b/module/plugins/hooks/EasybytezComHook.py @@ -5,8 +5,8 @@ import re from pyload.plugin.internal.MultiHook import MultiHook -class EasybytezCom(MultiHook): - __name__ = "EasybytezCom" +class EasybytezComHook(MultiHook): + __name__ = "EasybytezComHook" __type__ = "hook" __version__ = "0.07" diff --git a/module/plugins/hooks/FastixRuHook.py b/module/plugins/hooks/FastixRuHook.py index d0e2ff2fd..4e03e887b 100644 --- a/module/plugins/hooks/FastixRuHook.py +++ b/module/plugins/hooks/FastixRuHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class FastixRu(MultiHook): - __name__ = "FastixRu" +class FastixRuHook(MultiHook): + __name__ = "FastixRuHook" __type__ = "hook" __version__ = "0.05" diff --git a/module/plugins/hooks/FreeWayMeHook.py b/module/plugins/hooks/FreeWayMeHook.py index 086824550..c498725f5 100644 --- a/module/plugins/hooks/FreeWayMeHook.py +++ b/module/plugins/hooks/FreeWayMeHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class FreeWayMe(MultiHook): - __name__ = "FreeWayMe" +class FreeWayMeHook(MultiHook): + __name__ = "FreeWayMeHook" __type__ = "hook" __version__ = "0.15" diff --git a/module/plugins/hooks/LinkdecrypterComHook.py b/module/plugins/hooks/LinkdecrypterComHook.py index ab1e662dc..d8c0018c9 100644 --- a/module/plugins/hooks/LinkdecrypterComHook.py +++ b/module/plugins/hooks/LinkdecrypterComHook.py @@ -5,15 +5,16 @@ import re from pyload.plugin.internal.MultiHook import MultiHook -class LinkdecrypterCom(MultiHook): - __name__ = "LinkdecrypterCom" +class LinkdecrypterComHook(MultiHook): + __name__ = "LinkdecrypterComHook" __type__ = "hook" - __version__ = "1.03" + __version__ = "1.04" - __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"), - ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ), - ("reload" , "bool" , "Reload plugin list" , True ), - ("reloadinterval", "int" , "Reload interval in hours" , 12 )] + __config__ = [("activated" , "bool" , "Activated" , True ), + ("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"), + ("pluginlist" , "str" , "Plugin list (comma separated)", "" ), + ("reload" , "bool" , "Reload plugin list" , True ), + ("reloadinterval", "int" , "Reload interval in hours" , 12 )] __description__ = """Linkdecrypter.com hook plugin""" __license__ = "GPLv3" diff --git a/module/plugins/hooks/LinksnappyComHook.py b/module/plugins/hooks/LinksnappyComHook.py index 7eddc5811..22b958b31 100644 --- a/module/plugins/hooks/LinksnappyComHook.py +++ b/module/plugins/hooks/LinksnappyComHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class LinksnappyCom(MultiHook): - __name__ = "LinksnappyCom" +class LinksnappyComHook(MultiHook): + __name__ = "LinksnappyComHook" __type__ = "hook" __version__ = "0.04" diff --git a/module/plugins/hooks/MegaDebridEuHook.py b/module/plugins/hooks/MegaDebridEuHook.py index e373a544b..1d086b9d1 100644 --- a/module/plugins/hooks/MegaDebridEuHook.py +++ b/module/plugins/hooks/MegaDebridEuHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class MegaDebridEu(MultiHook): - __name__ = "MegaDebridEu" +class MegaDebridEuHook(MultiHook): + __name__ = "MegaDebridEuHook" __type__ = "hook" __version__ = "0.05" diff --git a/module/plugins/hooks/MegaRapidoNetHook.py b/module/plugins/hooks/MegaRapidoNetHook.py index 2f660c939..1fe8d4923 100644 --- a/module/plugins/hooks/MegaRapidoNetHook.py +++ b/module/plugins/hooks/MegaRapidoNetHook.py @@ -5,8 +5,8 @@ import re from pyload.plugin.internal.MultiHook import MultiHook -class MegaRapidoNet(MultiHook): - __name__ = "MegaRapidoNet" +class MegaRapidoNetHook(MultiHook): + __name__ = "MegaRapidoNetHook" __type__ = "hook" __version__ = "0.02" diff --git a/module/plugins/hooks/MultishareCzHook.py b/module/plugins/hooks/MultishareCzHook.py index 21e200584..70cc8d7a9 100644 --- a/module/plugins/hooks/MultishareCzHook.py +++ b/module/plugins/hooks/MultishareCzHook.py @@ -5,8 +5,8 @@ import re from pyload.plugin.internal.MultiHook import MultiHook -class MultishareCz(MultiHook): - __name__ = "MultishareCz" +class MultishareCzHook(MultiHook): + __name__ = "MultishareCzHook" __type__ = "hook" __version__ = "0.07" @@ -21,7 +21,7 @@ class MultishareCz(MultiHook): __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] - HOSTER_PATTERN = r'<img class="logo-shareserveru"[^>]*?alt="([^"]+)"></td>\s*<td class="stav">[^>]*?alt="OK"' + HOSTER_PATTERN = r'<img class="logo-shareserveru"[^>]*?alt="(.+?)"></td>\s*<td class="stav">[^>]*?alt="OK"' def getHosters(self): diff --git a/module/plugins/hooks/MyfastfileComHook.py b/module/plugins/hooks/MyfastfileComHook.py index 3149e832c..a9438f400 100644 --- a/module/plugins/hooks/MyfastfileComHook.py +++ b/module/plugins/hooks/MyfastfileComHook.py @@ -4,8 +4,8 @@ from pyload.plugin.internal.MultiHook import MultiHook from pyload.utils import json_loads -class MyfastfileCom(MultiHook): - __name__ = "MyfastfileCom" +class MyfastfileComHook(MultiHook): + __name__ = "MyfastfileComHook" __type__ = "hook" __version__ = "0.05" diff --git a/module/plugins/hooks/NoPremiumPlHook.py b/module/plugins/hooks/NoPremiumPlHook.py index 93c5b8d1e..743f18fc0 100644 --- a/module/plugins/hooks/NoPremiumPlHook.py +++ b/module/plugins/hooks/NoPremiumPlHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class NoPremiumPl(MultiHook): - __name__ = "NoPremiumPl" +class NoPremiumPlHook(MultiHook): + __name__ = "NoPremiumPlHook" __type__ = "hook" __version__ = "0.03" diff --git a/module/plugins/hooks/OverLoadMeHook.py b/module/plugins/hooks/OverLoadMeHook.py index 6db7c1fa2..58d419416 100644 --- a/module/plugins/hooks/OverLoadMeHook.py +++ b/module/plugins/hooks/OverLoadMeHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class OverLoadMe(MultiHook): - __name__ = "OverLoadMe" +class OverLoadMeHook(MultiHook): + __name__ = "OverLoadMeHook" __type__ = "hook" __version__ = "0.04" diff --git a/module/plugins/hooks/PremiumToHook.py b/module/plugins/hooks/PremiumToHook.py index 51e801c4f..8cd2ef0e5 100644 --- a/module/plugins/hooks/PremiumToHook.py +++ b/module/plugins/hooks/PremiumToHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class PremiumTo(MultiHook): - __name__ = "PremiumTo" +class PremiumToHook(MultiHook): + __name__ = "PremiumToHook" __type__ = "hook" __version__ = "0.08" diff --git a/module/plugins/hooks/PremiumizeMeHook.py b/module/plugins/hooks/PremiumizeMeHook.py index 209db7c75..1b6444f00 100644 --- a/module/plugins/hooks/PremiumizeMeHook.py +++ b/module/plugins/hooks/PremiumizeMeHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class PremiumizeMe(MultiHook): - __name__ = "PremiumizeMe" +class PremiumizeMeHook(MultiHook): + __name__ = "PremiumizeMeHook" __type__ = "hook" __version__ = "0.17" diff --git a/module/plugins/hooks/RPNetBizHook.py b/module/plugins/hooks/RPNetBizHook.py index e8afb4fc0..c7893ef46 100644 --- a/module/plugins/hooks/RPNetBizHook.py +++ b/module/plugins/hooks/RPNetBizHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class RPNetBiz(MultiHook): - __name__ = "RPNetBiz" +class RPNetBizHook(MultiHook): + __name__ = "RPNetBizHook" __type__ = "hook" __version__ = "0.14" diff --git a/module/plugins/hooks/RapideoPlHook.py b/module/plugins/hooks/RapideoPlHook.py index 74bad2cfd..dd68fb244 100644 --- a/module/plugins/hooks/RapideoPlHook.py +++ b/module/plugins/hooks/RapideoPlHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class RapideoPl(MultiHook): - __name__ = "RapideoPl" +class RapideoPlHook(MultiHook): + __name__ = "RapideoPlHook" __type__ = "hook" __version__ = "0.03" diff --git a/module/plugins/hooks/RealdebridComHook.py b/module/plugins/hooks/RealdebridComHook.py index 74a114105..6399d6dc2 100644 --- a/module/plugins/hooks/RealdebridComHook.py +++ b/module/plugins/hooks/RealdebridComHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class RealdebridCom(MultiHook): - __name__ = "RealdebridCom" +class RealdebridComHook(MultiHook): + __name__ = "RealdebridComHook" __type__ = "hook" __version__ = "0.46" diff --git a/module/plugins/hooks/RehostToHook.py b/module/plugins/hooks/RehostToHook.py index 69978edaa..b55f4cdb7 100644 --- a/module/plugins/hooks/RehostToHook.py +++ b/module/plugins/hooks/RehostToHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class RehostTo(MultiHook): - __name__ = "RehostTo" +class RehostToHook(MultiHook): + __name__ = "RehostToHook" __type__ = "hook" __version__ = "0.50" diff --git a/module/plugins/hooks/SimplyPremiumComHook.py b/module/plugins/hooks/SimplyPremiumComHook.py index 9f696666f..ee125cbf6 100644 --- a/module/plugins/hooks/SimplyPremiumComHook.py +++ b/module/plugins/hooks/SimplyPremiumComHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class SimplyPremiumCom(MultiHook): - __name__ = "SimplyPremiumCom" +class SimplyPremiumComHook(MultiHook): + __name__ = "SimplyPremiumComHook" __type__ = "hook" __version__ = "0.05" diff --git a/module/plugins/hooks/SimplydebridComHook.py b/module/plugins/hooks/SimplydebridComHook.py index 74eba106e..2e9da87bd 100644 --- a/module/plugins/hooks/SimplydebridComHook.py +++ b/module/plugins/hooks/SimplydebridComHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class SimplydebridCom(MultiHook): - __name__ = "SimplydebridCom" +class SimplydebridComHook(MultiHook): + __name__ = "SimplydebridComHook" __type__ = "hook" __version__ = "0.04" diff --git a/module/plugins/hooks/SmoozedComHook.py b/module/plugins/hooks/SmoozedComHook.py index 37c0d9bcb..786f85491 100644 --- a/module/plugins/hooks/SmoozedComHook.py +++ b/module/plugins/hooks/SmoozedComHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class SmoozedCom(MultiHook): - __name__ = "SmoozedCom" +class SmoozedComHook(MultiHook): + __name__ = "SmoozedComHook" __type__ = "hook" __version__ = "0.03" diff --git a/module/plugins/hooks/UnrestrictLiHook.py b/module/plugins/hooks/UnrestrictLiHook.py index a0fb53004..8f9bdaaf5 100644 --- a/module/plugins/hooks/UnrestrictLiHook.py +++ b/module/plugins/hooks/UnrestrictLiHook.py @@ -4,8 +4,8 @@ from pyload.utils import json_loads from pyload.plugin.internal.MultiHook import MultiHook -class UnrestrictLi(MultiHook): - __name__ = "UnrestrictLi" +class UnrestrictLiHook(MultiHook): + __name__ = "UnrestrictLiHook" __type__ = "hook" __version__ = "0.05" diff --git a/module/plugins/hooks/UserAgentSwitcher.py b/module/plugins/hooks/UserAgentSwitcher.py new file mode 100644 index 000000000..912c2ef09 --- /dev/null +++ b/module/plugins/hooks/UserAgentSwitcher.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +from __future__ import with_statement + +import os +import pycurl +import random + +from module.plugins.Hook import Hook +from module.utils import fs_encode + + +class UserAgentSwitcher(Hook): + __name__ = "UserAgentSwitcher" + __type__ = "hook" + __version__ = "0.04" + + __config__ = [("activated", "bool", "Activated" , True ), + ("uaf" , "file", "Random user-agents file" , "" ), + ("uar" , "bool", "Random user-agent" , False ), + ("uas" , "str" , "Custom user-agent string", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0")] + + __description__ = """Custom user-agent""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + interval = 0 #@TODO: Remove in 0.4.10 + + + def setup(self): + self.info = {} #@TODO: Remove in 0.4.10 + + + def downloadPreparing(self, pyfile): + uar = self.getConfig('uar') + uaf = fs_encode(self.getConfig('uaf')) + + if uar and os.path.isfile(uaf): + with open(uaf) as f: + uas = random.choice([ua for ua in f.read().splitlines()]) + else: + uas = self.getConfig('uas') + + if uas: + self.logDebug("Use custom user-agent string: " + uas) + pyfile.plugin.req.http.c.setopt(pycurl.USERAGENT, uas.encode('utf-8')) diff --git a/module/plugins/hooks/ZeveraComHook.py b/module/plugins/hooks/ZeveraComHook.py index 0ca2e72d2..83723351e 100644 --- a/module/plugins/hooks/ZeveraComHook.py +++ b/module/plugins/hooks/ZeveraComHook.py @@ -3,8 +3,8 @@ from pyload.plugin.internal.MultiHook import MultiHook -class ZeveraCom(MultiHook): - __name__ = "ZeveraCom" +class ZeveraComHook(MultiHook): + __name__ = "ZeveraComHook" __type__ = "hook" __version__ = "0.05" diff --git a/module/plugins/hoster/LolabitsEs.py b/module/plugins/hoster/LolabitsEs.py new file mode 100644 index 000000000..61df5f0bb --- /dev/null +++ b/module/plugins/hoster/LolabitsEs.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -* + +import HTMLParser +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class LolabitsEs(SimpleHoster): + __name__ = "LolabitsEs" + __type__ = "hoster" + __version__ = "0.02" + + __pattern__ = r'https?://(?:www\.)?lolabits\.es/.+' + + __description__ = """Lolabits.es hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")] + + + NAME_PATTERN = r'Descargar: <b>(?P<N>.+?)<' + SIZE_PATTERN = r'class="fileSize">(?P<S>[\d.,]+) (?P<U>[\w^_]+)' + OFFLINE_PATTERN = r'Un usuario con este nombre no existe' + + FILEID_PATTERN = r'name="FileId" value="(\d+)"' + TOKEN_PATTERN = r'name="__RequestVerificationToken" type="hidden" value="(.+?)"' + LINK_PATTERN = r'"redirectUrl":"(.+?)"' + + + def setup(self): + self.chunkLimit = 1 + + + def handleFree(self, pyfile): + fileid = re.search(self.FILEID_PATTERN, self.html).group(1) + self.logDebug("FileID: " + fileid) + + token = re.search(self.TOKEN_PATTERN, self.html).group(1) + self.logDebug("Token: " + token) + + self.html = self.load("http://lolabits.es/action/License/Download", + post={'fileId' : fileid, + '__RequestVerificationToken' : token}).decode('unicode-escape') + + self.link = HTMLParser.HTMLParser().unescape(re.search(self.LINK_PATTERN, self.html).group(1)) + + +getInfo = create_getInfo(LolabitsEs) diff --git a/module/plugins/hoster/SolidfilesCom.py b/module/plugins/hoster/SolidfilesCom.py new file mode 100644 index 000000000..d359577d6 --- /dev/null +++ b/module/plugins/hoster/SolidfilesCom.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Test links: +# http://www.solidfiles.com/d/609cdb4b1b + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class SolidfilesCom(SimpleHoster): + __name__ = "SolidfilesCom" + __type__ = "hoster" + __version__ = "0.02" + + __pattern__ = r'http://(?:www\.)?solidfiles\.com\/d/\w+' + + __description__ = """Solidfiles.com hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("sraedler", "simon.raedler@yahoo.de")] + + + NAME_PATTERN = r'<h1 title="(?P<N>.+?)"' + SIZE_PATTERN = r'<p class="meta">(?P<S>[\d.,]+) (?P<U>[\w_^]+)' + OFFLINE_PATTERN = r'<h1>404' + + LINK_FREE_PATTERN = r'id="ddl-text" href="(.+?)"' + + + def setup(self): + self.multiDL = True + self.chunkLimit = 1 + + +getInfo = create_getInfo(SolidfilesCom) diff --git a/module/plugins/hoster/YadiSk.py b/module/plugins/hoster/YadiSk.py new file mode 100644 index 000000000..c3749d30d --- /dev/null +++ b/module/plugins/hoster/YadiSk.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +import re +import random + +from module.common.json_layer import json_loads +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class YadiSk(SimpleHoster): + __name__ = "YadiSk" + __type__ = "hoster" + __version__ = "0.03" + + __pattern__ = r'https?://yadi\.sk/d/\w+' + + __description__ = """Yadi.sk hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("GammaC0de", None)] + + + OFFLINE_PATTERN = r'Nothing found' + + + def setup(self): + self.resumeDownload = False + self.multiDL = False + self.chunkLimit = 1 + + + def handleFree(self, pyfile): + m = re.search(r'<script id="models-client" type="application/json">(.+?)</script>', self.html) + if m is None: + self.error(_("could not find required json data")) + + res = json_loads(m.group(1)) + + yadisk_ver = None + yadisk_sk = None + yadisk_id = None + yadisk_size = None + yadisk_name = None + + try: #@TODO: Copy to apiInfo + for sect in res: + if 'model' in sect: + if sect['model'] == "config": + yadisk_ver = sect['data']['version'] + yadisk_sk = sect['data']['sk'] + + elif sect['model'] == "resource": + yadisk_id = sect['data']['id'] + yadisk_size = sect['data']['meta']['size'] + yadisk_name = sect['data']['name'] + + except Exception, e: + self.fail(_("Unexpected server response"), e) + + if None in (yadisk_id, yadisk_sk, yadisk_id, yadisk_size, yadisk_name): + self.error(_("Missing JSON data")) + + self.pyfile.size = yadisk_size + self.pyfile.name = yadisk_name + + yadisk_idclient = "" + for _i in range(32): + yadisk_idclient += random.choice('0123456abcdef') + + try: + self.html = self.load("https://yadi.sk/models/", + get={'_m': "do-get-resource-url"}, + post={'idClient': yadisk_idclient, + 'version' : yadisk_ver, + '_model.0': "do-get-resource-url", + 'sk' : yadisk_sk, + 'id.0' : yadisk_id}) + + self.link = json_loads(self.html)['models'][0]['data']['file'] + + except Exception: + pass + + +getInfo = create_getInfo(YadiSk) diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py new file mode 100644 index 000000000..ec938079a --- /dev/null +++ b/module/plugins/internal/CaptchaService.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- + +import re +import time + +from base64 import b64encode +from random import random, randint +from urlparse import urljoin, urlparse + +from module.common.json_layer import json_loads +from module.plugins.Plugin import Base + + +#@TODO: Extend (new) Plugin class; remove all `html` args +class CaptchaService(Base): + __name__ = "CaptchaService" + __type__ = "captcha" + __version__ = "0.26" + + __description__ = """Base captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + key = None #: last key detected + + + def __init__(self, plugin): + self.plugin = plugin + super(CaptchaService, self).__init__(plugin.core) + + + def detect_key(self, html=None): + raise NotImplementedError + + + def challenge(self, key=None, html=None): + raise NotImplementedError + + + def result(self, server, challenge): + raise NotImplementedError + + +class ReCaptcha(CaptchaService): + __name__ = "ReCaptcha" + __type__ = "captcha" + __version__ = "0.15" + + __description__ = """ReCaptcha captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org"), + ("Walter Purcaro", "vuolter@gmail.com"), + ("zapp-brannigan", "fuerst.reinje@web.de")] + + + KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)' + KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)' + + + def detect_key(self, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("ReCaptcha html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + m = re.search(self.KEY_V2_PATTERN, html) or re.search(self.KEY_V1_PATTERN, html) + if m: + self.key = m.group(1).strip() + self.logDebug("Key: %s" % self.key) + return self.key + else: + self.logDebug("Key not found") + return None + + + def challenge(self, key=None, html=None, version=None): + if not key: + if self.detect_key(html): + key = self.key + else: + errmsg = _("ReCaptcha key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + if version in (1, 2): + return getattr(self, "_challenge_v%s" % version)(key) + + elif not html and hasattr(self.plugin, "html") and self.plugin.html: + version = 2 if re.search(self.KEY_V2_PATTERN, self.plugin.html) else 1 + return self.challenge(key, self.plugin.html, version) + + else: + errmsg = _("ReCaptcha html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + + def _challenge_v1(self, key): + html = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge", + get={'k': key}) + try: + challenge = re.search("challenge : '(.+?)',", html).group(1) + server = re.search("server : '(.+?)',", html).group(1) + + except AttributeError: + errmsg = _("ReCaptcha challenge pattern not found") + self.plugin.fail(errmsg) + raise AttributeError(errmsg) + + self.logDebug("Challenge: %s" % challenge) + + return self.result(server, challenge), challenge + + + def result(self, server, challenge): + result = self.plugin.decryptCaptcha("%simage" % server, + get={'c': challenge}, + cookies=True, + forceUser=True, + imgtype="jpg") + + self.logDebug("Result: %s" % result) + + return result + + + def _collectApiInfo(self): + html = self.plugin.req.load("http://www.google.com/recaptcha/api.js") + a = re.search(r'po.src = \'(.*?)\';', html).group(1) + vers = a.split("/")[5] + + self.logDebug("API version: %s" %vers) + + language = a.split("__")[1].split(".")[0] + + self.logDebug("API language: %s" % language) + + html = self.plugin.req.load("https://apis.google.com/js/api.js") + b = re.search(r'"h":"(.*?)","', html).group(1) + jsh = b.decode('unicode-escape') + + self.logDebug("API jsh-string: %s" % jsh) + + return vers, language, jsh + + + def _prepareTimeAndRpc(self): + self.plugin.req.load("http://www.google.com/recaptcha/api2/demo") + + millis = int(round(time.time() * 1000)) + + self.logDebug("Time: %s" % millis) + + rand = randint(1, 99999999) + a = "0.%s" % str(rand * 2147483647) + rpc = int(100000000 * float(a)) + + self.logDebug("Rpc-token: %s" % rpc) + + return millis, rpc + + + def _challenge_v2(self, key, parent=None): + if parent is None: + try: + parent = urljoin("http://", urlparse(self.plugin.pyfile.url).netloc) + + except Exception: + parent = "" + + botguardstring = "!A" + vers, language, jsh = self._collectApiInfo() + millis, rpc = self._prepareTimeAndRpc() + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/anchor", + get={'k' : key, + 'hl' : language, + 'v' : vers, + 'usegapi' : "1", + 'jsh' : "%s#id=IO_%s" % (jsh, millis), + 'parent' : parent, + 'pfname' : "", + 'rpctoken': rpc}) + + token1 = re.search(r'id="recaptcha-token" value="(.*?)">', html) + self.logDebug("Token #1: %s" % token1.group(1)) + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/frame", + get={'c' : token1.group(1), + 'hl' : language, + 'v' : vers, + 'bg' : botguardstring, + 'k' : key, + 'usegapi': "1", + 'jsh' : jsh}).decode('unicode-escape') + + token2 = re.search(r'"finput","(.*?)",', html) + self.logDebug("Token #2: %s" % token2.group(1)) + + token3 = re.search(r'"rresp","(.*?)",', html) + self.logDebug("Token #3: %s" % token3.group(1)) + + millis_captcha_loading = int(round(time.time() * 1000)) + captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload", + get={'c':token3.group(1), 'k':key}, + cookies=True, + forceUser=True) + response = b64encode('{"response":"%s"}' % captcha_response) + + self.logDebug("Result: %s" % response) + + timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading + timeToSolveMore = timeToSolve + int(float("0." + str(randint(1, 99999999))) * 500) + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify", + post={'k' : key, + 'c' : token3.group(1), + 'response': response, + 't' : timeToSolve, + 'ct' : timeToSolveMore, + 'bg' : botguardstring}) + + token4 = re.search(r'"uvresp","(.*?)",', html) + self.logDebug("Token #4: %s" % token4.group(1)) + + result = token4.group(1) + + return result, None + + +class AdsCaptcha(CaptchaService): + __name__ = "AdsCaptcha" + __type__ = "captcha" + __version__ = "0.08" + + __description__ = """AdsCaptcha captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + CAPTCHAID_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?.*?CaptchaId=(\d+)' + PUBLICKEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?.*?PublicKey=([\w-]+)' + + + def detect_key(self, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("AdsCaptcha html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + m = re.search(self.PUBLICKEY_PATTERN, html) + n = re.search(self.CAPTCHAID_PATTERN, html) + if m and n: + self.key = (m.group(1).strip(), n.group(1).strip()) #: key is the tuple(PublicKey, CaptchaId) + self.logDebug("Key|id: %s | %s" % self.key) + return self.key + else: + self.logDebug("Key or id not found") + return None + + + def challenge(self, key=None, html=None): + if not key: + if self.detect_key(html): + key = self.key + else: + errmsg = _("AdsCaptcha key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + PublicKey, CaptchaId = key + + html = self.plugin.req.load("http://api.adscaptcha.com/Get.aspx", + get={'CaptchaId': CaptchaId, + 'PublicKey': PublicKey}) + try: + challenge = re.search("challenge: '(.+?)',", html).group(1) + server = re.search("server: '(.+?)',", html).group(1) + + except AttributeError: + errmsg = _("AdsCaptcha challenge pattern not found") + self.plugin.fail(errmsg) + raise AttributeError(errmsg) + + self.logDebug("Challenge: %s" % challenge) + + return self.result(server, challenge), challenge + + + def result(self, server, challenge): + result = self.plugin.decryptCaptcha("%sChallenge.aspx" % server, + get={'cid': challenge, 'dummy': random()}, + cookies=True, + imgtype="jpg") + + self.logDebug("Result: %s" % result) + + return result + + +class SolveMedia(CaptchaService): + __name__ = "SolveMedia" + __type__ = "captcha" + __version__ = "0.12" + + __description__ = """SolveMedia captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']' + + + def detect_key(self, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("SolveMedia html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + m = re.search(self.KEY_PATTERN, html) + if m: + self.key = m.group(1).strip() + self.logDebug("Key: %s" % self.key) + return self.key + else: + self.logDebug("Key not found") + return None + + + def challenge(self, key=None, html=None): + if not key: + if self.detect_key(html): + key = self.key + else: + errmsg = _("SolveMedia key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + html = self.plugin.req.load("http://api.solvemedia.com/papi/challenge.noscript", + get={'k': key}) + try: + challenge = re.search(r'<input type=hidden name="adcopy_challenge" id="adcopy_challenge" value="(.+?)">', + html).group(1) + server = "http://api.solvemedia.com/papi/media" + + except AttributeError: + errmsg = _("SolveMedia challenge pattern not found") + self.plugin.fail(errmsg) + raise AttributeError(errmsg) + + self.logDebug("Challenge: %s" % challenge) + + result = self.result(server, challenge) + + try: + magic = re.search(r'name="magic" value="(.+?)"', html).group(1) + + except AttributeError: + self.logDebug("Magic code not found") + + else: + if not self._verify(key, magic, result, challenge): + self.logDebug("Captcha code was invalid") + + return result, challenge + + + def _verify(self, key, magic, result, challenge, ref=None): #@TODO: Clean up + if ref is None: + try: + ref = self.plugin.pyfile.url + + except Exception: + ref = "" + + html = self.plugin.req.load("http://api.solvemedia.com/papi/verify.noscript", + post={'adcopy_response' : result, + 'k' : key, + 'l' : "en", + 't' : "img", + 's' : "standard", + 'magic' : magic, + 'adcopy_challenge' : challenge, + 'ref' : ref}) + try: + html = self.plugin.req.load(re.search(r'URL=(.+?)">', html).group(1)) + gibberish = re.search(r'id=gibberish>(.+?)</textarea>', html).group(1) + + except Exception: + return False + + else: + return True + + + def result(self, server, challenge): + result = self.plugin.decryptCaptcha(server, + get={'c': challenge}, + cookies=True, + imgtype="gif") + + self.logDebug("Result: %s" % result) + + return result + + +class AdYouLike(CaptchaService): + __name__ = "AdYouLike" + __type__ = "captcha" + __version__ = "0.05" + + __description__ = """AdYouLike captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + AYL_PATTERN = r'Adyoulike\.create\s*\((.+?)\)' + CALLBACK_PATTERN = r'(Adyoulike\.g\._jsonp_\d+)' + + + def detect_key(self, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("AdYouLike html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + m = re.search(self.AYL_PATTERN, html) + n = re.search(self.CALLBACK_PATTERN, html) + if m and n: + self.key = (m.group(1).strip(), n.group(1).strip()) + self.logDebug("Ayl|callback: %s | %s" % self.key) + return self.key #: key is the tuple(ayl, callback) + else: + self.logDebug("Ayl or callback not found") + return None + + + def challenge(self, key=None, html=None): + if not key: + if self.detect_key(html): + key = self.key + else: + errmsg = _("AdYouLike key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + ayl, callback = key + + # {"adyoulike":{"key":"P~zQ~O0zV0WTiAzC-iw0navWQpCLoYEP"}, + # "all":{"element_id":"ayl_private_cap_92300","lang":"fr","env":"prod"}} + ayl = json_loads(ayl) + + html = self.plugin.req.load("http://api-ayl.appspot.com/challenge", + get={'key' : ayl['adyoulike']['key'], + 'env' : ayl['all']['env'], + 'callback': callback}) + try: + challenge = json_loads(re.search(callback + r'\s*\((.+?)\)', html).group(1)) + + except AttributeError: + errmsg = _("AdYouLike challenge pattern not found") + self.plugin.fail(errmsg) + raise AttributeError(errmsg) + + self.logDebug("Challenge: %s" % challenge) + + return self.result(ayl, challenge), challenge + + + def result(self, server, challenge): + # Adyoulike.g._jsonp_5579316662423138 + # ({"translations":{"fr":{"instructions_visual":"Recopiez « Soonnight » ci-dessous :"}}, + # "site_under":true,"clickable":true,"pixels":{"VIDEO_050":[],"DISPLAY":[],"VIDEO_000":[],"VIDEO_100":[], + # "VIDEO_025":[],"VIDEO_075":[]},"medium_type":"image/adyoulike", + # "iframes":{"big":"<iframe src=\"http://www.soonnight.com/campagn.html\" scrolling=\"no\" + # height=\"250\" width=\"300\" frameborder=\"0\"></iframe>"},"shares":{},"id":256, + # "token":"e6QuI4aRSnbIZJg02IsV6cp4JQ9~MjA1","formats":{"small":{"y":300,"x":0,"w":300,"h":60}, + # "big":{"y":0,"x":0,"w":300,"h":250},"hover":{"y":440,"x":0,"w":300,"h":60}}, + # "tid":"SqwuAdxT1EZoi4B5q0T63LN2AkiCJBg5"}) + + if isinstance(server, basestring): + server = json_loads(server) + + if isinstance(challenge, basestring): + challenge = json_loads(challenge) + + try: + instructions_visual = challenge['translations'][server['all']['lang']]['instructions_visual'] + result = re.search(u'«(.+?)»', instructions_visual).group(1).strip() + + except AttributeError: + errmsg = _("AdYouLike result not found") + self.plugin.fail(errmsg) + raise AttributeError(errmsg) + + result = {'_ayl_captcha_engine' : "adyoulike", + '_ayl_env' : server['all']['env'], + '_ayl_tid' : challenge['tid'], + '_ayl_token_challenge': challenge['token'], + '_ayl_response' : response} + + self.logDebug("Result: %s" % result) + + return result |