summaryrefslogtreecommitdiffstats
path: root/module/plugins/internal
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/internal')
-rw-r--r--module/plugins/internal/AbstractExtractor.py2
-rw-r--r--module/plugins/internal/CaptchaService.py203
-rw-r--r--module/plugins/internal/MultiHoster.py45
-rw-r--r--module/plugins/internal/SimpleHoster.py24
-rw-r--r--module/plugins/internal/UnZip.py2
-rw-r--r--module/plugins/internal/XFSCrypter.py4
6 files changed, 202 insertions, 78 deletions
diff --git a/module/plugins/internal/AbstractExtractor.py b/module/plugins/internal/AbstractExtractor.py
index 8a69ebb56..2317ad689 100644
--- a/module/plugins/internal/AbstractExtractor.py
+++ b/module/plugins/internal/AbstractExtractor.py
@@ -14,7 +14,7 @@ class WrongPassword(Exception):
class AbtractExtractor:
__name__ = "AbtractExtractor"
- __version__ = "0.1"
+ __version__ = "0.10"
__description__ = """Abtract extractor plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py
index 7009e6986..965799e8e 100644
--- a/module/plugins/internal/CaptchaService.py
+++ b/module/plugins/internal/CaptchaService.py
@@ -4,10 +4,12 @@ import re
from random import random
+from module.common.json_layer import json_loads
+
class CaptchaService:
__name__ = "CaptchaService"
- __version__ = "0.15"
+ __version__ = "0.16"
__description__ = """Base captcha service plugin"""
__license__ = "GPLv3"
@@ -34,7 +36,7 @@ class CaptchaService:
m = re.search(self.KEY_PATTERN, html)
if m:
- self.key = m.group("KEY")
+ self.key = m.group(1).strip()
self.plugin.logDebug("%s key: %s" % (self.__name__, self.key))
return self.key
else:
@@ -59,8 +61,8 @@ class ReCaptcha(CaptchaService):
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- KEY_PATTERN = r'recaptcha(/api|\.net)/(challenge|noscript)\?k=(?P<KEY>[\w-]+)'
- KEY_AJAX_PATTERN = r'Recaptcha\.create\s*\(\s*["\'](?P<KEY>[\w-]+)'
+ KEY_PATTERN = r'recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=([\w-]+)'
+ KEY_AJAX_PATTERN = r'Recaptcha\.create\s*\(\s*["\']([\w-]+)'
def detect_key(self, html=None):
@@ -74,7 +76,7 @@ class ReCaptcha(CaptchaService):
m = re.search(self.KEY_PATTERN, html) or re.search(self.KEY_AJAX_PATTERN, html)
if m:
- self.key = m.group("KEY")
+ self.key = m.group(1).strip()
self.plugin.logDebug("ReCaptcha key: %s" % self.key)
return self.key
else:
@@ -91,36 +93,43 @@ class ReCaptcha(CaptchaService):
self.plugin.fail(errmsg)
raise TypeError(errmsg)
- js = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge", get={'k': key})
+ html = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge", get={'k': key})
try:
- challenge = re.search("challenge : '(.+?)',", js).group(1)
- server = re.search("server : '(.+?)',", js).group(1)
+ challenge = re.search("challenge : '(.+?)',", html).group(1)
+ server = re.search("server : '(.+?)',", html).group(1)
except:
- self.plugin.error("ReCaptcha challenge pattern not found")
-
- result = self.result(server, challenge)
+ errmsg = _("ReCaptcha challenge pattern not found")
+ self.plugin.fail(errmsg)
+ raise ValueError(errmsg)
- self.plugin.logDebug("ReCaptcha result: %s" % result, "challenge: %s" % challenge)
+ self.plugin.logDebug("ReCaptcha challenge: %s" % challenge)
- return challenge, result
+ return challenge, self.result(server, challenge)
def result(self, server, challenge):
- return self.plugin.decryptCaptcha("%simage" % server, get={'c': challenge},
- cookies=True, forceUser=True, imgtype="jpg")
+ result = self.plugin.decryptCaptcha("%simage" % server,
+ get={'c': challenge},
+ cookies=True,
+ forceUser=True,
+ imgtype="jpg")
+
+ self.plugin.logDebug("ReCaptcha result: %s" % result)
+
+ return result
class AdsCaptcha(CaptchaService):
__name__ = "AdsCaptcha"
- __version__ = "0.05"
+ __version__ = "0.06"
__description__ = """AdsCaptcha captcha service plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- ID_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*CaptchaId=(?P<ID>\d+)'
- KEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*PublicKey=(?P<KEY>[\w-]+)'
+ 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):
@@ -132,18 +141,18 @@ class AdsCaptcha(CaptchaService):
self.plugin.fail(errmsg)
raise TypeError(errmsg)
- m = re.search(self.ID_PATTERN, html)
- n = re.search(self.KEY_PATTERN, html)
+ m = re.search(self.PUBLICKEY_PATTERN, html)
+ n = re.search(self.CAPTCHAID_PATTERN, html)
if m and n:
- self.key = (m.group("ID"), m.group("KEY"))
- self.plugin.logDebug("AdsCaptcha id|key: %s | %s" % self.key)
+ self.key = (m.group(1).strip(), n.group(1).strip()) #: key is the tuple(PublicKey, CaptchaId)
+ self.plugin.logDebug("AdsCaptcha key|id: %s | %s" % self.key)
return self.key
else:
- self.plugin.logDebug("AdsCaptcha id or key not found")
+ self.plugin.logDebug("AdsCaptcha key or id not found")
return None
- def challenge(self, key=None): #: key is a tuple(CaptchaId, PublicKey)
+ def challenge(self, key=None):
if not key:
if self.detect_key():
key = self.key
@@ -152,25 +161,31 @@ class AdsCaptcha(CaptchaService):
self.plugin.fail(errmsg)
raise TypeError(errmsg)
- CaptchaId, PublicKey = key
+ PublicKey, CaptchaId = key
- js = self.plugin.req.load("http://api.adscaptcha.com/Get.aspx", get={'CaptchaId': CaptchaId, 'PublicKey': PublicKey})
+ html = self.plugin.req.load("http://api.adscaptcha.com/Get.aspx", get={'CaptchaId': CaptchaId, 'PublicKey': PublicKey})
try:
- challenge = re.search("challenge: '(.+?)',", js).group(1)
- server = re.search("server: '(.+?)',", js).group(1)
+ challenge = re.search("challenge: '(.+?)',", html).group(1)
+ server = re.search("server: '(.+?)',", html).group(1)
except:
- self.plugin.error("AdsCaptcha challenge pattern not found")
-
- result = self.result(server, challenge)
+ errmsg = _("AdsCaptcha challenge pattern not found")
+ self.plugin.fail(errmsg)
+ raise ValueError(errmsg)
- self.plugin.logDebug("AdsCaptcha result: %s" % result, "challenge: %s" % challenge)
+ self.plugin.logDebug("AdsCaptcha challenge: %s" % challenge)
- return challenge, result
+ return challenge, self.result(server, challenge)
def result(self, server, challenge):
- return self.plugin.decryptCaptcha("%sChallenge.aspx" % server, get={'cid': challenge, 'dummy': random()},
- cookies=True, imgtype="jpg")
+ result = self.plugin.decryptCaptcha("%sChallenge.aspx" % server,
+ get={'cid': challenge, 'dummy': random()},
+ cookies=True,
+ imgtype="jpg")
+
+ self.plugin.logDebug("AdsCaptcha result: %s" % result)
+
+ return result
class SolveMedia(CaptchaService):
@@ -182,7 +197,7 @@ class SolveMedia(CaptchaService):
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(no)?script\?k=(?P<KEY>.+?)["\']'
+ KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']'
def challenge(self, key=None):
@@ -198,16 +213,120 @@ class SolveMedia(CaptchaService):
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"
+ server = "http://api.solvemedia.com/papi/media"
except:
- self.plugin.error("SolveMedia challenge pattern not found")
+ errmsg = _("SolveMedia challenge pattern not found")
+ self.plugin.fail(errmsg)
+ raise ValueError(errmsg)
+
+ self.plugin.logDebug("SolveMedia challenge: %s" % challenge)
+
+ return challenge, self.result(server, challenge)
+
+
+ def result(self, server, challenge):
+ result = self.plugin.decryptCaptcha(server, get={'c': challenge}, imgtype="gif")
+
+ self.plugin.logDebug("SolveMedia result: %s" % result)
+
+ return result
+
+
+class AdYouLike(CaptchaService):
+ __name__ = "AdYouLike"
+ __version__ = "0.02"
+
+ __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)
- result = self.result(server, challenge)
+ 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.plugin.logDebug("AdYouLike ayl|callback: %s | %s" % self.key)
+ return self.key #: key is the tuple(ayl, callback)
+ else:
+ self.plugin.logDebug("AdYouLike ayl or callback not found")
+ return None
- self.plugin.logDebug("SolveMedia result: %s" % result, "challenge: %s" % challenge)
- return challenge, result
+ def challenge(self, key=None):
+ if not key:
+ if self.detect_key():
+ 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:
+ errmsg = _("AdYouLike challenge pattern not found")
+ self.plugin.fail(errmsg)
+ raise ValueError(errmsg)
+
+ self.plugin.logDebug("AdYouLike challenge: %s" % challenge)
+
+ return self.result(ayl, challenge)
def result(self, server, challenge):
- return self.plugin.decryptCaptcha(server, get={'c': challenge}, imgtype="gif")
+ # 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:
+ errmsg = _("AdYouLike result not found")
+ self.plugin.fail(errmsg)
+ raise ValueError(errmsg)
+
+ result = {'_ayl_captcha_engine' : "adyoulike",
+ '_ayl_env' : server['all']['env'],
+ '_ayl_tid' : challenge['tid'],
+ '_ayl_token_challenge': challenge['token'],
+ '_ayl_response' : response}
+
+ self.plugin.logDebug("AdYouLike result: %s" % result)
+
+ return result
diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py
index c86f9b286..6ec2e4b82 100644
--- a/module/plugins/internal/MultiHoster.py
+++ b/module/plugins/internal/MultiHoster.py
@@ -9,25 +9,28 @@ from module.utils import remove_chars
class MultiHoster(Hook):
__name__ = "MultiHoster"
__type__ = "hook"
- __version__ = "0.19"
+ __version__ = "0.20"
__description__ = """Generic MultiHoster plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- interval = 24 * 60 * 60 #: reload hosters daily
+ interval = 12 * 60 * 60 #: reload hosters every 12h
- HOSTER_REPLACEMENTS = [("2shared.com", "twoshared.com"), ("4shared.com", "fourshared.com"), ("cloudnator.com", "shragle.com"),
- ("ifile.it", "filecloud.io"), ("easy-share.com", "crocko.com"), ("freakshare.net", "freakshare.com"),
- ("hellshare.com", "hellshare.cz"), ("share-rapid.cz", "sharerapid.com"), ("sharerapid.cz", "sharerapid.com"),
- ("ul.to", "uploaded.to"), ("uploaded.net", "uploaded.to"), ("1fichier.com", "onefichier.com")]
+ HOSTER_REPLACEMENTS = [("1fichier.com", "onefichier.com"), ("2shared.com", "twoshared.com"),
+ ("4shared.com", "fourshared.com"), ("cloudnator.com", "shragle.com"),
+ ("easy-share.com", "crocko.com"), ("freakshare.net", "freakshare.com"),
+ ("hellshare.com", "hellshare.cz"), ("ifile.it", "filecloud.io"),
+ ("putlocker.com", "firedrive.com"), ("share-rapid.cz", "multishare.cz"),
+ ("sharerapid.cz", "multishare.cz"), ("ul.to", "uploaded.to"),
+ ("uploaded.net", "uploaded.to")]
HOSTER_EXCLUDED = []
def setup(self):
- self.hosters = []
- self.supported = []
+ self.hosters = []
+ self.supported = []
self.new_supported = []
@@ -41,7 +44,6 @@ class MultiHoster(Hook):
def getHosterCached(self):
if not self.hosters:
-
try:
hosterSet = self.toHosterSet(self.getHoster()) - set(self.HOSTER_EXCLUDED)
except Exception, e:
@@ -110,8 +112,10 @@ class MultiHoster(Hook):
"""reload hoster list periodically"""
self.logInfo(_("Reloading supported hoster list"))
- old_supported = self.supported
- self.supported, self.new_supported, self.hosters = [], [], []
+ old_supported = self.supported
+ self.supported = []
+ self.new_supported = []
+ self.hosters = []
self.overridePlugins()
@@ -123,11 +127,8 @@ class MultiHoster(Hook):
def overridePlugins(self):
- pluginMap = {}
- for name in self.core.pluginManager.hosterPlugins.keys():
- pluginMap[name.lower()] = name
-
- accountList = [name.lower() for name, data in self.core.accountManager.accounts.iteritems() if data]
+ pluginMap = dict((name.lower(), name) for name in self.core.pluginManager.hosterPlugins.keys())
+ accountList = [name.lower() for name, data in self.core.accountManager.accounts.iteritems() if data]
excludedList = []
for hoster in self.getHosterCached():
@@ -146,14 +147,14 @@ class MultiHoster(Hook):
return
module = self.core.pluginManager.getPlugin(self.__name__)
- klass = getattr(module, self.__name__)
+ klass = getattr(module, self.__name__)
# inject plugin plugin
self.logDebug("Overwritten Hosters", ", ".join(sorted(self.supported)))
for hoster in self.supported:
dict = self.core.pluginManager.hosterPlugins[hoster]
dict['new_module'] = module
- dict['new_name'] = self.__name__
+ dict['new_name'] = self.__name__
if excludedList:
self.logInfo(_("The following hosters were not overwritten - account exists"), ", ".join(sorted(excludedList)))
@@ -162,7 +163,7 @@ class MultiHoster(Hook):
self.logDebug("New Hosters", ", ".join(sorted(self.new_supported)))
# create new regexp
- regexp = r'.*(%s).*' % "|".join([x.replace(".", "\\.") for x in self.new_supported])
+ regexp = r'.*(%s).*' % "|".join([x.replace(".", "\.") for x in self.new_supported])
if hasattr(klass, "__pattern__") and isinstance(klass.__pattern__, basestring) and '://' in klass.__pattern__:
regexp = r'%s|%s' % (klass.__pattern__, regexp)
@@ -170,7 +171,7 @@ class MultiHoster(Hook):
dict = self.core.pluginManager.hosterPlugins[self.__name__]
dict['pattern'] = regexp
- dict['re'] = re.compile(regexp)
+ dict['re'] = re.compile(regexp)
def unloadHoster(self, hoster):
@@ -190,9 +191,9 @@ class MultiHoster(Hook):
# reset pattern
klass = getattr(self.core.pluginManager.getPlugin(self.__name__), self.__name__)
- dict = self.core.pluginManager.hosterPlugins[self.__name__]
+ dict = self.core.pluginManager.hosterPlugins[self.__name__]
dict['pattern'] = getattr(klass, "__pattern__", r'^unmatchable$')
- dict['re'] = re.compile(dict['pattern'])
+ dict['re'] = re.compile(dict['pattern'])
def downloadFailed(self, pyfile):
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index f391445fd..ddaea020a 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -104,9 +104,9 @@ def parseFileInfo(plugin, url="", html=""):
#@TODO: Remove in 0.4.10
-#@NOTE: Every plugin must have own parseInfo classmethod to work with 0.4.10
+#@NOTE: Every plugin must have own parseInfos classmethod to work with 0.4.10
def create_getInfo(plugin):
- return lambda urls: [(info['name'], info['size'], info['status'], info['url']) for info in plugin.parseInfo(urls)]
+ return lambda urls: [(info['name'], info['size'], info['status'], info['url']) for info in plugin.parseInfos(urls)]
def timestamp():
@@ -144,7 +144,7 @@ def _isDirectLink(self, url, resumable=True):
class SimpleHoster(Hoster):
__name__ = "SimpleHoster"
__type__ = "hoster"
- __version__ = "0.70"
+ __version__ = "0.72"
__pattern__ = r'^unmatchable$'
@@ -206,11 +206,10 @@ class SimpleHoster(Hoster):
FORCE_CHECK_TRAFFIC = False #: Set to True to force checking traffic left for premium account
CHECK_DIRECT_LINK = None #: Set to True to check for direct link, set to None to do it only if self.account is True
MULTI_HOSTER = False #: Set to True to leech other hoster link (according its multihoster hook if available)
- CONTENT_DISPOSITION = False #: Set to True to replace file name with content-disposition value from http header
@classmethod
- def parseInfo(cls, urls):
+ def parseInfos(cls, urls):
for url in urls:
url = replace_patterns(url, cls.FILE_URL_REPLACEMENTS if hasattr(cls, "FILE_URL_REPLACEMENTS") else cls.URL_REPLACEMENTS) #@TODO: Remove FILE_URL_REPLACEMENTS check in 0.4.10
yield cls.getInfo(url)
@@ -319,8 +318,8 @@ class SimpleHoster(Hoster):
set_cookies(self.req.cj, self.COOKIES)
if (self.MULTI_HOSTER
- and self.__pattern__ != self.core.pluginManager.hosterPlugins[self.__name__]['pattern']
- and re.match(self.__pattern__, self.pyfile.url) is None):
+ and (self.__pattern__ != self.core.pluginManager.hosterPlugins[self.__name__]['pattern']
+ or re.match(self.__pattern__, self.pyfile.url) is None)):
self.logInfo("Multi hoster detected")
@@ -384,12 +383,17 @@ class SimpleHoster(Hoster):
self.logDebug("Handled as free download")
self.handleFree()
- if self.link:
- self.download(self.link, disposition=self.CONTENT_DISPOSITION)
-
+ self.downloadLink(self.link)
self.checkFile()
+ def downloadLink(self, link):
+ if not link:
+ return
+
+ self.download(link, disposition=True)
+
+
def checkFile(self):
if self.checkDownload({'empty': re.compile(r"^$")}) is "empty": #@TODO: Move to hoster in 0.4.10
self.fail(_("Empty file"))
diff --git a/module/plugins/internal/UnZip.py b/module/plugins/internal/UnZip.py
index e754141a1..053946dbe 100644
--- a/module/plugins/internal/UnZip.py
+++ b/module/plugins/internal/UnZip.py
@@ -8,7 +8,7 @@ from module.plugins.internal.AbstractExtractor import AbtractExtractor
class UnZip(AbtractExtractor):
__name__ = "UnZip"
- __version__ = "0.1"
+ __version__ = "0.10"
__description__ = """Zip extractor plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/internal/XFSCrypter.py b/module/plugins/internal/XFSCrypter.py
index 62fd8c017..4b57dab90 100644
--- a/module/plugins/internal/XFSCrypter.py
+++ b/module/plugins/internal/XFSCrypter.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleCrypter import SimpleCrypter
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class XFSCrypter(SimpleCrypter):
__name__ = "XFSCrypter"
__type__ = "crypter"
- __version__ = "0.04"
+ __version__ = "0.05"
__pattern__ = r'^unmatchable$'