summaryrefslogtreecommitdiffstats
path: root/module/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins')
-rw-r--r--module/plugins/accounts/AlldebridCom.py4
-rw-r--r--module/plugins/accounts/CatShareNet.py2
-rw-r--r--module/plugins/accounts/FilerNet.py12
-rw-r--r--module/plugins/accounts/NitroflareCom.py83
-rw-r--r--module/plugins/accounts/NoPremiumPl.py52
-rw-r--r--module/plugins/accounts/PremiumizeMe.py7
-rw-r--r--module/plugins/accounts/RapideoPl.py53
-rw-r--r--module/plugins/accounts/RapidgatorNet.py2
-rw-r--r--module/plugins/accounts/RealdebridCom.py4
-rw-r--r--module/plugins/accounts/WebshareCz.py6
-rw-r--r--module/plugins/accounts/WorldbytezCom.py16
-rw-r--r--module/plugins/crypter/Dereferer.py35
-rw-r--r--module/plugins/crypter/DontKnowMe.py17
-rw-r--r--module/plugins/crypter/FilecryptCc.py4
-rw-r--r--module/plugins/crypter/FurLy.py24
-rw-r--r--module/plugins/crypter/GooGl.py10
-rw-r--r--module/plugins/crypter/LinkSaveIn.py6
-rw-r--r--module/plugins/crypter/MegaCoNzFolder.py4
-rw-r--r--module/plugins/crypter/NCryptIn.py4
-rw-r--r--module/plugins/crypter/SafelinkingNet.py4
-rw-r--r--module/plugins/crypter/TinyurlCom.py23
-rw-r--r--module/plugins/crypter/XFileSharingProFolder.py4
-rw-r--r--module/plugins/hooks/UserAgentSwitcher.py19
-rw-r--r--module/plugins/hooks/XFileSharingPro.py12
-rw-r--r--module/plugins/hoster/BitshareCom.py4
-rw-r--r--module/plugins/hoster/CatShareNet.py4
-rw-r--r--module/plugins/hoster/CrockoCom.py4
-rw-r--r--module/plugins/hoster/DateiTo.py4
-rw-r--r--module/plugins/hoster/DepositfilesCom.py4
-rw-r--r--module/plugins/hoster/DlFreeFr.py21
-rw-r--r--module/plugins/hoster/ExtabitCom.py4
-rw-r--r--module/plugins/hoster/FileboomMe.py102
-rw-r--r--module/plugins/hoster/FilecloudIo.py4
-rw-r--r--module/plugins/hoster/FilepostCom.py4
-rw-r--r--module/plugins/hoster/FilerNet.py4
-rw-r--r--module/plugins/hoster/FileserveCom.py4
-rw-r--r--module/plugins/hoster/FreakshareCom.py4
-rw-r--r--module/plugins/hoster/Keep2ShareCc.py4
-rw-r--r--module/plugins/hoster/KingfilesNet.py4
-rw-r--r--module/plugins/hoster/LetitbitNet.py4
-rw-r--r--module/plugins/hoster/LoadTo.py4
-rw-r--r--module/plugins/hoster/LuckyShareNet.py4
-rw-r--r--module/plugins/hoster/MediafireCom.py5
-rw-r--r--module/plugins/hoster/MegaCoNz.py6
-rw-r--r--module/plugins/hoster/NitroflareCom.py22
-rw-r--r--module/plugins/hoster/OboomCom.py4
-rw-r--r--module/plugins/hoster/OpenloadIo.py4
-rw-r--r--module/plugins/hoster/RapidgatorNet.py6
-rw-r--r--module/plugins/hoster/RapiduNet.py4
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py41
-rw-r--r--module/plugins/hoster/TurbobitNet.py4
-rw-r--r--module/plugins/hoster/TusfilesNet.py1
-rw-r--r--module/plugins/hoster/UploadableCh.py4
-rw-r--r--module/plugins/hoster/UploadedTo.py4
-rw-r--r--module/plugins/hoster/UpstoreNet.py4
-rw-r--r--module/plugins/hoster/WebshareCz.py37
-rw-r--r--module/plugins/hoster/XFileSharingPro.py4
-rw-r--r--module/plugins/hoster/ZahikiNet.py32
-rw-r--r--module/plugins/hoster/ZippyshareCom.py4
-rw-r--r--module/plugins/internal/AdYouLike.py91
-rw-r--r--module/plugins/internal/AdsCaptcha.py63
-rw-r--r--module/plugins/internal/Captcha.py56
-rw-r--r--module/plugins/internal/CaptchaService.py489
-rw-r--r--module/plugins/internal/DeadCrypter.py8
-rw-r--r--module/plugins/internal/DeadHoster.py8
-rw-r--r--module/plugins/internal/Extractor.py2
-rw-r--r--module/plugins/internal/ReCaptcha.py195
-rw-r--r--module/plugins/internal/SimpleCrypter.py42
-rw-r--r--module/plugins/internal/SimpleDereferer.py101
-rw-r--r--module/plugins/internal/SimpleHoster.py27
-rw-r--r--module/plugins/internal/SolveMedia.py104
-rw-r--r--module/plugins/internal/UnZip.py2
-rw-r--r--module/plugins/internal/XFSCrypter.py2
-rw-r--r--module/plugins/internal/XFSHoster.py11
74 files changed, 1101 insertions, 880 deletions
diff --git a/module/plugins/accounts/AlldebridCom.py b/module/plugins/accounts/AlldebridCom.py
index f9c1f2ca6..d09086907 100644
--- a/module/plugins/accounts/AlldebridCom.py
+++ b/module/plugins/accounts/AlldebridCom.py
@@ -2,7 +2,7 @@
import re
import time
-import xml.dom.minidom as dom
+import xml.dom.minidom
from BeautifulSoup import BeautifulSoup
@@ -43,7 +43,7 @@ class AlldebridCom(Account):
self.logDebug(html)
- xml = dom.parseString(html)
+ xml = xml.dom.minidom.parseString(html)
exp_time = time.time() + int(xml.getElementsByTagName("date")[0].childNodes[0].nodeValue) * 24 * 60 * 60
account_info = {"validuntil": exp_time, "trafficleft": -1}
diff --git a/module/plugins/accounts/CatShareNet.py b/module/plugins/accounts/CatShareNet.py
index bb42f443f..3ddadca8e 100644
--- a/module/plugins/accounts/CatShareNet.py
+++ b/module/plugins/accounts/CatShareNet.py
@@ -11,7 +11,7 @@ class CatShareNet(Account):
__type__ = "account"
__version__ = "0.05"
- __description__ = """CatShareNet account plugin"""
+ __description__ = """Catshare.net account plugin"""
__license__ = "GPLv3"
__authors__ = [("prOq", None)]
diff --git a/module/plugins/accounts/FilerNet.py b/module/plugins/accounts/FilerNet.py
index ac5fd11da..149ff7d89 100644
--- a/module/plugins/accounts/FilerNet.py
+++ b/module/plugins/accounts/FilerNet.py
@@ -9,14 +9,14 @@ from module.plugins.Account import Account
class FilerNet(Account):
__name__ = "FilerNet"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.05"
__description__ = """Filer.net account plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- TOKEN_PATTERN = r'_csrf_token" value="(.+?)" />'
+ TOKEN_PATTERN = r'name="_csrf_token" value="(.+?)"'
WALID_UNTIL_PATTERN = r'Der Premium-Zugang ist gültig bis (.+)\.\s*</td>'
TRAFFIC_PATTERN = r'Traffic</th>\s*<td>([^<]+)</td>'
FREE_PATTERN = r'Account Status</th>\s*<td>\s*Free'
@@ -43,15 +43,15 @@ class FilerNet(Account):
def login(self, user, data, req):
- html = req.load("https://filer.net/login")
+ html = req.load("https://filer.net/login", decode=True)
token = re.search(self.TOKEN_PATTERN, html).group(1)
html = req.load("https://filer.net/login_check",
- post={"_username": user,
- "_password": data['password'],
+ post={"_username" : user,
+ "_password" : data['password'],
"_remember_me": "on",
- "_csrf_token": token,
+ "_csrf_token" : token,
"_target_path": "https://filer.net/"},
decode=True)
diff --git a/module/plugins/accounts/NitroflareCom.py b/module/plugins/accounts/NitroflareCom.py
new file mode 100644
index 000000000..57f2b9ae8
--- /dev/null
+++ b/module/plugins/accounts/NitroflareCom.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+
+import re
+import time
+
+from module.plugins.Account import Account
+
+
+class NitroflareCom(Account):
+ __name__ = "NitroflareCom"
+ __type__ = "account"
+ __version__ = "0.04"
+
+ __description__ = """Nitroflare.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com" )]
+
+
+ VALID_UNTIL_PATTERN = r'>Time Left</label><strong>(.+?)</'
+ TRAFFIC_LEFT_PATTERN = r'>Daily Limit</label><strong>([\d.,]+)'
+ LOGIN_FAIL_PATTERN = r'<ul class="errors">\s*<li>'
+
+ TOKEN_PATTERN = r'name="token" value="(.+?)"'
+
+
+ def loadAccountInfo(self, user, req):
+ validuntil = -1
+ trafficleft = None
+ premium = False
+
+ html = req.load("https://nitroflare.com/member",
+ get={'s': "premium"},
+ decode=True)
+
+ m = re.search(self.VALID_UNTIL_PATTERN, html)
+ if m:
+ expiredate = m.group(1).strip()
+ self.logDebug("Time Left: " + expiredate)
+
+ 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.logError(e)
+
+ else:
+ self.logDebug("Valid until: %s" % validuntil)
+
+ if validuntil:
+ validuntil += time.time()
+ premium = True
+ else:
+ validuntil = -1
+
+ m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
+ if m:
+ try:
+ trafficleft = self.parseTraffic(str(max(0, 50 - float(m.group(1)))) + " GB")
+
+ except Exception, e:
+ self.logError(e)
+ else:
+ self.logDebug("TRAFFIC_LEFT_PATTERN not found")
+
+ return {'validuntil' : validuntil,
+ 'trafficleft': trafficleft,
+ 'premium' : premium}
+
+
+ def login(self, user, data, req):
+ html = req.load("https://nitroflare.com/login", decode=True)
+
+ token = re.search(self.TOKEN_PATTERN, html).group(1)
+
+ html = req.load("https://nitroflare.com/login",
+ post={'login' : "",
+ 'email' : user,
+ 'password': data['password'],
+ 'token' : token},
+ decode=True)
+
+ if re.search(self.LOGIN_FAIL_PATTERN, html):
+ self.wrongPassword()
diff --git a/module/plugins/accounts/NoPremiumPl.py b/module/plugins/accounts/NoPremiumPl.py
index 7e3f757d3..6c034b31f 100644
--- a/module/plugins/accounts/NoPremiumPl.py
+++ b/module/plugins/accounts/NoPremiumPl.py
@@ -4,37 +4,37 @@ import datetime
import hashlib
import time
+from module.common.json_layer import json_loads
from module.plugins.Account import Account
-from module.common.json_layer import json_loads as loads
class NoPremiumPl(Account):
- __name__ = "NoPremiumPl"
+ __name__ = "NoPremiumPl"
+ __type__ = "account"
__version__ = "0.01"
- __type__ = "account"
+
__description__ = "NoPremium.pl account plugin"
- __license__ = "GPLv3"
- __authors__ = [("goddie", "dev@nopremium.pl")]
+ __license__ = "GPLv3"
+ __authors__ = [("goddie", "dev@nopremium.pl")]
- _api_url = "http://crypt.nopremium.pl"
- _api_query = {
- "site": "nopremium",
- "username": "",
- "password": "",
- "output": "json",
- "loc": "1",
- "info": "1"
- }
+ API_URL = "http://crypt.nopremium.pl"
+ API_QUERY = {'site' : "nopremium",
+ 'username': "" ,
+ 'password': "" ,
+ 'output' : "json" ,
+ 'loc' : "1" ,
+ 'info' : "1" }
_req = None
_usr = None
_pwd = None
+
def loadAccountInfo(self, name, req):
self._req = req
try:
- result = loads(self.runAuthQuery())
+ result = json_loads(self.runAuthQuery())
except Exception:
# todo: return or let it be thrown?
return
@@ -45,13 +45,13 @@ class NoPremiumPl(Account):
if "expire" in result.keys() and result["expire"]:
premium = True
valid_untill = time.mktime(datetime.datetime.fromtimestamp(int(result["expire"])).timetuple())
+
traffic_left = result["balance"] * 1024
- return ({
- "validuntil": valid_untill,
- "trafficleft": traffic_left,
- "premium": premium
- })
+ return {'validuntil' : valid_untill,
+ 'trafficleft': traffic_left,
+ 'premium' : premium }
+
def login(self, user, data, req):
self._usr = user
@@ -59,23 +59,23 @@ class NoPremiumPl(Account):
self._req = req
try:
- response = loads(self.runAuthQuery())
+ response = json_loads(self.runAuthQuery())
except Exception:
self.wrongPassword()
if "errno" in response.keys():
self.wrongPassword()
+
data['usr'] = self._usr
data['pwd'] = self._pwd
+
def createAuthQuery(self):
- query = self._api_query
+ query = self.API_QUERY
query["username"] = self._usr
query["password"] = self._pwd
-
return query
- def runAuthQuery(self):
- data = self._req.load(self._api_url, post=self.createAuthQuery())
- return data \ No newline at end of file
+ def runAuthQuery(self):
+ return self._req.load(self.API_URL, post=self.createAuthQuery())
diff --git a/module/plugins/accounts/PremiumizeMe.py b/module/plugins/accounts/PremiumizeMe.py
index 7d061ec2d..da31d93ee 100644
--- a/module/plugins/accounts/PremiumizeMe.py
+++ b/module/plugins/accounts/PremiumizeMe.py
@@ -1,14 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
-
from module.common.json_layer import json_loads
+from module.plugins.Account import Account
class PremiumizeMe(Account):
__name__ = "PremiumizeMe"
__type__ = "account"
- __version__ = "0.13"
+ __version__ = "0.16"
__description__ = """Premiumize.me account plugin"""
__license__ = "GPLv3"
@@ -42,7 +41,7 @@ class PremiumizeMe(Account):
def getAccountStatus(self, user, req):
# Use premiumize.me API v1 (see https://secure.premiumize.me/?show=api)
# to retrieve account info and return the parsed json answer
- answer = req.load("https://api.premiumize.me/pm-api/v1.php",
+ answer = req.load("http://api.premiumize.me/pm-api/v1.php",
get={'method' : "accountstatus",
'params[login]': user,
'params[pass]' : self.getAccountData(user)['password']})
diff --git a/module/plugins/accounts/RapideoPl.py b/module/plugins/accounts/RapideoPl.py
index 3e9d52fe8..92736cba0 100644
--- a/module/plugins/accounts/RapideoPl.py
+++ b/module/plugins/accounts/RapideoPl.py
@@ -4,77 +4,78 @@ import datetime
import hashlib
import time
+from module.common.json_layer import json_loads
from module.plugins.Account import Account
-from module.common.json_layer import json_loads as loads
class RapideoPl(Account):
- __name__ = "RapideoPl"
+ __name__ = "RapideoPl"
+ __type__ = "account"
__version__ = "0.01"
- __type__ = "account"
+
__description__ = "Rapideo.pl account plugin"
- __license__ = "GPLv3"
- __authors__ = [("goddie", "dev@rapideo.pl")]
+ __license__ = "GPLv3"
+ __authors__ = [("goddie", "dev@rapideo.pl")]
- _api_url = "http://enc.rapideo.pl"
- _api_query = {
- "site": "newrd",
- "username": "",
- "password": "",
- "output": "json",
- "loc": "1",
- "info": "1"
- }
+ API_URL = "http://enc.rapideo.pl"
+ API_QUERY = {'site' : "newrd",
+ 'username': "" ,
+ 'password': "" ,
+ 'output' : "json" ,
+ 'loc' : "1" ,
+ 'info' : "1" }
_req = None
_usr = None
_pwd = None
+
def loadAccountInfo(self, name, req):
self._req = req
try:
- result = loads(self.runAuthQuery())
+ result = json_loads(self.runAuthQuery())
except Exception:
# todo: return or let it be thrown?
return
premium = False
valid_untill = -1
+
if "expire" in result.keys() and result["expire"]:
premium = True
valid_untill = time.mktime(datetime.datetime.fromtimestamp(int(result["expire"])).timetuple())
traffic_left = result["balance"]
- return ({
- "validuntil": valid_untill,
- "trafficleft": traffic_left,
- "premium": premium
- })
+ return {'validuntil' : valid_untill,
+ 'trafficleft': traffic_left,
+ 'premium' : premium }
+
def login(self, user, data, req):
self._usr = user
self._pwd = hashlib.md5(data["password"]).hexdigest()
self._req = req
+
try:
- response = loads(self.runAuthQuery())
+ response = json_loads(self.runAuthQuery())
except Exception:
self.wrongPassword()
if "errno" in response.keys():
self.wrongPassword()
+
data['usr'] = self._usr
data['pwd'] = self._pwd
+
def createAuthQuery(self):
- query = self._api_query
+ query = self.API_QUERY
query["username"] = self._usr
query["password"] = self._pwd
-
return query
- def runAuthQuery(self):
- data = self._req.load(self._api_url, post=self.createAuthQuery())
- return data \ No newline at end of file
+ def runAuthQuery(self):
+ return self._req.load(self.API_URL, post=self.createAuthQuery())
diff --git a/module/plugins/accounts/RapidgatorNet.py b/module/plugins/accounts/RapidgatorNet.py
index 23d7aff53..5ff30e061 100644
--- a/module/plugins/accounts/RapidgatorNet.py
+++ b/module/plugins/accounts/RapidgatorNet.py
@@ -24,7 +24,7 @@ class RapidgatorNet(Account):
sid = None
try:
- sid = self.getAccountData(user).get('sid')
+ sid = self.getAccountData(user).get('sid', None)
assert sid
html = req.load("%s/info" % self.API_URL, get={'sid': sid})
diff --git a/module/plugins/accounts/RealdebridCom.py b/module/plugins/accounts/RealdebridCom.py
index 41d8a0975..ad2975aa9 100644
--- a/module/plugins/accounts/RealdebridCom.py
+++ b/module/plugins/accounts/RealdebridCom.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-import xml.dom.minidom as dom
+import xml.dom.minidom
from module.plugins.Account import Account
@@ -19,7 +19,7 @@ class RealdebridCom(Account):
if self.pin_code:
return {"premium": False}
html = req.load("https://real-debrid.com/api/account.php")
- xml = dom.parseString(html)
+ xml = xml.dom.minidom.parseString(html)
account_info = {"validuntil": float(xml.getElementsByTagName("expiration")[0].childNodes[0].nodeValue),
"trafficleft": -1}
diff --git a/module/plugins/accounts/WebshareCz.py b/module/plugins/accounts/WebshareCz.py
index f032e2317..8c53dd41e 100644
--- a/module/plugins/accounts/WebshareCz.py
+++ b/module/plugins/accounts/WebshareCz.py
@@ -12,7 +12,7 @@ from module.plugins.Account import Account
class WebshareCz(Account):
__name__ = "WebshareCz"
__type__ = "account"
- __version__ = "0.07"
+ __version__ = "0.08"
__description__ = """Webshare.cz account plugin"""
__license__ = "GPLv3"
@@ -26,7 +26,7 @@ class WebshareCz(Account):
def loadAccountInfo(self, user, req):
html = req.load("https://webshare.cz/api/user_data/",
- post={'wst': self.infos['wst']},
+ post={'wst': self.getAccountData(user).get('wst', None)},
decode=True)
self.logDebug("Response: " + html)
@@ -65,4 +65,4 @@ class WebshareCz(Account):
if "<status>OK</status>" not in login:
self.wrongPassword()
- self.infos['wst'] = re.search('<token>(.+)</token>', login).group(1)
+ data['wst'] = re.search('<token>(.+)</token>', login).group(1)
diff --git a/module/plugins/accounts/WorldbytezCom.py b/module/plugins/accounts/WorldbytezCom.py
new file mode 100644
index 000000000..a90dbea56
--- /dev/null
+++ b/module/plugins/accounts/WorldbytezCom.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.XFSAccount import XFSAccount
+
+
+class WorldbytezCom(XFSAccount):
+ __name__ = "WorldbytezCom"
+ __type__ = "account"
+ __version__ = "0.01"
+
+ __description__ = """Worldbytez.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = "worldbytez.com"
diff --git a/module/plugins/crypter/Dereferer.py b/module/plugins/crypter/Dereferer.py
index 8427c1540..85b84a242 100644
--- a/module/plugins/crypter/Dereferer.py
+++ b/module/plugins/crypter/Dereferer.py
@@ -1,17 +1,42 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer
+import re
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
-class Dereferer(SimpleDereferer):
+
+class Dereferer(SimpleCrypter):
__name__ = "Dereferer"
__type__ = "crypter"
- __version__ = "0.11"
+ __version__ = "0.14"
- __pattern__ = r'https?://([^/]+)/.*?(?P<LINK>(ht|f)tps?(://|%3A%2F%2F).+)'
+ __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)]
__description__ = """Crypter for dereferers"""
__license__ = "GPLv3"
- __authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = None
+ HOSTER_NAME = None
+
+
+ def _log(self, type, args):
+ msg = " | ".join(str(a).strip() for a in args if a)
+ logger = getattr(self.log, type)
+ logger("%s: %s: %s" % (self.__name__, self.HOSTER_NAME, msg or _("%s MARK" % type.upper())))
+
+
+ def init(self):
+ super(Dereferer, self).init()
+
+ self.__pattern__ = self.core.pluginManager.crypterPlugins[self.__name__]['pattern'] #@TODO: Recheck in 0.4.10
+
+ self.HOSTER_DOMAIN = re.match(self.__pattern__, self.pyfile.url).group("DOMAIN").lower()
+ self.HOSTER_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+)', self.HOSTER_DOMAIN) if part != '.')
+
+
+ def getLinks(self):
+ return [re.match(self.__pattern__, self.pyfile.url).group('LINK').strip()]
diff --git a/module/plugins/crypter/DontKnowMe.py b/module/plugins/crypter/DontKnowMe.py
deleted file mode 100644
index e56751972..000000000
--- a/module/plugins/crypter/DontKnowMe.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer
-
-
-class DontKnowMe(SimpleDereferer):
- __name__ = "DontKnowMe"
- __type__ = "crypter"
- __version__ = "0.11"
-
- __pattern__ = r'http://(?:www\.)?dontknow\.me/at/\?(?P<LINK>.+)'
- __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
- ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
-
- __description__ = """DontKnow.me decrypter plugin"""
- __license__ = "GPLv3"
- __authors__ = [("selaux", "")]
diff --git a/module/plugins/crypter/FilecryptCc.py b/module/plugins/crypter/FilecryptCc.py
index a1a94b6f6..4d2b42f90 100644
--- a/module/plugins/crypter/FilecryptCc.py
+++ b/module/plugins/crypter/FilecryptCc.py
@@ -10,13 +10,13 @@ import urlparse
from Crypto.Cipher import AES
from module.plugins.Crypter import Crypter
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
class FilecryptCc(Crypter):
__name__ = "FilecryptCc"
__type__ = "crypter"
- __version__ = "0.14"
+ __version__ = "0.15"
__pattern__ = r'https?://(?:www\.)?filecrypt\.cc/Container/\w+'
diff --git a/module/plugins/crypter/FurLy.py b/module/plugins/crypter/FurLy.py
new file mode 100644
index 000000000..b8e9332e2
--- /dev/null
+++ b/module/plugins/crypter/FurLy.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
+
+
+class FurLy(SimpleCrypter):
+ __name__ = "FurLy"
+ __type__ = "crypter"
+ __version__ = "0.01"
+
+ __pattern__ = r'http://(?:www\.)?fur\.ly/(\d/)?\w+'
+
+ __description__ = """Fur.ly decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ URL_REPLACEMENTS = [(r'fur\.ly/', r'fur\.ly/bar/')]
+
+ LINK_PATTERN = r'urls\[\d+\] = "(.+?)"'
+ OFFLINE_PATTERN = r'var output;\s*var total'
+
+
+getInfo = create_getInfo(FurLy)
diff --git a/module/plugins/crypter/GooGl.py b/module/plugins/crypter/GooGl.py
index 30e193b9d..b36e22884 100644
--- a/module/plugins/crypter/GooGl.py
+++ b/module/plugins/crypter/GooGl.py
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer, create_getInfo
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
from module.common.json_layer import json_loads
-class GooGl(SimpleDereferer):
+class GooGl(SimpleCrypter):
__name__ = "GooGl"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.03"
__pattern__ = r'https?://(?:www\.)?goo\.gl/([a-zA-Z]+/)?\w+'
@@ -22,11 +22,11 @@ class GooGl(SimpleDereferer):
OFFLINE_PATTERN = r'has been disabled|does not exist'
- def getLink(self):
+ def getLinks(self):
rep = self.load(self.API_URL, get={'shortUrl': self.pyfile.url})
self.logDebug("JSON data: " + rep)
rep = json_loads(rep)
- return rep['longUrl'] if "longUrl" in rep else None
+ return [rep['longUrl']] if "longUrl" in rep else None
getInfo = create_getInfo(GooGl)
diff --git a/module/plugins/crypter/LinkSaveIn.py b/module/plugins/crypter/LinkSaveIn.py
index 95652096d..dce74b689 100644
--- a/module/plugins/crypter/LinkSaveIn.py
+++ b/module/plugins/crypter/LinkSaveIn.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer, create_getInfo
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
-class LinkSaveIn(SimpleDereferer):
+class LinkSaveIn(SimpleCrypter):
__name__ = "LinkSaveIn"
__type__ = "crypter"
- __version__ = "2.04"
+ __version__ = "2.05"
__pattern__ = r'https?://(?:www\.)?linksave\.in/\w+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/MegaCoNzFolder.py b/module/plugins/crypter/MegaCoNzFolder.py
index bd135ac5f..0c6f224a4 100644
--- a/module/plugins/crypter/MegaCoNzFolder.py
+++ b/module/plugins/crypter/MegaCoNzFolder.py
@@ -10,7 +10,7 @@ class MegaCoNzFolder(Crypter):
__type__ = "crypter"
__version__ = "0.04"
- __pattern__ = r'(?:https?://(?:www\.)?mega\.co\.nz/|mega:|chrome:.+?)#F!(?P<ID>[\w^_]+)!(?P<KEY>[\w,\\-]+)'
+ __pattern__ = r'(?:https?://(?:www\.)?mega(\.co)?\.nz/|mega:|chrome:.+?)#F!(?P<ID>[\w^_]+)!(?P<KEY>[\w,\\-]+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
@@ -26,7 +26,7 @@ class MegaCoNzFolder(Crypter):
def decrypt(self, pyfile):
url = "https://mega.co.nz/#F!%s!%s" % re.match(self.__pattern__, pyfile.url).groups()
self.html = self.load("http://rapidgen.org/linkfinder", post={'linklisturl': url})
- self.urls = re.findall(r'(https://mega.co.nz/#N!.+?)<', self.html)
+ self.urls = re.findall(r'(https://mega(\.co)?\.nz/#N!.+?)<', self.html)
if not self.urls: #@TODO: Remove in 0.4.10
self.fail(_("No link grabbed"))
diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py
index 8ceb9d3c8..593e9b506 100644
--- a/module/plugins/crypter/NCryptIn.py
+++ b/module/plugins/crypter/NCryptIn.py
@@ -6,13 +6,13 @@ import re
from Crypto.Cipher import AES
from module.plugins.Crypter import Crypter
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
class NCryptIn(Crypter):
__name__ = "NCryptIn"
__type__ = "crypter"
- __version__ = "1.34"
+ __version__ = "1.35"
__pattern__ = r'http://(?:www\.)?ncrypt\.in/(?P<TYPE>folder|link|frame)-([^/\?]+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/SafelinkingNet.py b/module/plugins/crypter/SafelinkingNet.py
index 7f0915065..5d822af11 100644
--- a/module/plugins/crypter/SafelinkingNet.py
+++ b/module/plugins/crypter/SafelinkingNet.py
@@ -6,13 +6,13 @@ from BeautifulSoup import BeautifulSoup
from module.common.json_layer import json_loads
from module.plugins.Crypter import Crypter
-from module.plugins.internal.CaptchaService import SolveMedia
+from module.plugins.internal.SolveMedia import SolveMedia
class SafelinkingNet(Crypter):
__name__ = "SafelinkingNet"
__type__ = "crypter"
- __version__ = "0.14"
+ __version__ = "0.15"
__pattern__ = r'https?://(?:www\.)?safelinking\.net/([pd])/\w+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/TinyurlCom.py b/module/plugins/crypter/TinyurlCom.py
new file mode 100644
index 000000000..e2cf50358
--- /dev/null
+++ b/module/plugins/crypter/TinyurlCom.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
+
+
+class TinyurlCom(SimpleCrypter):
+ __name__ = "TinyurlCom"
+ __type__ = "crypter"
+ __version__ = "0.02"
+
+ __pattern__ = r'https?://(?:www\.)?(preview\.)?tinyurl\.com/[\w-]+'
+
+ __description__ = """Tinyurl.com decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ URL_REPLACEMENTS = [(r'preview\.', r'')]
+
+ OFFLINE_PATTERN = r">Error: Unable to find site's URL to redirect to"
+
+
+getInfo = create_getInfo(TinyurlCom)
diff --git a/module/plugins/crypter/XFileSharingProFolder.py b/module/plugins/crypter/XFileSharingProFolder.py
index 8b850271d..2e1a2f022 100644
--- a/module/plugins/crypter/XFileSharingProFolder.py
+++ b/module/plugins/crypter/XFileSharingProFolder.py
@@ -8,9 +8,9 @@ from module.plugins.internal.XFSCrypter import XFSCrypter, create_getInfo
class XFileSharingProFolder(XFSCrypter):
__name__ = "XFileSharingProFolder"
__type__ = "crypter"
- __version__ = "0.05"
+ __version__ = "0.06"
- __pattern__ = r'^unmatchable$'
+ __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)]
diff --git a/module/plugins/hooks/UserAgentSwitcher.py b/module/plugins/hooks/UserAgentSwitcher.py
index 5f9fd5212..74c43f7c4 100644
--- a/module/plugins/hooks/UserAgentSwitcher.py
+++ b/module/plugins/hooks/UserAgentSwitcher.py
@@ -8,10 +8,12 @@ from module.plugins.Hook import Hook
class UserAgentSwitcher(Hook):
__name__ = "UserAgentSwitcher"
__type__ = "hook"
- __version__ = "0.07"
+ __version__ = "0.08"
- __config__ = [("activated", "bool", "Activated" , True ),
- ("useragent", "str" , "Custom user-agent string" , "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0")]
+ __config__ = [("activated" , "bool", "Activated" , True ),
+ ("connecttimeout", "int" , "Connection timeout in seconds" , 60 ),
+ ("maxredirs" , "int" , "Maximum number of redirects to follow" , 10 ),
+ ("useragent" , "str" , "Custom user-agent string" , "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0")]
__description__ = """Custom user-agent"""
__license__ = "GPLv3"
@@ -26,7 +28,16 @@ class UserAgentSwitcher(Hook):
def downloadPreparing(self, pyfile):
- useragent = self.getConfig('useragent').encode("utf8", "replace") #@TODO: Remove `encode` in 0.4.10
+ connecttimeout = self.getConfig('connecttimeout')
+ maxredirs = self.getConfig('maxredirs')
+ useragent = self.getConfig('useragent').encode("utf8", "replace") #@TODO: Remove `encode` in 0.4.10
+
+ if connecttimeout:
+ pyfile.plugin.req.http.c.setopt(pycurl.CONNECTTIMEOUT, connecttimeout)
+
+ if maxredirs:
+ pyfile.plugin.req.http.c.setopt(pycurl.MAXREDIRS, maxredirs)
+
if useragent:
self.logDebug("Use custom user-agent string: " + useragent)
pyfile.plugin.req.http.c.setopt(pycurl.USERAGENT, useragent)
diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py
index 7443266b3..62872992c 100644
--- a/module/plugins/hooks/XFileSharingPro.py
+++ b/module/plugins/hooks/XFileSharingPro.py
@@ -8,7 +8,7 @@ from module.plugins.Hook import Hook
class XFileSharingPro(Hook):
__name__ = "XFileSharingPro"
__type__ = "hook"
- __version__ = "0.37"
+ __version__ = "0.38"
__config__ = [("activated" , "bool", "Activated" , True ),
("use_hoster_list" , "bool", "Load listed hosters only" , False),
@@ -17,25 +17,25 @@ class XFileSharingPro(Hook):
("hoster_list" , "str" , "Hoster list (comma separated)" , "" ),
("crypter_list" , "str" , "Crypter list (comma separated)", "" )]
- __description__ = """Load XFileSharingPro based hosters and crypter which don't need a own plugin to run"""
+ __description__ = """Load XFileSharingPro based hosters and crypters which don't need a own plugin to run"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
interval = 0 #@TODO: Remove in 0.4.10
- regexp = {'hoster' : (r'https?://(?:www\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{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\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{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+')}
HOSTER_BUILTIN = [#WORKING HOSTERS:
"backin.net", "eyesfile.ca", "file4safe.com", "fileband.com", "filedwon.com", "fileparadox.in",
"filevice.com", "hostingbulk.com", "junkyvideo.com", "linestorage.com", "ravishare.com", "ryushare.com",
- "salefiles.com", "sendmyway.com", "sharesix.com", "thefile.me", "verzend.be", "xvidstage.com",
+ "salefiles.com", "sendmyway.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", "sharebeast.com", "sharerepo.com", "shareswift.com", "uploadbaz.com", "uploadc.com",
- "vidbull.com", "worldbytez.com", "zalaa.com", "zomgupload.com",
+ "vidbull.com", "zalaa.com", "zomgupload.com",
#NOT WORKING:
"amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", "laoupload.com", "rd-fs.com"]
CRYPTER_BUILTIN = ["junocloud.me", "rapidfileshare.net"]
diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py
index 79aaedcd9..5c709e4f7 100644
--- a/module/plugins/hoster/BitshareCom.py
+++ b/module/plugins/hoster/BitshareCom.py
@@ -4,14 +4,14 @@ from __future__ import with_statement
import re
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class BitshareCom(SimpleHoster):
__name__ = "BitshareCom"
__type__ = "hoster"
- __version__ = "0.53"
+ __version__ = "0.54"
__pattern__ = r'http://(?:www\.)?bitshare\.com/(files/)?(?(1)|\?f=)(?P<ID>\w+)(?(1)/(?P<NAME>.+?)\.html)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/CatShareNet.py b/module/plugins/hoster/CatShareNet.py
index 868be4033..c966dbe1a 100644
--- a/module/plugins/hoster/CatShareNet.py
+++ b/module/plugins/hoster/CatShareNet.py
@@ -3,13 +3,13 @@
import re
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
class CatShareNet(SimpleHoster):
__name__ = "CatShareNet"
__type__ = "hoster"
- __version__ = "0.14"
+ __version__ = "0.15"
__pattern__ = r'http://(?:www\.)?catshare\.net/\w{16}'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/CrockoCom.py b/module/plugins/hoster/CrockoCom.py
index 4f872f60a..098ba5fab 100644
--- a/module/plugins/hoster/CrockoCom.py
+++ b/module/plugins/hoster/CrockoCom.py
@@ -3,14 +3,14 @@
import re
import urlparse
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class CrockoCom(SimpleHoster):
__name__ = "CrockoCom"
__type__ = "hoster"
- __version__ = "0.19"
+ __version__ = "0.20"
__pattern__ = r'http://(?:www\.)?(crocko|easy-share)\.com/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/DateiTo.py b/module/plugins/hoster/DateiTo.py
index f0ad95d1e..92a96b9ec 100644
--- a/module/plugins/hoster/DateiTo.py
+++ b/module/plugins/hoster/DateiTo.py
@@ -2,14 +2,14 @@
import re
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DateiTo(SimpleHoster):
__name__ = "DateiTo"
__type__ = "hoster"
- __version__ = "0.08"
+ __version__ = "0.09"
__pattern__ = r'http://(?:www\.)?datei\.to/datei/(?P<ID>\w+)\.html'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/DepositfilesCom.py b/module/plugins/hoster/DepositfilesCom.py
index 8559bbc36..18f23f552 100644
--- a/module/plugins/hoster/DepositfilesCom.py
+++ b/module/plugins/hoster/DepositfilesCom.py
@@ -3,14 +3,14 @@
import re
import urllib
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DepositfilesCom(SimpleHoster):
__name__ = "DepositfilesCom"
__type__ = "hoster"
- __version__ = "0.55"
+ __version__ = "0.56"
__pattern__ = r'https?://(?:www\.)?(depositfiles\.com|dfiles\.(eu|ru))(/\w{1,3})?/files/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/DlFreeFr.py b/module/plugins/hoster/DlFreeFr.py
index 72d15852c..ff5ee7b92 100644
--- a/module/plugins/hoster/DlFreeFr.py
+++ b/module/plugins/hoster/DlFreeFr.py
@@ -5,7 +5,6 @@ import re
from module.network.Browser import Browser
from module.network.CookieJar import CookieJar
-from module.plugins.internal.CaptchaService import AdYouLike
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns
@@ -36,7 +35,7 @@ class CustomBrowser(Browser):
class DlFreeFr(SimpleHoster):
__name__ = "DlFreeFr"
__type__ = "hoster"
- __version__ = "0.28"
+ __version__ = "0.30"
__pattern__ = r'http://(?:www\.)?dl\.free\.fr/(\w+|getfile\.pl\?file=/\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -44,12 +43,12 @@ class DlFreeFr(SimpleHoster):
__description__ = """Dl.free.fr hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("the-razer", "daniel_ AT gmx DOT net"),
- ("zoidberg", "zoidberg@mujmail.cz"),
- ("Toilal", "toilal.dev@gmail.com")]
+ ("zoidberg" , "zoidberg@mujmail.cz" ),
+ ("Toilal" , "toilal.dev@gmail.com" )]
- NAME_PATTERN = r'Fichier:</td>\s*<td.*?>(?P<N>[^>]*)</td>'
- SIZE_PATTERN = r'Taille:</td>\s*<td.*?>(?P<S>[\d.,]+\w)o'
+ NAME_PATTERN = r'Fichier:</td>\s*<td.*?>(?P<N>[^>]*)</td>'
+ SIZE_PATTERN = r'Taille:</td>\s*<td.*?>(?P<S>[\d.,]+\w)o'
OFFLINE_PATTERN = r'Erreur 404 - Document non trouv|Fichier inexistant|Le fichier demand&eacute; n\'a pas &eacute;t&eacute; trouv&eacute;'
@@ -84,6 +83,8 @@ class DlFreeFr(SimpleHoster):
# Direct access to requested file for users using free.fr as Internet Service Provider.
self.link = valid_url
+ self.download(self.link, disposition=True)
+
elif headers.get('code') == 404:
self.offline()
@@ -93,15 +94,10 @@ class DlFreeFr(SimpleHoster):
def handleFree(self, pyfile):
action, inputs = self.parseHtmlForm('action="getfile.pl"')
-
- adyoulike = AdYouLike(self)
- response, challenge = adyoulike.challenge()
- inputs.update(response)
-
self.load("http://dl.free.fr/getfile.pl", post=inputs)
headers = self.getLastHeaders()
if headers.get("code") == 302 and "set-cookie" in headers and "location" in headers:
- m = re.search("(.*?)=(.*?); path=(.*?); domain=(.*?)", headers.get("set-cookie"))
+ m = re.search("(.*?)=(.*?); path=(.*?); domain=(.*)", headers.get("set-cookie"))
cj = CookieJar(__name__)
if m:
cj.setCookie(m.group(4), m.group(1), m.group(2), m.group(3))
@@ -109,7 +105,6 @@ class DlFreeFr(SimpleHoster):
self.fail(_("Cookie error"))
self.link = headers.get("location")
-
self.req.setCookieJar(cj)
else:
self.fail(_("Invalid response"))
diff --git a/module/plugins/hoster/ExtabitCom.py b/module/plugins/hoster/ExtabitCom.py
index f3b4d28be..ead2e1e53 100644
--- a/module/plugins/hoster/ExtabitCom.py
+++ b/module/plugins/hoster/ExtabitCom.py
@@ -4,14 +4,14 @@ import re
from module.common.json_layer import json_loads
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, secondsToMidnight
class ExtabitCom(SimpleHoster):
__name__ = "ExtabitCom"
__type__ = "hoster"
- __version__ = "0.65"
+ __version__ = "0.66"
__pattern__ = r'http://(?:www\.)?extabit\.com/(file|go|fid)/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/FileboomMe.py b/module/plugins/hoster/FileboomMe.py
new file mode 100644
index 000000000..9cdeebe3d
--- /dev/null
+++ b/module/plugins/hoster/FileboomMe.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from urlparse import urljoin
+
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+
+
+class FileboomMe(SimpleHoster):
+ __name__ = "FileboomMe"
+ __type__ = "hoster"
+ __version__ = "0.02"
+
+ __pattern__ = r'https?://f(?:ile)?boom\.me/file/(?P<ID>\w+)'
+
+ __description__ = """Fileboom.me hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("GammaC0de", None)]
+
+
+ NAME_PATTERN = r'<i class="icon-download"></i>\s*(?P<N>.+?)\s*<'
+ SIZE_PATTERN = r'File size: (?P<S>[\d.,]+) (?P<U>[\w^_]+)'
+ OFFLINE_PATTERN = r'>This file is no longer available'
+
+ WAIT_PATTERN = r'<div class="tik-tak">([\d:]+)'
+ LINK_PATTERN = r'/file/url\.html\?file=\w+'
+
+ CAPTCHA_PATTERN = r'<img .* src="(/file/captcha.html\?v=\w+)"'
+
+
+ def setup(self):
+ self.resumeDownload = True
+ self.multiDL = False
+ self.chunkLimit = 1
+
+
+ def handleFree(self, pyfile):
+ post_url = urljoin(pyfile.url, "/file/" + self.info['pattern']['ID'])
+
+ m = re.search(r'data-slow-id="(\w+)"', self.html)
+ if m:
+ self.html = self.load(post_url,
+ post={'slow_id': m.group(1)})
+
+ m = re.search(self.LINK_PATTERN, self.html)
+ if m:
+ self.link = urljoin(pyfile.url, m.group(0))
+
+ else:
+ for _i in xrange(5):
+ m = re.search(r'<input type="hidden" name="uniqueId" value="(\w+)">', self.html)
+ if m:
+ uniqueId = m.group(1)
+
+ m = re.search(self.CAPTCHA_PATTERN, self.html)
+ if m:
+ captcha = self.decryptCaptcha(urljoin(pyfile.url, m.group(1)))
+
+ self.html = self.load(post_url,
+ post={'CaptchaForm[code]' : captcha,
+ 'free' : 1,
+ 'freeDownloadRequest': 1,
+ 'uniqueId' : uniqueId})
+
+ if 'The verification code is incorrect' in self.html:
+ self.invalidCaptcha()
+
+ else:
+ self.checkErrors()
+
+ self.html = self.load(post_url,
+ post={'free' : 1,
+ 'uniqueId': uniqueId})
+
+ m = re.search(self.LINK_PATTERN, self.html)
+ if m:
+ self.link = urljoin(pyfile.url, m.group(0))
+
+ else:
+ self.invalidCaptcha()
+
+ break
+
+ else:
+ self.fail(_("Captcha not found"))
+
+ else:
+ m = re.search(r'>\s*Please wait ([\d:]+)', self.html)
+ if m:
+ wait_time = 0
+ for v in re.findall(r'(\d+)', m.group(1), re.I):
+ wait_time = 60 * wait_time + int(v)
+ self.wait(wait_time)
+ self.retry()
+ break
+
+ else:
+ self.fail(_("Invalid captcha"))
+
+
+getInfo = create_getInfo(FileboomMe)
diff --git a/module/plugins/hoster/FilecloudIo.py b/module/plugins/hoster/FilecloudIo.py
index 38d2972a1..346e9c444 100644
--- a/module/plugins/hoster/FilecloudIo.py
+++ b/module/plugins/hoster/FilecloudIo.py
@@ -3,14 +3,14 @@
import re
from module.common.json_layer import json_loads
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilecloudIo(SimpleHoster):
__name__ = "FilecloudIo"
__type__ = "hoster"
- __version__ = "0.08"
+ __version__ = "0.09"
__pattern__ = r'http://(?:www\.)?(?:filecloud\.io|ifile\.it|mihd\.net)/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/FilepostCom.py b/module/plugins/hoster/FilepostCom.py
index 2a9e3dc26..1f3de6717 100644
--- a/module/plugins/hoster/FilepostCom.py
+++ b/module/plugins/hoster/FilepostCom.py
@@ -4,14 +4,14 @@ import re
import time
from module.common.json_layer import json_loads
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilepostCom(SimpleHoster):
__name__ = "FilepostCom"
__type__ = "hoster"
- __version__ = "0.33"
+ __version__ = "0.34"
__pattern__ = r'https?://(?:www\.)?(?:filepost\.com/files|fp\.io)/(?P<ID>[^/]+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py
index 156392c79..3b876ed48 100644
--- a/module/plugins/hoster/FilerNet.py
+++ b/module/plugins/hoster/FilerNet.py
@@ -8,14 +8,14 @@ import pycurl
import re
import urlparse
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilerNet(SimpleHoster):
__name__ = "FilerNet"
__type__ = "hoster"
- __version__ = "0.19"
+ __version__ = "0.20"
__pattern__ = r'https?://(?:www\.)?filer\.net/get/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py
index 4bca2eb59..f8cf652b9 100644
--- a/module/plugins/hoster/FileserveCom.py
+++ b/module/plugins/hoster/FileserveCom.py
@@ -6,7 +6,7 @@ from module.common.json_layer import json_loads
from module.network.RequestFactory import getURL
from module.plugins.Hoster import Hoster
from module.plugins.Plugin import chunks
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import secondsToMidnight
from module.utils import parseFileSize
@@ -33,7 +33,7 @@ def checkFile(plugin, urls):
class FileserveCom(Hoster):
__name__ = "FileserveCom"
__type__ = "hoster"
- __version__ = "0.54"
+ __version__ = "0.55"
__pattern__ = r'http://(?:www\.)?fileserve\.com/file/(?P<ID>[^/]+)'
diff --git a/module/plugins/hoster/FreakshareCom.py b/module/plugins/hoster/FreakshareCom.py
index 6a595e75b..d005443d9 100644
--- a/module/plugins/hoster/FreakshareCom.py
+++ b/module/plugins/hoster/FreakshareCom.py
@@ -3,14 +3,14 @@
import re
from module.plugins.Hoster import Hoster
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import secondsToMidnight
class FreakshareCom(Hoster):
__name__ = "FreakshareCom"
__type__ = "hoster"
- __version__ = "0.40"
+ __version__ = "0.41"
__pattern__ = r'http://(?:www\.)?freakshare\.(net|com)/files/\S*?/'
diff --git a/module/plugins/hoster/Keep2ShareCc.py b/module/plugins/hoster/Keep2ShareCc.py
index fdae65096..fb94d12c4 100644
--- a/module/plugins/hoster/Keep2ShareCc.py
+++ b/module/plugins/hoster/Keep2ShareCc.py
@@ -3,14 +3,14 @@
import re
import urlparse
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class Keep2ShareCc(SimpleHoster):
__name__ = "Keep2ShareCc"
__type__ = "hoster"
- __version__ = "0.21"
+ __version__ = "0.22"
__pattern__ = r'https?://(?:www\.)?(keep2share|k2s|keep2s)\.cc/file/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/KingfilesNet.py b/module/plugins/hoster/KingfilesNet.py
index 99f309d00..42547d658 100644
--- a/module/plugins/hoster/KingfilesNet.py
+++ b/module/plugins/hoster/KingfilesNet.py
@@ -2,14 +2,14 @@
import re
-from module.plugins.internal.CaptchaService import SolveMedia
+from module.plugins.internal.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class KingfilesNet(SimpleHoster):
__name__ = "KingfilesNet"
__type__ = "hoster"
- __version__ = "0.07"
+ __version__ = "0.08"
__pattern__ = r'http://(?:www\.)?kingfiles\.net/(?P<ID>\w{12})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/LetitbitNet.py b/module/plugins/hoster/LetitbitNet.py
index 40d792e11..62afb6c7c 100644
--- a/module/plugins/hoster/LetitbitNet.py
+++ b/module/plugins/hoster/LetitbitNet.py
@@ -11,7 +11,7 @@ import urlparse
from module.common.json_layer import json_loads, json_dumps
from module.network.RequestFactory import getURL
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, secondsToMidnight
@@ -35,7 +35,7 @@ def getInfo(urls):
class LetitbitNet(SimpleHoster):
__name__ = "LetitbitNet"
__type__ = "hoster"
- __version__ = "0.30"
+ __version__ = "0.31"
__pattern__ = r'https?://(?:www\.)?(letitbit|shareflare)\.net/download/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/LoadTo.py b/module/plugins/hoster/LoadTo.py
index 2b4202051..d2b25f0db 100644
--- a/module/plugins/hoster/LoadTo.py
+++ b/module/plugins/hoster/LoadTo.py
@@ -6,14 +6,14 @@
import re
-from module.plugins.internal.CaptchaService import SolveMedia
+from module.plugins.internal.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class LoadTo(SimpleHoster):
__name__ = "LoadTo"
__type__ = "hoster"
- __version__ = "0.22"
+ __version__ = "0.23"
__pattern__ = r'http://(?:www\.)?load\.to/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py
index 26af8153f..f4932d93d 100644
--- a/module/plugins/hoster/LuckyShareNet.py
+++ b/module/plugins/hoster/LuckyShareNet.py
@@ -4,14 +4,14 @@ import re
from bottle import json_loads
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class LuckyShareNet(SimpleHoster):
__name__ = "LuckyShareNet"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.07"
__pattern__ = r'https?://(?:www\.)?luckyshare\.net/(?P<ID>\d{10,})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/MediafireCom.py b/module/plugins/hoster/MediafireCom.py
index 1ba38fdf7..09eb4705d 100644
--- a/module/plugins/hoster/MediafireCom.py
+++ b/module/plugins/hoster/MediafireCom.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.CaptchaService import SolveMedia, ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.internal.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class MediafireCom(SimpleHoster):
__name__ = "MediafireCom"
__type__ = "hoster"
- __version__ = "0.88"
+ __version__ = "0.89"
__pattern__ = r'https?://(?:www\.)?mediafire\.com/(file/|view/\??|download(\.php\?|/)|\?)(?P<ID>\w{15})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/MegaCoNz.py b/module/plugins/hoster/MegaCoNz.py
index aa7755af4..5280b42ec 100644
--- a/module/plugins/hoster/MegaCoNz.py
+++ b/module/plugins/hoster/MegaCoNz.py
@@ -48,9 +48,9 @@ from module.utils import decode, fs_decode, fs_encode
class MegaCoNz(Hoster):
__name__ = "MegaCoNz"
__type__ = "hoster"
- __version__ = "0.26"
+ __version__ = "0.29"
- __pattern__ = r'(?:https?://(?:www\.)?mega\.co\.nz/|mega:|chrome:.+?)#(?P<TYPE>N|)!(?P<ID>[\w^_]+)!(?P<KEY>[\w,-]+)'
+ __pattern__ = r'(?:https?://(?:www\.)?mega(?:\.co)?\.nz/|mega:|chrome:.+?)#(?P<TYPE>N|)!(?P<ID>[\w^_]+)!(?P<KEY>[\w,-]+)'
__description__ = """Mega.co.nz hoster plugin"""
__license__ = "GPLv3"
@@ -82,7 +82,7 @@ class MegaCoNz(Hoster):
""" Dispatch a call to the api, see https://mega.co.nz/#developers """
# generate a session id, no idea where to obtain elsewhere
- uid = random.random.randint(10 << 9, 10 ** 10)
+ uid = random.randint(10 << 9, 10 ** 10)
res = self.load(self.API_URL, get={'id': uid}, post=json_dumps([kwargs]))
self.logDebug("Api Response: " + res)
diff --git a/module/plugins/hoster/NitroflareCom.py b/module/plugins/hoster/NitroflareCom.py
index 6696d15d3..a0734d9b1 100644
--- a/module/plugins/hoster/NitroflareCom.py
+++ b/module/plugins/hoster/NitroflareCom.py
@@ -2,30 +2,28 @@
import re
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster
class NitroflareCom(SimpleHoster):
__name__ = "NitroflareCom"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.14"
__pattern__ = r'https?://(?:www\.)?nitroflare\.com/view/(?P<ID>[\w^_]+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
__description__ = """Nitroflare.com hoster plugin"""
__license__ = "GPLv3"
- __authors__ = [("sahil", "sahilshekhawat01@gmail.com"),
- ("Walter Purcaro", "vuolter@gmail.com"),
- ("Stickell", "l.stickell@yahoo.it")]
-
- # URL_REPLACEMENTS = [("http://", "https://")]
+ __authors__ = [("sahil" , "sahilshekhawat01@gmail.com"),
+ ("Walter Purcaro", "vuolter@gmail.com" ),
+ ("Stickell" , "l.stickell@yahoo.it" )]
INFO_PATTERN = r'title="(?P<N>.+?)".+>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
OFFLINE_PATTERN = r'>File doesn\'t exist'
- 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'
@@ -61,12 +59,4 @@ class NitroflareCom(SimpleHoster):
'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
- if "The captcha wasn't entered correctly" in self.html:
- self.logWarning("The captcha wasn't entered correctly")
- return
-
- if "You have to fill the captcha" in self.html:
- self.logWarning("Captcha unfilled")
- return
-
return super(NitroflareCom, self).handleFree(pyfile)
diff --git a/module/plugins/hoster/OboomCom.py b/module/plugins/hoster/OboomCom.py
index cfc448ff0..b50e2fb42 100644
--- a/module/plugins/hoster/OboomCom.py
+++ b/module/plugins/hoster/OboomCom.py
@@ -7,13 +7,13 @@ import re
from module.common.json_layer import json_loads
from module.plugins.Hoster import Hoster
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
class OboomCom(Hoster):
__name__ = "OboomCom"
__type__ = "hoster"
- __version__ = "0.32"
+ __version__ = "0.33"
__pattern__ = r'https?://(?:www\.)?oboom\.com/(?:#(?:id=|/)?)?(?P<ID>\w{8})'
diff --git a/module/plugins/hoster/OpenloadIo.py b/module/plugins/hoster/OpenloadIo.py
index c31b5b997..5a60b6787 100644
--- a/module/plugins/hoster/OpenloadIo.py
+++ b/module/plugins/hoster/OpenloadIo.py
@@ -6,14 +6,14 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class OpenloadIo(SimpleHoster):
__name__ = "OpenloadIo"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.02"
__pattern__ = r'https?://(?:www\.)?openload\.io/f/\w{11}'
__description__ = """Openload.io hoster plugin"""
__license__ = "GPLv3"
- NAME_PATTERN = r'<span id="filename">(?P<N>.+)</'
+ 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)"
diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py
index ae74e8a63..bd6bb8582 100644
--- a/module/plugins/hoster/RapidgatorNet.py
+++ b/module/plugins/hoster/RapidgatorNet.py
@@ -5,14 +5,16 @@ import re
from module.common.json_layer import json_loads
from module.network.HTTPRequest import BadHeader
-from module.plugins.internal.CaptchaService import AdsCaptcha, ReCaptcha, SolveMedia
+from module.plugins.internal.AdsCaptcha import AdsCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.internal.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class RapidgatorNet(SimpleHoster):
__name__ = "RapidgatorNet"
__type__ = "hoster"
- __version__ = "0.33"
+ __version__ = "0.34"
__pattern__ = r'http://(?:www\.)?(rapidgator\.net|rg\.to)/file/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/RapiduNet.py b/module/plugins/hoster/RapiduNet.py
index fcccbbebc..da353ec70 100644
--- a/module/plugins/hoster/RapiduNet.py
+++ b/module/plugins/hoster/RapiduNet.py
@@ -5,14 +5,14 @@ import re
import time
from module.common.json_layer import json_loads
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class RapiduNet(SimpleHoster):
__name__ = "RapiduNet"
__type__ = "hoster"
- __version__ = "0.08"
+ __version__ = "0.09"
__pattern__ = r'https?://(?:www\.)?rapidu\.net/(?P<ID>\d{10})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index a260f39f7..64a490993 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -6,14 +6,14 @@ import urllib
import urlparse
from module.network.RequestFactory import getURL
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class ShareonlineBiz(SimpleHoster):
__name__ = "ShareonlineBiz"
__type__ = "hoster"
- __version__ = "0.50"
+ __version__ = "0.51"
__pattern__ = r'https?://(?:www\.)?(share-online\.biz|egoshare\.com)/(download\.php\?id=|dl/)(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -39,25 +39,24 @@ class ShareonlineBiz(SimpleHoster):
def apiInfo(cls, url):
info = super(ShareonlineBiz, cls).apiInfo(url)
- if url:
- field = getURL("http://api.share-online.biz/linkcheck.php",
- get={'md5' : "1",
- 'links': re.match(cls.__pattern__, url).group("ID")},
- decode=True).split(";")
-
- try:
- if field[1] == "OK":
- info['fileid'] = field[0]
- info['status'] = 2
- info['name'] = field[2]
- info['size'] = field[3] #: in bytes
- info['md5'] = field[4].strip().lower().replace("\n\n", "") #: md5
-
- elif field[1] in ("DELETED", "NOT FOUND"):
- info['status'] = 1
-
- except IndexError:
- pass
+ field = getURL("http://api.share-online.biz/linkcheck.php",
+ get={'md5' : "1",
+ 'links': re.match(cls.__pattern__, url).group("ID")},
+ decode=True).split(";")
+
+ try:
+ if field[1] == "OK":
+ info['fileid'] = field[0]
+ info['status'] = 2
+ info['name'] = field[2]
+ info['size'] = field[3] #: in bytes
+ info['md5'] = field[4].strip().lower().replace("\n\n", "") #: md5
+
+ elif field[1] in ("DELETED", "NOT FOUND"):
+ info['status'] = 1
+
+ except IndexError:
+ pass
return info
diff --git a/module/plugins/hoster/TurbobitNet.py b/module/plugins/hoster/TurbobitNet.py
index 7995bd0c0..254e06c2a 100644
--- a/module/plugins/hoster/TurbobitNet.py
+++ b/module/plugins/hoster/TurbobitNet.py
@@ -10,14 +10,14 @@ import urllib
from Crypto.Cipher import ARC4
from module.network.RequestFactory import getURL
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, timestamp
class TurbobitNet(SimpleHoster):
__name__ = "TurbobitNet"
__type__ = "hoster"
- __version__ = "0.19"
+ __version__ = "0.20"
__pattern__ = r'http://(?:www\.)?turbobit\.net/(?:download/free/)?(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/TusfilesNet.py b/module/plugins/hoster/TusfilesNet.py
index 6021a4c30..a79d8c869 100644
--- a/module/plugins/hoster/TusfilesNet.py
+++ b/module/plugins/hoster/TusfilesNet.py
@@ -18,7 +18,6 @@ class TusfilesNet(XFSHoster):
INFO_PATTERN = r'\](?P<N>.+) - (?P<S>[\d.,]+) (?P<U>[\w^_]+)\['
- OFFLINE_PATTERN = r'>File Not Found|<Title>TusFiles - Fast Sharing Files!|The file you are trying to download is no longer available'
def setup(self):
diff --git a/module/plugins/hoster/UploadableCh.py b/module/plugins/hoster/UploadableCh.py
index 2907bd825..f323a3538 100644
--- a/module/plugins/hoster/UploadableCh.py
+++ b/module/plugins/hoster/UploadableCh.py
@@ -2,14 +2,14 @@
import re
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UploadableCh(SimpleHoster):
__name__ = "UploadableCh"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.10"
__pattern__ = r'http://(?:www\.)?uploadable\.ch/file/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py
index 669694b22..16966a23d 100644
--- a/module/plugins/hoster/UploadedTo.py
+++ b/module/plugins/hoster/UploadedTo.py
@@ -4,14 +4,14 @@ import re
import time
from module.network.RequestFactory import getURL
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UploadedTo(SimpleHoster):
__name__ = "UploadedTo"
__type__ = "hoster"
- __version__ = "0.88"
+ __version__ = "0.89"
__pattern__ = r'https?://(?:www\.)?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/UpstoreNet.py b/module/plugins/hoster/UpstoreNet.py
index ec0c88c82..6410a2dce 100644
--- a/module/plugins/hoster/UpstoreNet.py
+++ b/module/plugins/hoster/UpstoreNet.py
@@ -2,14 +2,14 @@
import re
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UpstoreNet(SimpleHoster):
__name__ = "UpstoreNet"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
__pattern__ = r'https?://(?:www\.)?upstore\.net/'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/WebshareCz.py b/module/plugins/hoster/WebshareCz.py
index ae670c8d4..c898d23ab 100644
--- a/module/plugins/hoster/WebshareCz.py
+++ b/module/plugins/hoster/WebshareCz.py
@@ -9,42 +9,41 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class WebshareCz(SimpleHoster):
__name__ = "WebshareCz"
__type__ = "hoster"
- __version__ = "0.16"
+ __version__ = "0.18"
- __pattern__ = r'https?://(?:www\.)?webshare\.cz/(?:#/)?file/(?P<ID>\w+)'
+ __pattern__ = r'https?://(?:www\.)?(en\.)?webshare\.cz/(?:#/)?file/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
__description__ = """WebShare.cz hoster plugin"""
__license__ = "GPLv3"
- __authors__ = [("stickell", "l.stickell@yahoo.it"),
- ("rush", "radek.senfeld@gmail.com")]
+ __authors__ = [("stickell", "l.stickell@yahoo.it "),
+ ("rush" , "radek.senfeld@gmail.com")]
@classmethod
- def getInfo(cls, url="", html=""):
- info = super(WebshareCz, cls).getInfo(url, html)
+ def apiInfo(cls, url):
+ info = super(WebshareCz, cls).apiInfo(url)
- if url:
- info['pattern'] = re.match(cls.__pattern__, url).groupdict()
+ info['pattern'] = re.match(cls.__pattern__, url).groupdict()
- api_data = getURL("https://webshare.cz/api/file_info/",
- post={'ident': info['pattern']['ID']},
- decode=True)
+ api_data = getURL("https://webshare.cz/api/file_info/",
+ post={'ident': info['pattern']['ID'], 'wst': ""},
+ decode=True)
- if 'File not found' in api_data:
- info['status'] = 1
- else:
- info["status"] = 2
- info['name'] = re.search('<name>(.+)</name>', api_data).group(1) or info['name']
- info['size'] = re.search('<size>(.+)</size>', api_data).group(1) or info['size']
+ if not re.search(r'<status>OK', api_data):
+ info['status'] = 1
+ else:
+ info['status'] = 2
+ info['name'] = re.search(r'<name>(.+?)<', api_data).group(1)
+ info['size'] = re.search(r'<size>(.+?)<', api_data).group(1)
return info
def handleFree(self, pyfile):
- wst = self.account.infos['wst'] if self.account and 'wst' in self.account.infos else ""
+ wst = self.account.getAccountData(self.user).get('wst', None) if self.account else None
- api_data = getURL('https://webshare.cz/api/file_link/',
+ api_data = getURL("https://webshare.cz/api/file_link/",
post={'ident': self.info['pattern']['ID'], 'wst': wst},
decode=True)
diff --git a/module/plugins/hoster/XFileSharingPro.py b/module/plugins/hoster/XFileSharingPro.py
index 1bfb504b7..169fbc8d3 100644
--- a/module/plugins/hoster/XFileSharingPro.py
+++ b/module/plugins/hoster/XFileSharingPro.py
@@ -8,9 +8,9 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class XFileSharingPro(XFSHoster):
__name__ = "XFileSharingPro"
__type__ = "hoster"
- __version__ = "0.45"
+ __version__ = "0.46"
- __pattern__ = r'^unmatchable$'
+ __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"
diff --git a/module/plugins/hoster/ZahikiNet.py b/module/plugins/hoster/ZahikiNet.py
new file mode 100644
index 000000000..b2705662b
--- /dev/null
+++ b/module/plugins/hoster/ZahikiNet.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+
+
+class ZahikiNet(SimpleHoster):
+ __name__ = "ZahikiNet"
+ __type__ = "hoster"
+ __version__ = "0.01"
+
+ __pattern__ = r'https?://(?:www\.)?zahiki\.net/\w+/.+'
+
+ __description__ = """Zahiki.net hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ DIRECT_LINK = True
+
+ NAME_PATTERN = r'/(?P<N>.+?) </title>'
+ OFFLINE_PATTERN = r'>(Not Found|Il file selezionato non esiste)'
+
+ LINK_FREE_PATTERN = r'file: "(.+?)"'
+
+
+ def setup(self):
+ self.resumeDownload = True
+ self.multiDL = True
+ self.limitDL = 6
+
+
+getInfo = create_getInfo(ZahikiNet)
diff --git a/module/plugins/hoster/ZippyshareCom.py b/module/plugins/hoster/ZippyshareCom.py
index c47ac4fe1..d776e5928 100644
--- a/module/plugins/hoster/ZippyshareCom.py
+++ b/module/plugins/hoster/ZippyshareCom.py
@@ -5,14 +5,14 @@ import urllib
from BeautifulSoup import BeautifulSoup
-from module.plugins.internal.CaptchaService import ReCaptcha
+from module.plugins.internal.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class ZippyshareCom(SimpleHoster):
__name__ = "ZippyshareCom"
__type__ = "hoster"
- __version__ = "0.78"
+ __version__ = "0.79"
__pattern__ = r'http://www\d{0,2}\.zippyshare\.com/v(/|iew\.jsp.*key=)(?P<KEY>[\w^_]+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/internal/AdYouLike.py b/module/plugins/internal/AdYouLike.py
new file mode 100644
index 000000000..a9c194dda
--- /dev/null
+++ b/module/plugins/internal/AdYouLike.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.common.json_layer import json_loads
+from module.plugins.internal.Captcha import Captcha
+
+
+class AdYouLike(Captcha):
+ __name__ = "AdYouLike"
+ __type__ = "captcha"
+ __version__ = "0.06"
+
+ __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):
+ html = html or self.retrieve_html()
+
+ 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: %s | Callback: %s" % self.key)
+ return self.key #: key is the tuple(ayl, callback)
+ else:
+ self.logWarning("Ayl or callback pattern not found")
+ return None
+
+
+ def challenge(self, key=None, html=None):
+ ayl, callback = key or self.retrieve_key(html)
+
+ # {"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:
+ self.fail(_("AdYouLike challenge pattern not found"))
+
+ 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:
+ self.fail(_("AdYouLike result not found"))
+
+ 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
diff --git a/module/plugins/internal/AdsCaptcha.py b/module/plugins/internal/AdsCaptcha.py
new file mode 100644
index 000000000..9cab99151
--- /dev/null
+++ b/module/plugins/internal/AdsCaptcha.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+
+import random
+import re
+
+from module.plugins.internal.Captcha import Captcha
+
+
+class AdsCaptcha(Captcha):
+ __name__ = "AdsCaptcha"
+ __type__ = "captcha"
+ __version__ = "0.09"
+
+ __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):
+ html = html or self.retrieve_html()
+
+ 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: %s | ID: %s" % self.key)
+ return self.key
+ else:
+ self.logWarning("Key or id pattern not found")
+ return None
+
+
+ def challenge(self, key=None, html=None):
+ PublicKey, CaptchaId = key or self.retrieve_key(html)
+
+ 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:
+ self.fail(_("AdsCaptcha challenge pattern not found"))
+
+ 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.random()},
+ cookies=True,
+ imgtype="jpg")
+
+ self.logDebug("Result: %s" % result)
+
+ return result
diff --git a/module/plugins/internal/Captcha.py b/module/plugins/internal/Captcha.py
new file mode 100644
index 000000000..b4af46493
--- /dev/null
+++ b/module/plugins/internal/Captcha.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.Plugin import Base
+
+
+#@TODO: Extend (new) Plugin class; remove all `html` args
+class Captcha(Base):
+ __name__ = "Captcha"
+ __type__ = "captcha"
+ __version__ = "0.29"
+
+ __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(Captcha, self).__init__(plugin.core)
+
+
+ #@TODO: Recheck in 0.4.10
+ def fail(self, reason):
+ self.plugin.fail(reason)
+ raise AttributeError(reason)
+
+
+ #@TODO: Recheck in 0.4.10
+ def retrieve_key(self, html):
+ if self.detect_key(html):
+ return self.key
+ else:
+ self.fail(_("%s key not found") % self.__name__)
+
+
+ #@TODO: Recheck in 0.4.10
+ def retrieve_html(self):
+ if hasattr(self.plugin, "html") and self.plugin.html:
+ return self.plugin.html
+ else:
+ self.fail(_("%s html not found") % self.__name__)
+
+
+ def detect_key(self, html=None):
+ raise NotImplementedError
+
+
+ def challenge(self, key=None, html=None):
+ raise NotImplementedError
+
+
+ def result(self, server, challenge):
+ raise NotImplementedError
diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py
deleted file mode 100644
index e51844965..000000000
--- a/module/plugins/internal/CaptchaService.py
+++ /dev/null
@@ -1,489 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import random
-import re
-import time
-import urlparse
-
-from base64 import b64encode
-
-from module.common.json_layer import json_loads
-from module.plugins.Plugin import Base, Fail
-
-
-#@TODO: Extend (new) Plugin class; remove all `html` args
-class CaptchaService(Base):
- __name__ = "CaptchaService"
- __type__ = "captcha"
- __version__ = "0.29"
-
- __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)
-
-
- #@TODO: Recheck in 0.4.10
- def fail(self, reason):
- self.plugin.fail(reason)
- raise AttributeError(reason)
-
-
- #@TODO: Recheck in 0.4.10
- def retrieve_key(self, html):
- if self.detect_key(html):
- return self.key
- else:
- self.fail(_("%s key not found") % self.__name__)
-
-
- #@TODO: Recheck in 0.4.10
- def retrieve_html(self):
- if hasattr(self.plugin, "html") and self.plugin.html:
- return self.plugin.html
- else:
- self.fail(_("%s html not found") % self.__name__)
-
-
- 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 AdYouLike(CaptchaService):
- __name__ = "AdYouLike"
- __type__ = "captcha"
- __version__ = "0.06"
-
- __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):
- html = html or self.retrieve_html()
-
- 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: %s | Callback: %s" % self.key)
- return self.key #: key is the tuple(ayl, callback)
- else:
- self.logWarning("Ayl or callback pattern not found")
- return None
-
-
- def challenge(self, key=None, html=None):
- ayl, callback = key or self.retrieve_key(html)
-
- # {"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:
- self.fail(_("AdYouLike challenge pattern not found"))
-
- 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:
- self.fail(_("AdYouLike result not found"))
-
- 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
-
-
-class AdsCaptcha(CaptchaService):
- __name__ = "AdsCaptcha"
- __type__ = "captcha"
- __version__ = "0.09"
-
- __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):
- html = html or self.retrieve_html()
-
- 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: %s | ID: %s" % self.key)
- return self.key
- else:
- self.logWarning("Key or id pattern not found")
- return None
-
-
- def challenge(self, key=None, html=None):
- PublicKey, CaptchaId = key or self.retrieve_key(html)
-
- 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:
- self.fail(_("AdsCaptcha challenge pattern not found"))
-
- 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.random()},
- cookies=True,
- imgtype="jpg")
-
- self.logDebug("Result: %s" % result)
-
- return result
-
-
-class ReCaptcha(CaptchaService):
- __name__ = "ReCaptcha"
- __type__ = "captcha"
- __version__ = "0.17"
-
- __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):
- html = html or self.retrieve_html()
-
- 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.logWarning("Key pattern not found")
- return None
-
-
- def challenge(self, key=None, html=None, version=None):
- key = key or self.retrieve_key(html)
-
- if version in (1, 2):
- return getattr(self, "_challenge_v%s" % version)(key)
-
- else:
- return self.challenge(key,
- version=2 if re.search(self.KEY_V2_PATTERN, html or self.retrieve_html()) else 1)
-
-
- 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:
- self.fail(_("ReCaptcha challenge pattern not found"))
-
- self.logDebug("Challenge: %s" % challenge)
-
- return self.result(server, challenge, key)
-
-
- def result(self, server, challenge, key):
- self.plugin.req.load("http://www.google.com/recaptcha/api/js/recaptcha.js")
- html = self.plugin.req.load("http://www.google.com/recaptcha/api/reload",
- get={'c' : challenge,
- 'k' : key,
- 'reason': "i",
- 'type' : "image"})
-
- try:
- challenge = re.search('\(\'(.+?)\',',html).group(1)
-
- except AttributeError:
- self.fail(_("ReCaptcha second challenge pattern not found"))
-
- self.logDebug("Second challenge: %s" % challenge)
- result = self.plugin.decryptCaptcha("%simage" % server,
- get={'c': challenge},
- cookies=True,
- forceUser=True,
- imgtype="jpg")
-
- self.logDebug("Result: %s" % result)
-
- return result, challenge
-
-
- 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 = random.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 = urlparse.urljoin("http://", urlparse.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(random.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 SolveMedia(CaptchaService):
- __name__ = "SolveMedia"
- __type__ = "captcha"
- __version__ = "0.13"
-
- __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):
- html = html or self.retrieve_html()
-
- 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.logWarning("Key pattern not found")
- return None
-
-
- def challenge(self, key=None, html=None):
- key = key or self.retrieve_key(html)
-
- html = self.plugin.req.load("http://api.solvemedia.com/papi/challenge.noscript",
- get={'k': key})
-
- for i in xrange(1, 11):
- try:
- magic = re.search(r'name="magic" value="(.+?)"', html).group(1)
-
- except AttributeError:
- self.logWarning("Magic pattern not found")
- magic = None
-
- try:
- challenge = re.search(r'<input type=hidden name="adcopy_challenge" id="adcopy_challenge" value="(.+?)">',
- html).group(1)
-
- except AttributeError:
- self.fail(_("SolveMedia challenge pattern not found"))
-
- else:
- self.logDebug("Challenge: %s" % challenge)
-
- try:
- result = self.result("http://api.solvemedia.com/papi/media", challenge)
-
- except Fail, e:
- self.logWarning(e)
- self.plugin.invalidCaptcha()
- result = None
-
- 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' : self.plugin.pyfile.url})
- try:
- redirect = re.search(r'URL=(.+?)">', html).group(1)
-
- except AttributeError:
- self.fail(_("SolveMedia verify pattern not found"))
-
- else:
- if "error" in html:
- self.logWarning("Captcha code was invalid")
- self.logDebug("Retry #%d" % i)
- html = self.plugin.req.load(redirect)
- else:
- break
-
- else:
- self.fail(_("SolveMedia max retries exceeded"))
-
- return result, challenge
-
-
- def result(self, server, challenge):
- result = self.plugin.decryptCaptcha(server,
- get={'c': challenge},
- cookies=True,
- imgtype="gif")
-
- self.logDebug("Result: %s" % result)
-
- return result
diff --git a/module/plugins/internal/DeadCrypter.py b/module/plugins/internal/DeadCrypter.py
index c93447164..a12399501 100644
--- a/module/plugins/internal/DeadCrypter.py
+++ b/module/plugins/internal/DeadCrypter.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
from module.plugins.internal.SimpleCrypter import create_getInfo
-from module.plugins.Crypter import Crypter as _Crypter
+from module.plugins.Crypter import Crypter
-class DeadCrypter(_Crypter):
+class DeadCrypter(Crypter):
__name__ = "DeadCrypter"
__type__ = "crypter"
__version__ = "0.05"
@@ -17,8 +17,8 @@ class DeadCrypter(_Crypter):
@classmethod
- def apiInfo(cls, url):
- api = super(DeadCrypter, cls).apiInfo(url)
+ def apiInfo(cls, *args, **kwargs):
+ api = super(DeadCrypter, cls).apiInfo(*args, **kwargs)
api['status'] = 1
return api
diff --git a/module/plugins/internal/DeadHoster.py b/module/plugins/internal/DeadHoster.py
index f159ae5fa..22825e87b 100644
--- a/module/plugins/internal/DeadHoster.py
+++ b/module/plugins/internal/DeadHoster.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
from module.plugins.internal.SimpleHoster import create_getInfo
-from module.plugins.Hoster import Hoster as _Hoster
+from module.plugins.Hoster import Hoster
-class DeadHoster(_Hoster):
+class DeadHoster(Hoster):
__name__ = "DeadHoster"
__type__ = "hoster"
__version__ = "0.15"
@@ -17,8 +17,8 @@ class DeadHoster(_Hoster):
@classmethod
- def apiInfo(cls, url):
- api = super(DeadHoster, cls).apiInfo(url)
+ def apiInfo(cls, *args, **kwargs):
+ api = super(DeadHoster, cls).apiInfo(*args, **kwargs)
api['status'] = 1
return api
diff --git a/module/plugins/internal/Extractor.py b/module/plugins/internal/Extractor.py
index 159b65ffe..1a98060d9 100644
--- a/module/plugins/internal/Extractor.py
+++ b/module/plugins/internal/Extractor.py
@@ -29,8 +29,8 @@ class Extractor:
EXTENSIONS = []
- VERSION = ""
REPAIR = False
+ VERSION = ""
@classmethod
diff --git a/module/plugins/internal/ReCaptcha.py b/module/plugins/internal/ReCaptcha.py
new file mode 100644
index 000000000..a9d0f3752
--- /dev/null
+++ b/module/plugins/internal/ReCaptcha.py
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+
+import random
+import re
+import time
+import urlparse
+
+from base64 import b64encode
+
+from module.plugins.internal.Captcha import Captcha
+
+
+class ReCaptcha(Captcha):
+ __name__ = "ReCaptcha"
+ __type__ = "captcha"
+ __version__ = "0.17"
+
+ __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_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, html=None):
+ html = html or self.retrieve_html()
+
+ 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.logWarning("Key pattern not found")
+ return None
+
+
+ def challenge(self, key=None, html=None, version=None):
+ key = key or self.retrieve_key(html)
+
+ if version in (1, 2):
+ return getattr(self, "_challenge_v%s" % version)(key)
+
+ else:
+ return self.challenge(key,
+ version=2 if re.search(self.KEY_V2_PATTERN, html or self.retrieve_html()) else 1)
+
+
+ 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:
+ self.fail(_("ReCaptcha challenge pattern not found"))
+
+ self.logDebug("Challenge: %s" % challenge)
+
+ return self.result(server, challenge, key)
+
+
+ def result(self, server, challenge, key):
+ self.plugin.req.load("http://www.google.com/recaptcha/api/js/recaptcha.js")
+ html = self.plugin.req.load("http://www.google.com/recaptcha/api/reload",
+ get={'c' : challenge,
+ 'k' : key,
+ 'reason': "i",
+ 'type' : "image"})
+
+ try:
+ challenge = re.search('\(\'(.+?)\',',html).group(1)
+
+ except AttributeError:
+ self.fail(_("ReCaptcha second challenge pattern not found"))
+
+ self.logDebug("Second challenge: %s" % challenge)
+ result = self.plugin.decryptCaptcha("%simage" % server,
+ get={'c': challenge},
+ cookies=True,
+ forceUser=True,
+ imgtype="jpg")
+
+ self.logDebug("Result: %s" % result)
+
+ return result, challenge
+
+
+ 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 = random.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 = urlparse.urljoin("http://", urlparse.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(random.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
diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py
index b843a28f0..81f977e57 100644
--- a/module/plugins/internal/SimpleCrypter.py
+++ b/module/plugins/internal/SimpleCrypter.py
@@ -11,7 +11,7 @@ from module.utils import fixup, html_unescape
class SimpleCrypter(Crypter, SimpleHoster):
__name__ = "SimpleCrypter"
__type__ = "crypter"
- __version__ = "0.46"
+ __version__ = "0.49"
__pattern__ = r'^unmatchable$'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides core.config['general']['folder_per_package']
@@ -55,15 +55,6 @@ class SimpleCrypter(Crypter, SimpleHoster):
LINK_PATTERN = None
- NAME_REPLACEMENTS = [("&#?\w+;", fixup)]
- URL_REPLACEMENTS = []
-
- TEXT_ENCODING = False #: Set to True or encoding name if encoding in http header is not correct
- COOKIES = True #: or False or list of tuples [(domain, name, value)]
-
- LOGIN_ACCOUNT = False
- LOGIN_PREMIUM = False
-
#@TODO: Remove in 0.4.10
def init(self):
@@ -83,6 +74,7 @@ class SimpleCrypter(Crypter, SimpleHoster):
self.info = {}
self.html = ""
+ self.link = "" #@TODO: Move to hoster class in 0.4.10
self.links = [] #@TODO: Move to hoster class in 0.4.10
if self.LOGIN_PREMIUM and not self.premium:
@@ -99,18 +91,34 @@ class SimpleCrypter(Crypter, SimpleHoster):
self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS)
+ def handleDirect(self, pyfile):
+ while True:
+ header = self.load(self.link or pyfile.url, just_header=True, decode=True)
+ if 'location' in header and header['location']:
+ self.link = header['location']
+ else:
+ break
+
+
def decrypt(self, pyfile):
self.prepare()
- self.preload()
- self.checkInfo()
+ self.logDebug("Looking for link redirect...")
+ self.handleDirect(pyfile)
+
+ if self.link:
+ self.urls = [self.link]
+
+ else:
+ self.preload()
+ self.checkInfo()
- self.links = self.getLinks()
+ self.links = self.getLinks()
- if hasattr(self, 'PAGES_PATTERN') and hasattr(self, 'loadPage'):
- self.handlePages(pyfile)
+ if hasattr(self, 'PAGES_PATTERN') and hasattr(self, 'loadPage'):
+ self.handlePages(pyfile)
- self.logDebug("Package has %d links" % len(self.links))
+ self.logDebug("Package has %d links" % len(self.links))
if self.links:
self.packages = [(self.info['name'], self.links, self.info['folder'])]
@@ -155,7 +163,7 @@ class SimpleCrypter(Crypter, SimpleHoster):
links = [urlparse.urljoin(baseurl, link) if not urlparse.urlparse(link).scheme else link \
for link in re.findall(self.LINK_PATTERN, self.html)]
- return [html_unescape(l.strip().decode('unicode-escape')) for l in links]
+ return [html_unescape(l.decode('unicode-escape').strip()) for l in links]
def handlePages(self, pyfile):
diff --git a/module/plugins/internal/SimpleDereferer.py b/module/plugins/internal/SimpleDereferer.py
deleted file mode 100644
index 1f04ab1c6..000000000
--- a/module/plugins/internal/SimpleDereferer.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import re
-import urllib
-
-from module.plugins.Crypter import Crypter
-from module.plugins.internal.SimpleHoster import create_getInfo, set_cookies
-from module.utils import html_unescape
-
-
-class SimpleDereferer(Crypter):
- __name__ = "SimpleDereferer"
- __type__ = "crypter"
- __version__ = "0.13"
-
- __pattern__ = r'^unmatchable$'
- __config__ = [] #@TODO: Remove in 0.4.10
-
- __description__ = """Simple dereferer plugin"""
- __license__ = "GPLv3"
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
-
-
- """
- Following patterns should be defined by each crypter:
-
- LINK_PATTERN: Regex to catch the redirect url in group(1)
- example: LINK_PATTERN = r'<div class="link"><a href="(.+?)"'
-
- OFFLINE_PATTERN: (optional) Checks if the page is unreachable
- example: OFFLINE_PATTERN = r'File (deleted|not found)'
-
- TEMP_OFFLINE_PATTERN: (optional) Checks if the page is temporarily unreachable
- example: TEMP_OFFLINE_PATTERN = r'Server maintainance'
-
-
- You can override the getLinks method if you need a more sophisticated way to extract the redirect url.
- """
-
- LINK_PATTERN = None
-
- TEXT_ENCODING = False
- COOKIES = True
-
-
- def handleDirect(self, pyfile):
- header = self.load(pyfile.url, just_header=True, decode=True)
- if 'location' in header and header['location']:
- self.link = header['location']
-
-
- def decrypt(self, pyfile):
- self.handleDirect(pyfile)
-
- if not self.link:
- try:
- self.link = urllib.unquote(re.match(self.__pattern__, pyfile.url).group('LINK'))
-
- except AttributeError:
- self.prepare()
- self.preload()
- self.checkStatus()
-
- self.link = self.getLink()
-
- if self.link:
- self.urls = [self.link]
-
- elif not self.urls and not self.packages: #@TODO: Remove in 0.4.10
- self.fail(_("No link grabbed"))
-
-
- def prepare(self):
- self.info = {}
- self.html = ""
- self.link = "" #@TODO: Move to hoster class in 0.4.10
-
- self.req.setOption("timeout", 120)
-
- if isinstance(self.COOKIES, list):
- set_cookies(self.req.cj, self.COOKIES)
-
-
- def preload(self):
- self.html = self.load(self.pyfile.url, cookies=bool(self.COOKIES), decode=not self.TEXT_ENCODING)
-
- if isinstance(self.TEXT_ENCODING, basestring):
- self.html = unicode(self.html, self.TEXT_ENCODING)
-
-
- def checkStatus(self):
- if hasattr(self, "OFFLINE_PATTERN") and re.search(self.OFFLINE_PATTERN, self.html):
- self.offline()
-
- elif hasattr(self, "TEMP_OFFLINE_PATTERN") and re.search(self.TEMP_OFFLINE_PATTERN, self.html):
- self.tempOffline()
-
-
- def getLink(self):
- link = re.search(self.LINK_PATTERN, self.html).group(1)
- return html_unescape(link.strip().decode('unicode-escape')) #@TODO: Move this check to plugin `load` method in 0.4.10
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index 1d44a6642..33e7d3674 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -239,7 +239,7 @@ def secondsToMidnight(gmt=0):
class SimpleHoster(Hoster):
__name__ = "SimpleHoster"
__type__ = "hoster"
- __version__ = "1.50"
+ __version__ = "1.53"
__pattern__ = r'^unmatchable$'
__config__ = [("use_premium", "bool", "Use premium account if available" , True),
@@ -308,13 +308,15 @@ class SimpleHoster(Hoster):
SIZE_REPLACEMENTS = []
URL_REPLACEMENTS = []
- TEXT_ENCODING = False #: Set to True or encoding name if encoding value in http header is not correct
- COOKIES = True #: or False or list of tuples [(domain, name, value)]
CHECK_TRAFFIC = False #: Set to True to force checking traffic left for premium account
+ COOKIES = True #: or False or list of tuples [(domain, name, value)]
DIRECT_LINK = None #: Set to True to looking for direct link (as defined in handleDirect method), set to None to do it if self.account is True else False
- MULTI_HOSTER = False #: Set to True to leech other hoster link (as defined in handleMulti method)
- LOGIN_ACCOUNT = False #: Set to True to require account login
DISPOSITION = True #: Set to True to use any content-disposition value in http header as file name
+ LOGIN_ACCOUNT = False #: Set to True to require account login
+ LOGIN_PREMIUM = False #: Set to True to require premium account login
+ MULTI_HOSTER = False #: Set to True to leech other hoster link (as defined in handleMulti method)
+ TEXT_ENCODING = False #: Set to True or encoding name if encoding value in http header is not correct
+
directLink = getFileURL #@TODO: Remove in 0.4.10
@@ -430,6 +432,9 @@ class SimpleHoster(Hoster):
if not self.getConfig('use_premium', True):
self.retryFree()
+ if self.LOGIN_PREMIUM and not self.premium:
+ self.fail(_("Required premium account not found"))
+
if self.LOGIN_ACCOUNT and not self.account:
self.fail(_("Required account not found"))
@@ -474,7 +479,7 @@ class SimpleHoster(Hoster):
if not self.link and not self.lastDownload:
self.MULTI_HOSTER = False
- self.retry(1, reason="Multi hoster fails")
+ self.retry(1, reason=_("Multi hoster fails"))
if not self.link and not self.lastDownload:
self.preload()
@@ -511,7 +516,7 @@ class SimpleHoster(Hoster):
self.correctCaptcha()
- link = html_unescape(link.strip().decode('unicode-escape')) #@TODO: Move this check to plugin `load` method in 0.4.10
+ link = html_unescape(link.decode('unicode-escape').strip()) #@TODO: Move this check to plugin `load` method in 0.4.10
if not urlparse.urlparse(link).scheme:
url_p = urlparse.urlparse(self.pyfile.url)
@@ -625,6 +630,7 @@ class SimpleHoster(Hoster):
elif re.search('captcha|code', errmsg, re.I):
self.invalidCaptcha()
+ self.retry(10, reason=_("Wrong captcha"))
elif re.search('countdown|expired', errmsg, re.I):
self.retry(wait_time=60, reason=_("Link expired"))
@@ -635,9 +641,14 @@ class SimpleHoster(Hoster):
elif re.search('up to', errmsg, re.I):
self.fail(_("File too large for free download"))
- elif re.search('offline|delet|remov|not (found|available)', errmsg, re.I):
+ elif re.search('offline|delet|remov|not? (found|(longer)? available)', errmsg, re.I):
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.strip('/').split('/')[0])
+ self.retry(1, reason=_("Wrong url"))
+
elif re.search('premium', errmsg, re.I):
self.fail(_("File can be downloaded by premium users only"))
diff --git a/module/plugins/internal/SolveMedia.py b/module/plugins/internal/SolveMedia.py
new file mode 100644
index 000000000..7f5de51e1
--- /dev/null
+++ b/module/plugins/internal/SolveMedia.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.Plugin import Fail
+from module.plugins.internal.Captcha import Captcha
+
+
+class SolveMedia(Captcha):
+ __name__ = "SolveMedia"
+ __type__ = "captcha"
+ __version__ = "0.13"
+
+ __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):
+ html = html or self.retrieve_html()
+
+ 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.logWarning("Key pattern not found")
+ return None
+
+
+ def challenge(self, key=None, html=None):
+ key = key or self.retrieve_key(html)
+
+ html = self.plugin.req.load("http://api.solvemedia.com/papi/challenge.noscript",
+ get={'k': key})
+
+ for i in xrange(1, 11):
+ try:
+ magic = re.search(r'name="magic" value="(.+?)"', html).group(1)
+
+ except AttributeError:
+ self.logWarning("Magic pattern not found")
+ magic = None
+
+ try:
+ challenge = re.search(r'<input type=hidden name="adcopy_challenge" id="adcopy_challenge" value="(.+?)">',
+ html).group(1)
+
+ except AttributeError:
+ self.fail(_("SolveMedia challenge pattern not found"))
+
+ else:
+ self.logDebug("Challenge: %s" % challenge)
+
+ try:
+ result = self.result("http://api.solvemedia.com/papi/media", challenge)
+
+ except Fail, e:
+ self.logWarning(e)
+ self.plugin.invalidCaptcha()
+ result = None
+
+ 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' : self.plugin.pyfile.url})
+ try:
+ redirect = re.search(r'URL=(.+?)">', html).group(1)
+
+ except AttributeError:
+ self.fail(_("SolveMedia verify pattern not found"))
+
+ else:
+ if "error" in html:
+ self.logWarning("Captcha code was invalid")
+ self.logDebug("Retry #%d" % i)
+ html = self.plugin.req.load(redirect)
+ else:
+ break
+
+ else:
+ self.fail(_("SolveMedia max retries exceeded"))
+
+ return result, challenge
+
+
+ def result(self, server, challenge):
+ result = self.plugin.decryptCaptcha(server,
+ get={'c': challenge},
+ cookies=True,
+ imgtype="gif")
+
+ self.logDebug("Result: %s" % result)
+
+ return result
diff --git a/module/plugins/internal/UnZip.py b/module/plugins/internal/UnZip.py
index 8d3fec370..4c18a0e35 100644
--- a/module/plugins/internal/UnZip.py
+++ b/module/plugins/internal/UnZip.py
@@ -19,8 +19,8 @@ class UnZip(Extractor):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- EXTENSIONS = [".zip", ".zip64"]
VERSION ="(python %s.%s.%s)" % (sys.version_info[0], sys.version_info[1], sys.version_info[2])
+ EXTENSIONS = [".zip", ".zip64"]
@classmethod
diff --git a/module/plugins/internal/XFSCrypter.py b/module/plugins/internal/XFSCrypter.py
index 80eff53ea..8b333b45c 100644
--- a/module/plugins/internal/XFSCrypter.py
+++ b/module/plugins/internal/XFSCrypter.py
@@ -19,8 +19,8 @@ class XFSCrypter(SimpleCrypter):
URL_REPLACEMENTS = [(r'&?per_page=\d+', ""), (r'[?/&]+$', ""), (r'(.+/[^?]+)$', r'\1?'), (r'$', r'&per_page=10000')]
- LINK_PATTERN = r'<(?:td|TD).*?>\s*(?:<.+>\s*)?<a href="(.+?)".*?>.+?(?:</a>)?\s*(?:<.+>\s*)?</(?:td|TD)>'
NAME_PATTERN = r'<[Tt]itle>.*?\: (?P<N>.+) folder</[Tt]itle>'
+ LINK_PATTERN = r'<(?:td|TD).*?>\s*(?:<.+>\s*)?<a href="(.+?)".*?>.+?(?:</a>)?\s*(?:<.+>\s*)?</(?:td|TD)>'
OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed)'
TEMP_OFFLINE_PATTERN = r'>\s*\w+ server (is in )?(maintenance|maintainance)'
diff --git a/module/plugins/internal/XFSHoster.py b/module/plugins/internal/XFSHoster.py
index e2818886c..e0fd8fa8d 100644
--- a/module/plugins/internal/XFSHoster.py
+++ b/module/plugins/internal/XFSHoster.py
@@ -5,7 +5,8 @@ import random
import re
import urlparse
-from module.plugins.internal.CaptchaService import ReCaptcha, SolveMedia
+from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.internal.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, secondsToMidnight
from module.utils import html_unescape
@@ -13,7 +14,7 @@ from module.utils import html_unescape
class XFSHoster(SimpleHoster):
__name__ = "XFSHoster"
__type__ = "hoster"
- __version__ = "0.51"
+ __version__ = "0.53"
__pattern__ = r'^unmatchable$'
@@ -26,14 +27,12 @@ class XFSHoster(SimpleHoster):
HOSTER_DOMAIN = None
- TEXT_ENCODING = False
- DIRECT_LINK = None
- MULTI_HOSTER = True #@NOTE: Should be default to False for safe, but I'm lazy...
+ MULTI_HOSTER = True #@NOTE: Should be default to False for safe, but I'm lazy...
NAME_PATTERN = r'(Filename[ ]*:[ ]*</b>(</td><td nowrap>)?|name="fname"[ ]+value="|<[\w^_]+ class="(file)?name">)\s*(?P<N>.+?)(\s*<|")'
SIZE_PATTERN = r'(Size[ ]*:[ ]*</b>(</td><td>)?|File:.*>|</font>\s*\(|<[\w^_]+ class="size">)\s*(?P<S>[\d.,]+)\s*(?P<U>[\w^_]+)'
- OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed)'
+ OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed|no longer available)'
TEMP_OFFLINE_PATTERN = r'>\s*\w+ server (is in )?(maintenance|maintainance)'
WAIT_PATTERN = r'<span id="countdown_str".*>(\d+)</span>|id="countdown" value=".*?(\d+).*?"'