summaryrefslogtreecommitdiffstats
path: root/module/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins')
-rw-r--r--module/plugins/accounts/AlldebridCom.py2
-rw-r--r--module/plugins/accounts/CatShareNet.py35
-rw-r--r--module/plugins/accounts/ExashareCom.py16
-rw-r--r--module/plugins/accounts/File4SafeCom.py (renamed from module/plugins/accounts/File4safeCom.py)0
-rw-r--r--module/plugins/accounts/JunkyvideoCom.py16
-rw-r--r--module/plugins/accounts/Keep2ShareCc.py (renamed from module/plugins/accounts/Keep2shareCc.py)29
-rw-r--r--[-rwxr-xr-x]module/plugins/accounts/NetloadIn.py0
-rw-r--r--module/plugins/accounts/NoPremiumPl.py4
-rw-r--r--module/plugins/accounts/RapideoPl.py4
-rw-r--r--module/plugins/accounts/RapidgatorNet.py23
-rw-r--r--module/plugins/accounts/RehostTo.py8
-rw-r--r--module/plugins/accounts/ShareonlineBiz.py9
-rw-r--r--module/plugins/accounts/ZeveraCom.py4
-rw-r--r--module/plugins/captcha/LinksaveIn.py2
-rw-r--r--module/plugins/captcha/captcha.py6
-rw-r--r--module/plugins/container/CCF.py4
-rw-r--r--module/plugins/container/DLC.py71
-rw-r--r--module/plugins/container/DLC_25.pycbin8340 -> 0 bytes
-rw-r--r--module/plugins/container/DLC_26.pycbin8313 -> 0 bytes
-rw-r--r--module/plugins/container/DLC_27.pycbin8237 -> 0 bytes
-rw-r--r--module/plugins/container/LinkList.py8
-rw-r--r--module/plugins/container/RSDF.py6
-rw-r--r--module/plugins/crypter/C1NeonCom.py (renamed from module/plugins/crypter/C1neonCom.py)0
-rw-r--r--module/plugins/crypter/ChipDe.py2
-rw-r--r--module/plugins/crypter/CloudzillaToFolder.py6
-rw-r--r--module/plugins/crypter/DevhostStFolder.py6
-rw-r--r--module/plugins/crypter/EasybytezComFolder.py2
-rw-r--r--module/plugins/crypter/FilecryptCc.py17
-rw-r--r--module/plugins/crypter/Go4UpCom.py2
-rw-r--r--module/plugins/crypter/JunocloudMeFolder.py23
-rw-r--r--module/plugins/crypter/LinkCryptWs.py2
-rw-r--r--module/plugins/crypter/MegaCoNzFolder.py2
-rw-r--r--module/plugins/crypter/Movie2KTo.py (renamed from module/plugins/crypter/Movie2kTo.py)0
-rw-r--r--module/plugins/crypter/NCryptIn.py8
-rw-r--r--[-rwxr-xr-x]module/plugins/crypter/OronComFolder.py0
-rw-r--r--module/plugins/crypter/RapidfileshareNetFolder.py23
-rw-r--r--module/plugins/crypter/RelinkUs.py10
-rw-r--r--module/plugins/crypter/SafelinkingNet.py4
-rw-r--r--module/plugins/crypter/ShareLinksBiz.py2
-rw-r--r--module/plugins/crypter/TusfilesNetFolder.py2
-rw-r--r--module/plugins/hooks/AndroidPhoneNotify.py4
-rw-r--r--[-rwxr-xr-x]module/plugins/hooks/Captcha9Kw.py (renamed from module/plugins/hooks/Captcha9kw.py)0
-rw-r--r--module/plugins/hooks/ClickAndLoad.py56
-rw-r--r--module/plugins/hooks/DeathByCaptcha.py2
-rw-r--r--module/plugins/hooks/ExternalScripts.py8
-rw-r--r--module/plugins/hooks/ExtractArchive.py268
-rw-r--r--module/plugins/hooks/IRCInterface.py8
-rw-r--r--module/plugins/hooks/ImageTyperz.py4
-rw-r--r--module/plugins/hooks/LinkdecrypterCom.py9
-rw-r--r--module/plugins/hooks/SkipRev.py4
-rw-r--r--module/plugins/hooks/UpdateManager.py8
-rw-r--r--module/plugins/hooks/WindowsPhoneToastNotify.py4
-rw-r--r--module/plugins/hooks/XFileSharingPro.py8
-rw-r--r--module/plugins/hooks/XMPPInterface.py6
-rw-r--r--module/plugins/hoster/BasePlugin.py43
-rw-r--r--module/plugins/hoster/BillionuploadsCom.py2
-rw-r--r--module/plugins/hoster/BitshareCom.py4
-rw-r--r--module/plugins/hoster/CatShareNet.py14
-rw-r--r--module/plugins/hoster/CloudzillaTo.py2
-rw-r--r--module/plugins/hoster/CramitIn.py2
-rw-r--r--module/plugins/hoster/CrockoCom.py4
-rw-r--r--module/plugins/hoster/DateiTo.py4
-rw-r--r--module/plugins/hoster/DepositfilesCom.py6
-rw-r--r--module/plugins/hoster/DlFreeFr.py5
-rw-r--r--module/plugins/hoster/EasybytezCom.py2
-rw-r--r--module/plugins/hoster/ExashareCom.py38
-rw-r--r--module/plugins/hoster/ExtabitCom.py4
-rw-r--r--module/plugins/hoster/FilecloudIo.py6
-rw-r--r--module/plugins/hoster/FilefactoryCom.py2
-rw-r--r--module/plugins/hoster/FileomCom.py2
-rw-r--r--module/plugins/hoster/FilepostCom.py4
-rw-r--r--module/plugins/hoster/FilerNet.py42
-rw-r--r--module/plugins/hoster/FilerioCom.py2
-rw-r--r--module/plugins/hoster/FilesMailRu.py2
-rw-r--r--module/plugins/hoster/FileserveCom.py4
-rw-r--r--module/plugins/hoster/FourSharedCom.py2
-rw-r--r--module/plugins/hoster/FshareVn.py14
-rw-r--r--module/plugins/hoster/Ftp.py2
-rw-r--r--module/plugins/hoster/HellshareCz.py8
-rw-r--r--module/plugins/hoster/HugefilesNet.py2
-rw-r--r--module/plugins/hoster/HundredEightyUploadCom.py2
-rw-r--r--module/plugins/hoster/JunocloudMe.py2
-rw-r--r--module/plugins/hoster/Keep2ShareCc.py (renamed from module/plugins/hoster/Keep2shareCc.py)64
-rw-r--r--module/plugins/hoster/KingfilesNet.py4
-rw-r--r--module/plugins/hoster/LetitbitNet.py4
-rw-r--r--module/plugins/hoster/LoadTo.py6
-rw-r--r--module/plugins/hoster/LuckyShareNet.py6
-rw-r--r--module/plugins/hoster/MediafireCom.py6
-rw-r--r--module/plugins/hoster/MegaCoNz.py4
-rw-r--r--module/plugins/hoster/MovReelCom.py2
-rw-r--r--module/plugins/hoster/MultihostersCom.py4
-rw-r--r--module/plugins/hoster/NetloadIn.py17
-rw-r--r--module/plugins/hoster/NitroflareCom.py120
-rw-r--r--module/plugins/hoster/NoPremiumPl.py6
-rw-r--r--module/plugins/hoster/NosuploadCom.py2
-rw-r--r--module/plugins/hoster/NovafileCom.py2
-rw-r--r--module/plugins/hoster/OboomCom.py4
-rw-r--r--module/plugins/hoster/OneFichierCom.py4
-rw-r--r--module/plugins/hoster/PutdriveCom.py4
-rw-r--r--module/plugins/hoster/RapideoPl.py6
-rw-r--r--module/plugins/hoster/RapidfileshareNet.py2
-rw-r--r--module/plugins/hoster/RapidgatorNet.py14
-rw-r--r--module/plugins/hoster/RapiduNet.py4
-rw-r--r--module/plugins/hoster/RarefileNet.py2
-rw-r--r--module/plugins/hoster/RemixshareCom.py2
-rw-r--r--module/plugins/hoster/SafesharingEu.py2
-rw-r--r--module/plugins/hoster/SecureUploadEu.py2
-rw-r--r--module/plugins/hoster/Share4WebCom.py (renamed from module/plugins/hoster/Share4webCom.py)0
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py6
-rw-r--r--module/plugins/hoster/SpeedyshareCom.py7
-rw-r--r--module/plugins/hoster/StreamcloudEu.py2
-rw-r--r--module/plugins/hoster/TurbobitNet.py38
-rw-r--r--module/plugins/hoster/TusfilesNet.py2
-rw-r--r--module/plugins/hoster/UlozTo.py13
-rw-r--r--module/plugins/hoster/UnibytesCom.py2
-rw-r--r--module/plugins/hoster/UpleaCom.py6
-rw-r--r--module/plugins/hoster/UploadableCh.py4
-rw-r--r--module/plugins/hoster/UploadedTo.py263
-rw-r--r--module/plugins/hoster/UpstoreNet.py4
-rw-r--r--module/plugins/hoster/UptoboxCom.py2
-rw-r--r--module/plugins/hoster/VidPlayNet.py2
-rw-r--r--module/plugins/hoster/Vipleech4UCom.py (renamed from module/plugins/hoster/Vipleech4uCom.py)0
-rw-r--r--module/plugins/hoster/WebshareCz.py4
-rw-r--r--module/plugins/hoster/YibaishiwuCom.py2
-rw-r--r--module/plugins/hoster/YoutubeCom.py57
-rw-r--r--module/plugins/hoster/ZeveraCom.py4
-rw-r--r--module/plugins/hoster/ZippyshareCom.py37
-rw-r--r--module/plugins/internal/CaptchaService.py233
-rw-r--r--module/plugins/internal/DeadCrypter.py3
-rw-r--r--module/plugins/internal/DeadHoster.py3
-rw-r--r--module/plugins/internal/Extractor.py99
-rw-r--r--module/plugins/internal/MultiHook.py4
-rw-r--r--module/plugins/internal/MultiHoster.py24
-rw-r--r--module/plugins/internal/SevenZip.py163
-rw-r--r--module/plugins/internal/SimpleCrypter.py21
-rw-r--r--module/plugins/internal/SimpleDereferer.py15
-rw-r--r--module/plugins/internal/SimpleHoster.py139
-rw-r--r--module/plugins/internal/UnRar.py175
-rw-r--r--module/plugins/internal/UnZip.py64
-rw-r--r--module/plugins/internal/XFSAccount.py31
-rw-r--r--module/plugins/internal/XFSCrypter.py23
-rw-r--r--module/plugins/internal/XFSHoster.py43
142 files changed, 1484 insertions, 1277 deletions
diff --git a/module/plugins/accounts/AlldebridCom.py b/module/plugins/accounts/AlldebridCom.py
index 1f2371e28..c830f0c09 100644
--- a/module/plugins/accounts/AlldebridCom.py
+++ b/module/plugins/accounts/AlldebridCom.py
@@ -37,7 +37,7 @@ class AlldebridCom(Account):
exp_data[1]) * 60 * 60 + (int(exp_data[2]) - 1) * 60
#Get expiration date from API
- except:
+ except Exception:
data = self.getAccountData(user)
html = req.load("http://www.alldebrid.com/api.php",
get={'action': "info_user", 'login': user, 'pw': data['password']})
diff --git a/module/plugins/accounts/CatShareNet.py b/module/plugins/accounts/CatShareNet.py
index bcb14bee3..ec4d706ae 100644
--- a/module/plugins/accounts/CatShareNet.py
+++ b/module/plugins/accounts/CatShareNet.py
@@ -10,39 +10,44 @@ from module.plugins.Account import Account
class CatShareNet(Account):
__name__ = "CatShareNet"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.05"
__description__ = """CatShareNet account plugin"""
__license__ = "GPLv3"
__authors__ = [("prOq", None)]
- PREMIUM_PATTERN = r'class="nav-collapse collapse pull-right">[\s\w<>=-."/:]*\sz.</a></li>\s*<li><a href="/premium">.*\s*<span style="color: red">(.*?)</span>[\s\w<>/]*href="/logout"'
- VALID_UNTIL_PATTERN = r'<div class="span6 pull-right">[\s\w<>=-":;]*<span style="font-size:13px;">.*?<strong>(.*?)</strong></span>'
+ PREMIUM_PATTERN = r'<a href="/premium">Konto:[\s\n]*Premium'
+ VALID_UNTIL_PATTERN = r'>Konto premium.*?<strong>(.*?)</strong></span>'
+ TRAFFIC_LEFT_PATTERN = r'<a href="/premium">([0-9.]+ [kMG]B)'
def loadAccountInfo(self, user, req):
- premium = False
- validuntil = -1
+ premium = False
+ validuntil = -1
+ trafficleft = -1
html = req.load("http://catshare.net/", decode=True)
+ if re.search(self.PREMIUM_PATTERN, html):
+ premium = True
+
try:
- m = re.search(self.PREMIUM_PATTERN, html)
- if "Premium" in m.group(1):
- premium = True
- except:
+ expiredate = re.search(self.VALID_UNTIL_PATTERN, html).group(1)
+ self.logDebug("Expire date: " + expiredate)
+
+ validuntil = mktime(strptime(expiredate, "%Y-%m-%d %H:%M:%S"))
+
+ except Exception:
pass
try:
- m = re.search(self.VALID_UNTIL_PATTERN, html)
- expiredate = m.group(1)
- if "-" not in expiredate:
- validuntil = mktime(strptime(expiredate, "%d.%m.%Y"))
- except:
+ trafficleft = self.parseTraffic(re.search(self.TRAFFIC_LEFT_PATTERN, html).group(1))
+
+ except Exception:
pass
- return {'premium': premium, 'trafficleft': -1, 'validuntil': validuntil}
+ return {'premium': premium, 'trafficleft': trafficleft, 'validuntil': validuntil}
def login(self, user, data, req):
diff --git a/module/plugins/accounts/ExashareCom.py b/module/plugins/accounts/ExashareCom.py
new file mode 100644
index 000000000..431798522
--- /dev/null
+++ b/module/plugins/accounts/ExashareCom.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.XFSAccount import XFSAccount
+
+
+class ExashareCom(XFSAccount):
+ __name__ = "ExashareCom"
+ __type__ = "account"
+ __version__ = "0.01"
+
+ __description__ = """Exashare.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = "exashare.com"
diff --git a/module/plugins/accounts/File4safeCom.py b/module/plugins/accounts/File4SafeCom.py
index 50fe1aac8..50fe1aac8 100644
--- a/module/plugins/accounts/File4safeCom.py
+++ b/module/plugins/accounts/File4SafeCom.py
diff --git a/module/plugins/accounts/JunkyvideoCom.py b/module/plugins/accounts/JunkyvideoCom.py
new file mode 100644
index 000000000..8275ff176
--- /dev/null
+++ b/module/plugins/accounts/JunkyvideoCom.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.XFSAccount import XFSAccount
+
+
+class JunkyvideoCom(XFSAccount):
+ __name__ = "JunkyvideoCom"
+ __type__ = "account"
+ __version__ = "0.01"
+
+ __description__ = """Junkyvideo.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = "junkyvideo.com"
diff --git a/module/plugins/accounts/Keep2shareCc.py b/module/plugins/accounts/Keep2ShareCc.py
index e855fb977..9f28799a2 100644
--- a/module/plugins/accounts/Keep2shareCc.py
+++ b/module/plugins/accounts/Keep2ShareCc.py
@@ -10,14 +10,15 @@ from module.plugins.Account import Account
class Keep2ShareCc(Account):
__name__ = "Keep2ShareCc"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.05"
__description__ = """Keep2Share.cc account plugin"""
__license__ = "GPLv3"
- __authors__ = [("aeronaut", "aeronaut@pianoguy.de")]
+ __authors__ = [("aeronaut", "aeronaut@pianoguy.de"),
+ ("Walter Purcaro", "vuolter@gmail.com")]
- VALID_UNTIL_PATTERN = r'Premium expires: <b>(.+?)</b>'
+ VALID_UNTIL_PATTERN = r'Premium expires:\s*<b>(.+?)<'
TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):\s*<b><a href="/user/statistic.html">(.+?)<'
LOGIN_FAIL_PATTERN = r'Please fix the following input errors'
@@ -25,8 +26,8 @@ class Keep2ShareCc(Account):
def loadAccountInfo(self, user, req):
validuntil = None
- trafficleft = None
- premium = None
+ trafficleft = -1
+ premium = False
html = req.load("http://keep2share.cc/site/profile.html", decode=True)
@@ -46,19 +47,15 @@ class Keep2ShareCc(Account):
self.logError(e)
else:
- if validuntil > mktime(gmtime()):
- premium = True
- else:
- premium = False
- validuntil = None
+ premium = True if validuntil > mktime(gmtime()) else False
- m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
- if m:
- try:
- trafficleft = self.parseTraffic(m.group(1))
+ m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
+ if m:
+ try:
+ trafficleft = self.parseTraffic(m.group(1))
- except Exception, e:
- self.logError(e)
+ except Exception, e:
+ self.logError(e)
return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
diff --git a/module/plugins/accounts/NetloadIn.py b/module/plugins/accounts/NetloadIn.py
index 1abd7fa84..1abd7fa84 100755..100644
--- a/module/plugins/accounts/NetloadIn.py
+++ b/module/plugins/accounts/NetloadIn.py
diff --git a/module/plugins/accounts/NoPremiumPl.py b/module/plugins/accounts/NoPremiumPl.py
index f2223b7d9..a36b114eb 100644
--- a/module/plugins/accounts/NoPremiumPl.py
+++ b/module/plugins/accounts/NoPremiumPl.py
@@ -35,7 +35,7 @@ class NoPremiumPl(Account):
self._req = req
try:
result = loads(self.runAuthQuery())
- except:
+ except Exception:
# todo: return or let it be thrown?
return
@@ -60,7 +60,7 @@ class NoPremiumPl(Account):
try:
response = loads(self.runAuthQuery())
- except:
+ except Exception:
self.wrongPassword()
if "errno" in response.keys():
diff --git a/module/plugins/accounts/RapideoPl.py b/module/plugins/accounts/RapideoPl.py
index 438ce7ad3..426c680a6 100644
--- a/module/plugins/accounts/RapideoPl.py
+++ b/module/plugins/accounts/RapideoPl.py
@@ -35,7 +35,7 @@ class RapideoPl(Account):
self._req = req
try:
result = loads(self.runAuthQuery())
- except:
+ except Exception:
# todo: return or let it be thrown?
return
@@ -59,7 +59,7 @@ class RapideoPl(Account):
self._req = req
try:
response = loads(self.runAuthQuery())
- except:
+ except Exception:
self.wrongPassword()
if "errno" in response.keys():
diff --git a/module/plugins/accounts/RapidgatorNet.py b/module/plugins/accounts/RapidgatorNet.py
index b29d94228..a7aa6ce09 100644
--- a/module/plugins/accounts/RapidgatorNet.py
+++ b/module/plugins/accounts/RapidgatorNet.py
@@ -7,7 +7,7 @@ from module.common.json_layer import json_loads
class RapidgatorNet(Account):
__name__ = "RapidgatorNet"
__type__ = "account"
- __version__ = "0.06"
+ __version__ = "0.07"
__description__ = """Rapidgator.net account plugin"""
__license__ = "GPLv3"
@@ -18,8 +18,13 @@ class RapidgatorNet(Account):
def loadAccountInfo(self, user, req):
+ validuntil = None
+ trafficleft = None
+ premium = False
+ sid = None
+
try:
- sid = self.getAccountData(user).get('SID')
+ sid = self.getAccountData(user).get('sid')
assert sid
json = req.load("%s/info?sid=%s" % (self.API_URL, sid))
@@ -30,15 +35,19 @@ class RapidgatorNet(Account):
if "reset_in" in json['response']:
self.scheduleRefresh(user, json['response']['reset_in'])
- return {"validuntil": json['response']['expire_date'],
- "trafficleft": float(json['response']['traffic_left']) / 1024, #@TODO: Remove `/ 1024` in 0.4.10
- "premium": True}
+ validuntil = json['response']['expire_date'],
+ trafficleft = float(json['response']['traffic_left']) / 1024, #@TODO: Remove `/ 1024` in 0.4.10
+ premium = True
else:
self.logError(json['response_details'])
+
except Exception, e:
self.logError(e)
- return {"validuntil": None, "trafficleft": None, "premium": False}
+ return {'validuntil' : validuntil,
+ 'trafficleft': trafficleft
+ 'premium' : premium,
+ 'sid' : sid}
def login(self, user, data, req):
@@ -50,7 +59,7 @@ class RapidgatorNet(Account):
json = json_loads(json)
if json['response_status'] == 200:
- data['SID'] = str(json['response']['session_id'])
+ data['sid'] = str(json['response']['session_id'])
return
else:
self.logError(json['response_details'])
diff --git a/module/plugins/accounts/RehostTo.py b/module/plugins/accounts/RehostTo.py
index 897f888b0..04e71c9ad 100644
--- a/module/plugins/accounts/RehostTo.py
+++ b/module/plugins/accounts/RehostTo.py
@@ -18,13 +18,13 @@ class RehostTo(Account):
trafficleft = None
validuntil = -1
session = ""
-
+
html = req.load("http://rehost.to/api.php",
get={'cmd' : "login", 'user': user,
'pass': self.getAccountData(user)['password']})
try:
session = html.split(",")[1].split("=")[1]
-
+
html = req.load("http://rehost.to/api.php",
get={'cmd': "get_premium_credits", 'long_ses': session})
@@ -32,11 +32,11 @@ class RehostTo(Account):
self.logDebug(html)
else:
traffic, valid = html.split(",")
-
+
premium = True
trafficleft = self.parseTraffic(traffic + "MB")
validuntil = float(valid)
-
+
finally:
return {'premium' : premium,
'trafficleft': trafficleft,
diff --git a/module/plugins/accounts/ShareonlineBiz.py b/module/plugins/accounts/ShareonlineBiz.py
index 3ee6e04af..7e05e2e76 100644
--- a/module/plugins/accounts/ShareonlineBiz.py
+++ b/module/plugins/accounts/ShareonlineBiz.py
@@ -8,7 +8,7 @@ from module.plugins.Account import Account
class ShareonlineBiz(Account):
__name__ = "ShareonlineBiz"
__type__ = "account"
- __version__ = "0.30"
+ __version__ = "0.31"
__description__ = """Share-online.biz account plugin"""
__license__ = "GPLv3"
@@ -40,7 +40,7 @@ class ShareonlineBiz(Account):
if api['a'].lower() != "not_available":
req.cj.setCookie("share-online.biz", 'a', api['a'])
- premium = api['group'] == "Premium"
+ premium = api['group'] in ("Premium", "PrePaid")
validuntil = float(api['expire_date'])
@@ -51,7 +51,10 @@ class ShareonlineBiz(Account):
maxtraffic /= 1024 #@TODO: Remove `/ 1024` in 0.4.10
trafficleft /= 1024 #@TODO: Remove `/ 1024` in 0.4.10
- return {'premium': premium, 'validuntil': validuntil, 'trafficleft': trafficleft, 'maxtraffic': maxtraffic}
+ return {'premium' : premium,
+ 'validuntil' : validuntil,
+ 'trafficleft': trafficleft,
+ 'maxtraffic' : maxtraffic}
def login(self, user, data, req):
diff --git a/module/plugins/accounts/ZeveraCom.py b/module/plugins/accounts/ZeveraCom.py
index 6c69a974f..15b6d9379 100644
--- a/module/plugins/accounts/ZeveraCom.py
+++ b/module/plugins/accounts/ZeveraCom.py
@@ -8,7 +8,7 @@ from module.plugins.Account import Account
class ZeveraCom(Account):
__name__ = "ZeveraCom"
__type__ = "account"
- __version__ = "0.24"
+ __version__ = "0.25"
__description__ = """Zevera.com account plugin"""
__license__ = "GPLv3"
@@ -39,7 +39,7 @@ class ZeveraCom(Account):
api = self.api_response(req)
- if api != "No trafic":
+ if "No trafic" not in api or "Expired" not in api:
validuntil = mktime(strptime(api['endsubscriptiondate'], "%Y/%m/%d %H:%M:%S"))
trafficleft = float(api['availabletodaytraffic']) * 1024 if api['orondaytrafficlimit'] != '0' else -1
premium = True
diff --git a/module/plugins/captcha/LinksaveIn.py b/module/plugins/captcha/LinksaveIn.py
index 56cbd58a0..de6b0e7ff 100644
--- a/module/plugins/captcha/LinksaveIn.py
+++ b/module/plugins/captcha/LinksaveIn.py
@@ -79,7 +79,7 @@ class LinksaveIn(OCR):
rgb_c = lut[pix[x, y]]
try:
cstat[rgb_c] += 1
- except:
+ except Exception:
cstat[rgb_c] = 1
if rgb_bg == rgb_c:
stat[bgpath] += 1
diff --git a/module/plugins/captcha/captcha.py b/module/plugins/captcha/captcha.py
index 0f233ec00..e89ec2e81 100644
--- a/module/plugins/captcha/captcha.py
+++ b/module/plugins/captcha/captcha.py
@@ -102,7 +102,7 @@ class OCR(object):
try:
with open(tmpTxt.name, 'r') as f:
self.result_captcha = f.read().replace("\n", "")
- except:
+ except Exception:
self.result_captcha = ""
self.logger.debug(self.result_captcha)
@@ -111,7 +111,7 @@ class OCR(object):
os.remove(tmpTxt.name)
if subset and (digits or lowercase or uppercase):
os.remove(tmpSub.name)
- except:
+ except Exception:
pass
@@ -166,7 +166,7 @@ class OCR(object):
count += 1
if pixels[x, y-1] != 255:
count += 1
- except:
+ except Exception:
pass
# not enough neighbors are dark pixels so mark this pixel
diff --git a/module/plugins/container/CCF.py b/module/plugins/container/CCF.py
index bca535175..c6e642cca 100644
--- a/module/plugins/container/CCF.py
+++ b/module/plugins/container/CCF.py
@@ -16,9 +16,9 @@ from module.utils import save_join
class CCF(Container):
__name__ = "CCF"
- __version__ = "0.20"
+ __version__ = "0.21"
- __pattern__ = r'.+\.ccf'
+ __pattern__ = r'.+\.ccf$'
__description__ = """CCF container decrypter plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/container/DLC.py b/module/plugins/container/DLC.py
new file mode 100644
index 000000000..53349c5c7
--- /dev/null
+++ b/module/plugins/container/DLC.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import re
+import xml.dom.minidom
+
+from base64 import standard_b64decode
+from Crypto.Cipher import AES
+
+from module.plugins.Container import Container
+from module.utils import decode
+
+
+class DLC(Container):
+ __name__ = "DLC"
+ __version__ = "0.22"
+ __pattern__ = r'.+\.dlc$'
+
+ __description__ = """DLC container decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("RaNaN", "RaNaN@pyload.org"),
+ ("spoob", "spoob@pyload.org"),
+ ("mkaay", "mkaay@mkaay.de"),
+ ("Schnusch", "Schnusch@users.noreply.github.com"),
+ ("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def setup(self):
+ self.key = "cb99b5cbc24db398"
+ self.iv = "9bc24cb995cb8db3"
+ self.api_url = "http://service.jdownloader.org/dlcrypt/service.php?srcType=dlc&destType=pylo&data="
+
+
+ def decrypt(self, pyfile):
+ with open(pyfile.url.replace("\n", "")) as dlc:
+ data = dlc.read().strip()
+
+ data += '=' * (-len(data) % 4)
+
+ dlckey = data[-88:]
+ dlcdata = data[:-88]
+ dlcdata = standard_b64decode(dlcdata)
+
+ rc = self.load(self.api_url + dlckey)
+ rc = re.search(r'<rc>(.+)</rc>', rc).group(1)
+ rc = standard_b64decode(rc)
+
+ obj = AES.new(self.key, AES.MODE_CBC, self.iv)
+ dlckey = obj.decrypt(rc)
+ obj = AES.new(dlckey, AES.MODE_CBC, dlckey)
+
+ self.data = standard_b64decode(obj.decrypt(dlcdata))
+ self.packages = [(entry[0] if entry[0] else pyfile.name, entry[1], entry[0] if entry[0] else pyfile.name) \
+ for entry in self.getPackages()]
+
+
+ def getPackages(self):
+ root = xml.dom.minidom.parseString(self.data).documentElement
+ content = root.getElementsByTagName("content")[0]
+ return self.parsePackages(content)
+
+
+ def parsePackages(self, startNode):
+ return [(standard_b64decode(decode(node.getAttribute("name"))), self.parseLinks(node)) \
+ for node in startNode.getElementsByTagName("package")]
+
+
+ def parseLinks(self, startNode):
+ return [standard_b64decode(node.getElementsByTagName("url")[0].firstChild.data) \
+ for node in startNode.getElementsByTagName("file")]
diff --git a/module/plugins/container/DLC_25.pyc b/module/plugins/container/DLC_25.pyc
deleted file mode 100644
index b8fde0051..000000000
--- a/module/plugins/container/DLC_25.pyc
+++ /dev/null
Binary files differ
diff --git a/module/plugins/container/DLC_26.pyc b/module/plugins/container/DLC_26.pyc
deleted file mode 100644
index 41a4e0cb8..000000000
--- a/module/plugins/container/DLC_26.pyc
+++ /dev/null
Binary files differ
diff --git a/module/plugins/container/DLC_27.pyc b/module/plugins/container/DLC_27.pyc
deleted file mode 100644
index a6bffaf74..000000000
--- a/module/plugins/container/DLC_27.pyc
+++ /dev/null
Binary files differ
diff --git a/module/plugins/container/LinkList.py b/module/plugins/container/LinkList.py
index c6173ad73..9c76c4341 100644
--- a/module/plugins/container/LinkList.py
+++ b/module/plugins/container/LinkList.py
@@ -8,9 +8,9 @@ from module.utils import fs_encode
class LinkList(Container):
__name__ = "LinkList"
- __version__ = "0.12"
+ __version__ = "0.13"
- __pattern__ = r'.+\.txt'
+ __pattern__ = r'.+\.txt$'
__config__ = [("clear", "bool", "Clear Linklist after adding", False),
("encoding", "string", "File encoding (default utf-8)", "")]
@@ -23,7 +23,7 @@ class LinkList(Container):
def decrypt(self, pyfile):
try:
file_enc = codecs.lookup(self.getConfig("encoding")).name
- except:
+ except Exception:
file_enc = "utf-8"
file_name = fs_encode(pyfile.url)
@@ -64,7 +64,7 @@ class LinkList(Container):
try:
txt = open(file_name, 'wb')
txt.close()
- except:
+ except Exception:
self.logWarning(_("LinkList could not be cleared"))
for name, links in packages.iteritems():
diff --git a/module/plugins/container/RSDF.py b/module/plugins/container/RSDF.py
index 0c43f0e6c..0c36293ec 100644
--- a/module/plugins/container/RSDF.py
+++ b/module/plugins/container/RSDF.py
@@ -12,9 +12,9 @@ from module.utils import fs_encode
class RSDF(Container):
__name__ = "RSDF"
- __version__ = "0.24"
+ __version__ = "0.25"
- __pattern__ = r'.+\.rsdf'
+ __pattern__ = r'.+\.rsdf$'
__description__ = """RSDF container decrypter plugin"""
__license__ = "GPLv3"
@@ -39,7 +39,7 @@ class RSDF(Container):
with open(infile, 'r') as rsdf:
data = rsdf.read()
except IOError, e:
- self.fail(str(e))
+ self.fail(e)
if re.search(r"<title>404 - Not Found</title>", data) is None:
data = binascii.unhexlify(''.join(data.split()))
diff --git a/module/plugins/crypter/C1neonCom.py b/module/plugins/crypter/C1NeonCom.py
index 926633ff7..926633ff7 100644
--- a/module/plugins/crypter/C1neonCom.py
+++ b/module/plugins/crypter/C1NeonCom.py
diff --git a/module/plugins/crypter/ChipDe.py b/module/plugins/crypter/ChipDe.py
index 133e5a005..2fc36c355 100644
--- a/module/plugins/crypter/ChipDe.py
+++ b/module/plugins/crypter/ChipDe.py
@@ -22,7 +22,7 @@ class ChipDe(Crypter):
self.html = self.load(pyfile.url)
try:
f = re.search(r'"(http://video\.chip\.de/.+)"', self.html)
- except:
+ except Exception:
self.fail(_("Failed to find the URL"))
else:
self.urls = [f.group(1)]
diff --git a/module/plugins/crypter/CloudzillaToFolder.py b/module/plugins/crypter/CloudzillaToFolder.py
index c156d4de4..76019d928 100644
--- a/module/plugins/crypter/CloudzillaToFolder.py
+++ b/module/plugins/crypter/CloudzillaToFolder.py
@@ -10,7 +10,7 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class CloudzillaToFolder(SimpleHoster):
__name__ = "CloudzillaToFolder"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
__pattern__ = r'http://(?:www\.)?cloudzilla\.to/share/folder/(?P<ID>[\w^_]+)'
@@ -36,8 +36,4 @@ class CloudzillaToFolder(SimpleHoster):
self.retry(reason="Wrong password")
- def getLinks(self):
- return [urljoin("http://www.cloudzilla.to", link) for link in super(CloudzillaToFolder, self).getLinks()]
-
-
getInfo = create_getInfo(CloudzillaToFolder)
diff --git a/module/plugins/crypter/DevhostStFolder.py b/module/plugins/crypter/DevhostStFolder.py
index 5ac9d4faf..8779cae5e 100644
--- a/module/plugins/crypter/DevhostStFolder.py
+++ b/module/plugins/crypter/DevhostStFolder.py
@@ -13,7 +13,7 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class DevhostStFolder(SimpleCrypter):
__name__ = "DevhostStFolder"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
__pattern__ = r'http://(?:www\.)?d-h\.st/users/(?P<USER>\w+)(/\?fld_id=(?P<ID>\d+))?'
__config__ = [("use_subfolder", "bool", "Save package to subfolder", True),
@@ -54,8 +54,4 @@ class DevhostStFolder(SimpleCrypter):
return {'name': name, 'folder': folder}
- def getLinks(self):
- return [urljoin("http://d-h.st", link) for link in re.findall(self.LINK_PATTERN, self.html)]
-
-
getInfo = create_getInfo(DevhostStFolder)
diff --git a/module/plugins/crypter/EasybytezComFolder.py b/module/plugins/crypter/EasybytezComFolder.py
index 04f9b853b..6c643e83f 100644
--- a/module/plugins/crypter/EasybytezComFolder.py
+++ b/module/plugins/crypter/EasybytezComFolder.py
@@ -17,8 +17,6 @@ class EasybytezComFolder(XFSCrypter):
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- HOSTER_DOMAIN = "easybytez.com"
-
LOGIN_ACCOUNT = True
diff --git a/module/plugins/crypter/FilecryptCc.py b/module/plugins/crypter/FilecryptCc.py
index af31dc743..096fd414d 100644
--- a/module/plugins/crypter/FilecryptCc.py
+++ b/module/plugins/crypter/FilecryptCc.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-
+# http://filecrypt.cc/Container/64E039F859.html
import base64
import binascii
import re
@@ -14,7 +14,7 @@ from module.plugins.internal.CaptchaService import ReCaptcha
class FilecryptCc(Crypter):
__name__ = "FilecryptCc"
__type__ = "crypter"
- __version__ = "0.09"
+ __version__ = "0.11"
__pattern__ = r'https?://(?:www\.)?filecrypt\.cc/Container/\w+'
@@ -108,20 +108,21 @@ class FilecryptCc(Crypter):
post={'button.x': captcha_code[0], 'button.y': captcha_code[1]},
cookies=True,
decode=True)
+
else:
recaptcha = ReCaptcha(self)
captcha_key = recaptcha.detect_key()
if captcha_key:
- self.siteWithLinks = self.load(self.pyfile.url,
- post={'g-recaptcha-response': recaptcha.challenge(captcha_key, True)},
- cookies=True,
- decode=True)
+ response, challenge = recaptcha.challenge(captcha_key)
+ self.siteWithLinks = self.load(self.pyfile.url,
+ post={'g-recaptcha-response': response},
+ decode=True)
else:
- self.logDebug("No captcha found")
+ self.logInfo(_("No captcha found"))
self.siteWithLinks = self.html
- if "recaptcha_image" in self.siteWithLinks:
+ if "recaptcha_image" in self.siteWithLinks or "data-sitekey" in self.siteWithLinks:
self.invalidCaptcha()
self.retry()
diff --git a/module/plugins/crypter/Go4UpCom.py b/module/plugins/crypter/Go4UpCom.py
index 102bc32b5..a7e16c0ab 100644
--- a/module/plugins/crypter/Go4UpCom.py
+++ b/module/plugins/crypter/Go4UpCom.py
@@ -40,7 +40,7 @@ class Go4UpCom(SimpleCrypter):
for html in pages:
try:
links.append(re.search(r'<b><a href="(.+?)"', html).group(1))
- except:
+ except Exception:
continue
return links
diff --git a/module/plugins/crypter/JunocloudMeFolder.py b/module/plugins/crypter/JunocloudMeFolder.py
deleted file mode 100644
index 990f25902..000000000
--- a/module/plugins/crypter/JunocloudMeFolder.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from module.plugins.internal.XFSCrypter import XFSCrypter, create_getInfo
-
-
-class JunocloudMeFolder(XFSCrypter):
- __name__ = "JunocloudMeFolder"
- __type__ = "crypter"
- __version__ = "0.03"
-
- __pattern__ = r'http://(?:www\.)?junocloud\.me/folders/(?P<ID>\d+/\w+)'
- __config__ = [("use_subfolder", "bool", "Save package to subfolder", True),
- ("subfolder_per_package", "bool", "Create a subfolder for each package", True)]
-
- __description__ = """Junocloud.me folder decrypter plugin"""
- __license__ = "GPLv3"
- __authors__ = [("guidobelix", "guidobelix@hotmail.it")]
-
-
- HOSTER_DOMAIN = "junocloud.me"
-
-
-getInfo = create_getInfo(JunocloudMeFolder)
diff --git a/module/plugins/crypter/LinkCryptWs.py b/module/plugins/crypter/LinkCryptWs.py
index 996a92c7b..c67372e3d 100644
--- a/module/plugins/crypter/LinkCryptWs.py
+++ b/module/plugins/crypter/LinkCryptWs.py
@@ -279,7 +279,7 @@ class LinkCryptWs(Crypter):
(vcrypted, vjk) = self._getCipherParams(cnl_section)
for (crypted, jk) in zip(vcrypted, vjk):
package_links.extend(self._getLinks(crypted, jk))
- except:
+ except Exception:
self.logError(_("Unable to decrypt CNL links (JS Error) try to get over links"))
return self.handleWebLinks()
diff --git a/module/plugins/crypter/MegaCoNzFolder.py b/module/plugins/crypter/MegaCoNzFolder.py
index bec4eba22..954bfb9a5 100644
--- a/module/plugins/crypter/MegaCoNzFolder.py
+++ b/module/plugins/crypter/MegaCoNzFolder.py
@@ -29,4 +29,4 @@ class MegaCoNzFolder(Crypter):
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")
+ self.fail(_("No link grabbed"))
diff --git a/module/plugins/crypter/Movie2kTo.py b/module/plugins/crypter/Movie2KTo.py
index 76bf702ac..76bf702ac 100644
--- a/module/plugins/crypter/Movie2kTo.py
+++ b/module/plugins/crypter/Movie2KTo.py
diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py
index 8b7214157..f75f6d484 100644
--- a/module/plugins/crypter/NCryptIn.py
+++ b/module/plugins/crypter/NCryptIn.py
@@ -13,7 +13,7 @@ from module.plugins.internal.CaptchaService import ReCaptcha
class NCryptIn(Crypter):
__name__ = "NCryptIn"
__type__ = "crypter"
- __version__ = "1.33"
+ __version__ = "1.34"
__pattern__ = r'http://(?:www\.)?ncrypt\.in/(?P<TYPE>folder|link|frame)-([^/\?]+)'
__config__ = [("use_subfolder", "bool", "Save package to subfolder", True),
@@ -156,7 +156,7 @@ class NCryptIn(Crypter):
captcha_key = re.search(r'\?k=(.*?)"', form).group(1)
self.logDebug("Resolving ReCaptcha with key [%s]" % captcha_key)
recaptcha = ReCaptcha(self)
- challenge, response = recaptcha.challenge(captcha_key)
+ response, challenge = recaptcha.challenge(captcha_key)
postData['recaptcha_challenge_field'] = challenge
postData['recaptcha_response_field'] = response
@@ -205,7 +205,7 @@ class NCryptIn(Crypter):
elif link_source_type == "web":
return self.handleWebLinks()
else:
- self.error('Unknown source type "%s" (this is probably a bug)' % link_source_type)
+ self.error(_('Unknown source type "%s"') % link_source_type)
def handleSingleLink(self):
@@ -229,7 +229,7 @@ class NCryptIn(Crypter):
(vcrypted, vjk) = self._getCipherParams()
for (crypted, jk) in zip(vcrypted, vjk):
package_links.extend(self._getLinks(crypted, jk))
- except:
+ except Exception:
self.fail(_("Unable to decrypt CNL2 links"))
return package_links
diff --git a/module/plugins/crypter/OronComFolder.py b/module/plugins/crypter/OronComFolder.py
index 9e06bdf32..9e06bdf32 100755..100644
--- a/module/plugins/crypter/OronComFolder.py
+++ b/module/plugins/crypter/OronComFolder.py
diff --git a/module/plugins/crypter/RapidfileshareNetFolder.py b/module/plugins/crypter/RapidfileshareNetFolder.py
deleted file mode 100644
index fc3d4241e..000000000
--- a/module/plugins/crypter/RapidfileshareNetFolder.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from module.plugins.internal.XFSCrypter import XFSCrypter, create_getInfo
-
-
-class RapidfileshareNetFolder(XFSCrypter):
- __name__ = "RapidfileshareNetFolder"
- __type__ = "crypter"
- __version__ = "0.03"
-
- __pattern__ = r'http://(?:www\.)?rapidfileshare\.net/users/\w+/\d+/\w+'
- __config__ = [("use_subfolder", "bool", "Save package to subfolder", True),
- ("subfolder_per_package", "bool", "Create a subfolder for each package", True)]
-
- __description__ = """Rapidfileshare.net folder decrypter plugin"""
- __license__ = "GPLv3"
- __authors__ = [("guidobelix", "guidobelix@hotmail.it")]
-
-
- HOSTER_DOMAIN = "rapidfileshare.net"
-
-
-getInfo = create_getInfo(RapidfileshareNetFolder)
diff --git a/module/plugins/crypter/RelinkUs.py b/module/plugins/crypter/RelinkUs.py
index c5a3f1011..a6014c866 100644
--- a/module/plugins/crypter/RelinkUs.py
+++ b/module/plugins/crypter/RelinkUs.py
@@ -191,7 +191,7 @@ class RelinkUs(Crypter):
elif source == 'web':
return self.handleWEBLinks()
else:
- self.error('Unknown source type "%s" (this is probably a bug)' % source)
+ self.error(_('Unknown source type "%s"') % source)
def handleCNL2Links(self):
@@ -204,7 +204,7 @@ class RelinkUs(Crypter):
(vcrypted, vjk) = self._getCipherParams(cnl2_form)
for (crypted, jk) in zip(vcrypted, vjk):
package_links.extend(self._getLinks(crypted, jk))
- except:
+ except Exception:
self.logDebug("Unable to decrypt CNL2 links")
return package_links
@@ -223,8 +223,10 @@ class RelinkUs(Crypter):
with open(dlc_filepath, "wb") as f:
f.write(dlc)
package_links.append(dlc_filepath)
- except:
- self.fail("Unable to download DLC container")
+
+ except Exception:
+ self.fail(_("Unable to download DLC container"))
+
return package_links
diff --git a/module/plugins/crypter/SafelinkingNet.py b/module/plugins/crypter/SafelinkingNet.py
index a56a0a44c..8e46e1e41 100644
--- a/module/plugins/crypter/SafelinkingNet.py
+++ b/module/plugins/crypter/SafelinkingNet.py
@@ -14,7 +14,7 @@ from module.plugins.internal.CaptchaService import SolveMedia
class SafelinkingNet(Crypter):
__name__ = "SafelinkingNet"
__type__ = "crypter"
- __version__ = "0.13"
+ __version__ = "0.14"
__pattern__ = r'https?://(?:www\.)?safelinking\.net/([pd])/\w+'
__config__ = [("use_subfolder", "bool", "Save package to subfolder", True),
@@ -57,7 +57,7 @@ class SafelinkingNet(Crypter):
else:
self.fail(_("Error parsing captcha"))
- challenge, response = captcha.challenge(captchaKey)
+ response, challenge = captcha.challenge(captchaKey)
postData['adcopy_challenge'] = challenge
postData['adcopy_response'] = response
diff --git a/module/plugins/crypter/ShareLinksBiz.py b/module/plugins/crypter/ShareLinksBiz.py
index d2e8138f6..df53b5879 100644
--- a/module/plugins/crypter/ShareLinksBiz.py
+++ b/module/plugins/crypter/ShareLinksBiz.py
@@ -235,7 +235,7 @@ class ShareLinksBiz(Crypter):
try:
(crypted, jk) = self._getCipherParams()
package_links.extend(self._getLinks(crypted, jk))
- except:
+ except Exception:
self.fail(_("Unable to decrypt CNL2 links"))
return package_links
diff --git a/module/plugins/crypter/TusfilesNetFolder.py b/module/plugins/crypter/TusfilesNetFolder.py
index 20bed0ab1..cb8efc9a8 100644
--- a/module/plugins/crypter/TusfilesNetFolder.py
+++ b/module/plugins/crypter/TusfilesNetFolder.py
@@ -22,8 +22,6 @@ class TusfilesNetFolder(XFSCrypter):
("stickell", "l.stickell@yahoo.it")]
- HOSTER_DOMAIN = "tusfiles.net"
-
PAGES_PATTERN = r'>\((\d+) \w+\)<'
URL_REPLACEMENTS = [(__pattern__ + ".*", r'https://www.tusfiles.net/go/\g<ID>/')]
diff --git a/module/plugins/hooks/AndroidPhoneNotify.py b/module/plugins/hooks/AndroidPhoneNotify.py
index 18e1cce66..fbc2acd5c 100644
--- a/module/plugins/hooks/AndroidPhoneNotify.py
+++ b/module/plugins/hooks/AndroidPhoneNotify.py
@@ -9,7 +9,7 @@ from module.plugins.Hook import Hook
class AndroidPhoneNotify(Hook):
__name__ = "AndroidPhoneNotify"
__type__ = "hook"
- __version__ = "0.02"
+ __version__ = "0.03"
__config__ = [("apikey" , "str" , "API key" , "" ),
("notifycaptcha" , "bool", "Notify captcha request" , True ),
@@ -51,7 +51,7 @@ class AndroidPhoneNotify(Hook):
self.notify(_("Package finished"), pypack.name)
- def allDownloadsProcessed(self, thread):
+ def allDownloadsProcessed(self):
if not self.getConfig("notifyprocessed"):
return False
diff --git a/module/plugins/hooks/Captcha9kw.py b/module/plugins/hooks/Captcha9Kw.py
index 600694e78..600694e78 100755..100644
--- a/module/plugins/hooks/Captcha9kw.py
+++ b/module/plugins/hooks/Captcha9Kw.py
diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py
index 222310c25..94a240d4c 100644
--- a/module/plugins/hooks/ClickAndLoad.py
+++ b/module/plugins/hooks/ClickAndLoad.py
@@ -18,10 +18,55 @@ def forward(source, destination):
destination.shutdown(socket.SHUT_WR)
+#: socket.create_connection wrapper for python 2.5
+def create_connection(address, timeout=object(), source_address=None):
+ try:
+ return socket.create_connection(address,
+ socket._GLOBAL_DEFAULT_TIMEOUT if type(timeout) == object else timeout,
+ source_address)
+
+ except SyntaxError:
+ """Connect to *address* and return the socket object.
+
+ Convenience function. Connect to *address* (a 2-tuple ``(host,
+ port)``) and return the socket object. Passing the optional
+ *timeout* parameter will set the timeout on the socket instance
+ before attempting to connect. If no *timeout* is supplied, the
+ global default timeout setting returned by :func:`getdefaulttimeout`
+ is used. If *source_address* is set it must be a tuple of (host, port)
+ for the socket to bind as a source address before making the connection.
+ An host of \'\' or port 0 tells the OS to use the default.
+ """
+
+ host, port = address
+ err = None
+ for res in getaddrinfo(host, port, 0, SOCK_STREAM):
+ af, socktype, proto, canonname, sa = res
+ sock = None
+ try:
+ sock = socket(af, socktype, proto)
+ if type(timeout) != object:
+ sock.settimeout(timeout)
+ if source_address:
+ sock.bind(source_address)
+ sock.connect(sa)
+ return sock
+
+ except socket.error, _:
+ err = _
+ if sock is not None:
+ sock.close()
+
+ if err is not None:
+ raise err
+ else:
+ raise socket.error("getaddrinfo returns an empty list")
+
+
class ClickAndLoad(Hook):
__name__ = "ClickAndLoad"
__type__ = "hook"
- __version__ = "0.26"
+ __version__ = "0.31"
__config__ = [("activated", "bool", "Activated" , True ),
("port" , "int" , "Port" , 9666 ),
@@ -46,7 +91,7 @@ class ClickAndLoad(Hook):
@threaded
def proxy(self, ip, webport, cnlport):
- hookManager.startThread(self.server, ip, webport, cnlport)
+ self.manager.startThread(self.server, ip, webport, cnlport)
lock = Lock()
lock.acquire()
lock.acquire()
@@ -62,14 +107,13 @@ class ClickAndLoad(Hook):
while True:
server_socket = dock_socket.accept()[0]
- client_socket = socket.create_connection(("127.0.0.1", webport))
+ client_socket = create_connection(("127.0.0.1", webport))
- hookManager.startThread(forward, server_socket, client_socket)
- hookManager.startThread(forward, client_socket, server_socket)
+ self.manager.startThread(forward, server_socket, client_socket)
+ self.manager.startThread(forward, client_socket, server_socket)
except socket.error, e:
self.logError(e)
- self.server(ip, webport, cnlport)
finally:
dock_socket.close()
diff --git a/module/plugins/hooks/DeathByCaptcha.py b/module/plugins/hooks/DeathByCaptcha.py
index 050b6fe15..d513c446d 100644
--- a/module/plugins/hooks/DeathByCaptcha.py
+++ b/module/plugins/hooks/DeathByCaptcha.py
@@ -135,7 +135,7 @@ class DeathByCaptcha(Hook):
def submit(self, captcha, captchaType="file", match=None):
- #workaround multipart-post bug in HTTPRequest.py
+ #@NOTE: Workaround multipart-post bug in HTTPRequest.py
if re.match("^\w*$", self.getConfig("passkey")):
multipart = True
data = (FORM_FILE, captcha)
diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py
index fc0cae44f..b2b4548a2 100644
--- a/module/plugins/hooks/ExternalScripts.py
+++ b/module/plugins/hooks/ExternalScripts.py
@@ -13,7 +13,7 @@ from module.utils import save_join
class ExternalScripts(Hook):
__name__ = "ExternalScripts"
__type__ = "hook"
- __version__ = "0.26"
+ __version__ = "0.27"
__config__ = [("activated", "bool", "Activated", True)]
@@ -59,7 +59,7 @@ class ExternalScripts(Hook):
if not exists(path):
try:
makedirs(path)
- except:
+ except Exception:
self.logDebug("Script folder %s not created" % folder)
return
@@ -136,11 +136,11 @@ class ExternalScripts(Hook):
self.callScript(script)
- def allDownloadsFinished(self, thread):
+ def allDownloadsFinished(self):
for script in chain(self.scripts['all_downloads_finished'], self.scripts['all_dls_finished']):
self.callScript(script)
- def allDownloadsProcessed(self, thread):
+ def allDownloadsProcessed(self):
for script in chain(self.scripts['all_downloads_processed'], self.scripts['all_dls_processed']):
self.callScript(script)
diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py
index 2e9efa2b0..5c4e9bc82 100644
--- a/module/plugins/hooks/ExtractArchive.py
+++ b/module/plugins/hooks/ExtractArchive.py
@@ -6,8 +6,6 @@ import os
import sys
from copy import copy
-from os import remove, chmod, makedirs
-from os.path import exists, basename, isfile, isdir
from traceback import print_exc
# monkey patch bug in python 2.6 and lower
@@ -47,18 +45,17 @@ if sys.version_info < (2, 7) and os.name != "nt":
if os.name != "nt":
from grp import getgrnam
- from os import chown
from pwd import getpwnam
from module.plugins.Hook import Hook, threaded, Expose
from module.plugins.internal.Extractor import ArchiveError, CRCError, PasswordError
-from module.utils import save_join, uniqify
+from module.utils import fs_decode, save_join, uniqify
class ExtractArchive(Hook):
__name__ = "ExtractArchive"
__type__ = "hook"
- __version__ = "1.03"
+ __version__ = "1.10"
__config__ = [("activated" , "bool" , "Activated" , True ),
("fullpath" , "bool" , "Extract full path" , True ),
@@ -77,7 +74,9 @@ class ExtractArchive(Hook):
__description__ = """Extract different kind of archives"""
__license__ = "GPLv3"
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+ __authors__ = [("RaNaN", "ranan@pyload.org"),
+ ("AndroKev", ""),
+ ("Walter Purcaro", "vuolter@gmail.com")]
event_list = ["allDownloadsProcessed"]
@@ -93,17 +92,18 @@ class ExtractArchive(Hook):
def setup(self):
- self.plugins = []
- self.passwords = []
- names = []
+ self.interval = 300
+ self.extractors = []
+ self.passwords = []
+ names = []
for p in ("UnRar", "SevenZip", "UnZip"):
try:
module = self.core.pluginManager.loadModule("internal", p)
klass = getattr(module, p)
if klass.checkDeps():
names.append(p)
- self.plugins.append(klass)
+ self.extractors.append(klass)
except OSError, e:
if e.errno == 2:
@@ -123,66 +123,48 @@ class ExtractArchive(Hook):
else:
self.logInfo(_("No Extract plugins activated"))
- # queue with package ids
- self.queue = []
-
def periodical(self):
- if not self.queue or self.extracting:
- return
-
- local = copy(self.queue)
- self.queue[:] = []
-
- self.extractPackages(*local)
+ if not self.extracting:
+ self.extractPackage(*self.getQueue())
@Expose
- def extractPackage(self, id):
- """ Extract package wrapper"""
- self.extractPackages(id)
-
-
- @Expose
- def extractPackages(self, *ids):
+ def extractPackage(self, *ids):
""" Extract packages with given id"""
self.manager.startThread(self.extract, ids)
def packageFinished(self, pypack):
- if self.getConfig("queue") or self.extracting:
+ if self.extracting or self.getConfig("queue"):
self.logInfo(_("Package %s queued for later extracting") % pypack.name)
- self.queue.append(pypack.id)
+ self.addToQueue(pypack.id)
else:
self.extractPackage(pypack.id)
@threaded
- def allDownloadsProcessed(self, thread):
- local = copy(self.queue)
- self.queue[:] = []
-
- if self.extract(local): #: check only if all gone fine, no failed reporting for now
+ def allDownloadsProcessed(self):
+ if self.extract(self.getQueue()): #@NOTE: check only if all gone fine, no failed reporting for now
self.manager.dispatchEvent("all_archives_extracted")
self.manager.dispatchEvent("all_archives_processed")
def extract(self, ids):
- self.extracting = True
-
processed = []
extracted = []
failed = []
- clearlist = lambda string: [x.lstrip('.') for x in string.replace(' ', '').replace(',', '|').replace(';', '|').split('|')]
+ clearList = lambda string: [x.lstrip('.') for x in string.replace(' ', '').replace(',', '|').replace(';', '|').split('|')]
destination = self.getConfig("destination")
subfolder = self.getConfig("subfolder")
fullpath = self.getConfig("fullpath")
overwrite = self.getConfig("overwrite")
- extensions = clearlist(self.getConfig("extensions"))
- excludefiles = clearlist(self.getConfig("excludefiles"))
+ extensions = clearList(self.getConfig("extensions"))
+ excludefiles = clearList(self.getConfig("excludefiles"))
+ excludefiles = self.getConfig("excludefiles")
renice = self.getConfig("renice")
recursive = self.getConfig("recursive")
delete = self.getConfig("delete")
@@ -197,25 +179,27 @@ class ExtractArchive(Hook):
# dl folder
dl = self.config['general']['download_folder']
- #iterate packages -> plugins -> targets
+ #iterate packages -> extractors -> targets
for pid in ids:
- p = self.core.files.getPackage(pid)
- self.logInfo(_("Check package: %s") % p.name)
- if not p:
+ pypack = self.core.files.getPackage(pid)
+
+ self.logInfo(_("Check package: %s") % pypack.name)
+
+ if not pypack:
continue
# determine output folder
- out = save_join(dl, p.folder, destination, "") #: force trailing slash
+ out = save_join(dl, pypack.folder, destination, "") #: force trailing slash
if subfolder:
- out = save_join(out, p.folder)
+ out = save_join(out, pypack.folder)
- if not exists(out):
- makedirs(out)
+ if not os.path.exists(out):
+ os.makedirs(out)
- files_ids = [(save_join(dl, p.folder, x['name']), x['id']) for x in p.getChildren().itervalues()]
matched = False
success = True
+ files_ids = [(save_join(dl, pypack.folder, x['name']), x['id']) for x in pypack.getChildren().itervalues()]
# check as long there are unseen files
while files_ids:
@@ -224,42 +208,41 @@ class ExtractArchive(Hook):
if extensions:
files_ids = [(file, id) for file, id in files_ids if filter(lambda ext: file.endswith(ext), extensions)]
- for plugin in self.plugins:
- targets = plugin.getTargets(files_ids)
-
+ for Extractor in self.extractors:
+ targets = Extractor.getTargets(files_ids)
if targets:
- self.logDebug("Targets for %s: %s" % (plugin.__name__, targets))
+ self.logDebug("Targets for %s: %s" % (Extractor.__name__, targets))
matched = True
- for target, fid in targets:
- if target in processed:
- self.logDebug(basename(target), "skipped")
+ for filename, fid in targets:
+ fname = os.path.basename(filename)
+
+ if filename in processed:
+ self.logDebug(fname, "Skipped")
continue
- processed.append(target) # prevent extracting same file twice
+ processed.append(filename) # prevent extracting same file twice
- self.logInfo(basename(target), _("Extract to: %s") % out)
+ self.logInfo(fname, _("Extract to: %s") % out)
try:
- klass = plugin(self,
- target,
- out,
- p.password,
- fullpath,
- overwrite,
- excludefiles,
- renice,
- delete,
- keepbroken)
+ self.extracting = True
+
+ klass = Extractor(self,
+ filename,
+ out,
+ fullpath,
+ overwrite,
+ excludefiles,
+ renice,
+ delete,
+ keepbroken,
+ fid)
klass.init()
- new_files = self._extract(klass, fid)
+ new_files = self._extract(klass, fid, pypack.password)
except Exception, e:
- self.logError(basename(target), e)
- new_files = None
-
- if new_files is None:
- self.logWarning(basename(target), _("No files extracted"))
+ self.logError(fname, e)
success = False
continue
@@ -267,10 +250,10 @@ class ExtractArchive(Hook):
self.setPermissions(new_files)
for file in new_files:
- if not exists(file):
+ if not os.path.exists(file):
self.logDebug("New file %s does not exists" % file)
continue
- if recursive and isfile(file):
+ if recursive and os.path.isfile(file):
new_files_ids.append((file, fid)) # append as new target
files_ids = new_files_ids # also check extracted files
@@ -278,10 +261,10 @@ class ExtractArchive(Hook):
if matched:
if success:
extracted.append(pid)
- self.manager.dispatchEvent("package_extracted", p)
+ self.manager.dispatchEvent("package_extracted", pypack)
else:
failed.append(pid)
- self.manager.dispatchEvent("package_extract_failed", p)
+ self.manager.dispatchEvent("package_extract_failed", pypack)
else:
self.logInfo(_("No files found to extract"))
@@ -295,124 +278,103 @@ class ExtractArchive(Hook):
return True if not failed else False
- def _extract(self, plugin, fid):
+ def _extract(self, archive, fid, password):
pyfile = self.core.files.getFile(fid)
+ fname = os.path.basename(fs_decode(archive.target))
pyfile.setCustomStatus(_("extracting"))
+ pyfile.setProgress(0)
try:
- progress = lambda x: pyfile.setProgress(x)
- encrypted = False
- passwords = self.getPasswords()
-
- try:
- self.logInfo(basename(plugin.file), "Verifying...")
-
- tmp_password = plugin.password
- plugin.password = "" #: Force verifying without password
-
- plugin.verify()
-
- except PasswordError:
- encrypted = True
-
- except CRCError:
- self.logWarning(basename(plugin.file), _("Archive damaged"))
-
- if not self.getConfig("repair"):
- raise CRCError
-
- elif plugin.repair():
- self.logInfo(basename(plugin.file), _("Successfully repaired"))
-
- elif not self.getConfig("keepbroken"):
- raise ArchiveError(_("Broken archive"))
-
- else:
- self.logInfo(basename(plugin.file), _("All OK"))
-
- plugin.password = tmp_password
-
- if not encrypted:
- plugin.extract(progress)
+ success = False
+ if not archive.checkArchive():
+ archive.extract(password)
+ success = True
else:
- self.logInfo(basename(plugin.file), _("Password protected"))
+ self.logInfo(fname, _("Password protected"))
+ self.logDebug("Password: %s" % (password or "No provided"))
- if plugin.password:
- passwords.insert(0, plugin.password)
- passwords = uniqify(self.passwords)
- self.logDebug("Password: %s" % plugin.password)
- else:
- self.logDebug("No package password provided")
-
- for pw in passwords:
+ for pw in set(self.getPasswords(False) + [password]):
try:
self.logDebug("Try password: %s" % pw)
-
- if plugin.setPassword(pw):
- plugin.extract(progress)
+ if archive.checkPassword(pw):
+ archive.extract(pw)
self.addPassword(pw)
+ success = True
break
- else:
- raise PasswordError
except PasswordError:
self.logDebug("Password was wrong")
else:
raise PasswordError
+ pyfile.setProgress(100)
+ pyfile.setStatus("processing")
+
if self.core.debug:
self.logDebug("Would delete: %s" % ", ".join(plugin.getDeleteFiles()))
if self.getConfig("delete"):
- files = plugin.getDeleteFiles()
+ files = archive.getDeleteFiles()
self.logInfo(_("Deleting %s files") % len(files))
for f in files:
- if exists(f):
- remove(f)
+ if os.path.exists(f):
+ os.remove(f)
else:
self.logDebug("%s does not exists" % f)
- self.logInfo(basename(plugin.file), _("Extracting finished"))
+ self.logInfo(fname, _("Extracting finished"))
- extracted_files = plugin.getExtractedFiles()
- self.manager.dispatchEvent("archive_extracted", pyfile, plugin.out, plugin.file, extracted_files)
+ extracted_files = archive.getExtractedFiles()
+ self.manager.dispatchEvent("archive_extracted", pyfile, archive.out, archive.file, extracted_files)
return extracted_files
except PasswordError:
- self.logError(basename(plugin.file), _("Wrong password" if passwords else "No password found"))
- plugin.password = ""
+ self.logError(fname, _("Wrong password" if password else "No password found"))
except CRCError:
- self.logError(basename(plugin.file), _("CRC Mismatch"))
+ self.logError(fname, _("CRC Mismatch"))
except ArchiveError, e:
- self.logError(basename(plugin.file), _("Archive Error"), e)
+ self.logError(fname, _("Archive Error"), e)
except Exception, e:
if self.core.debug:
print_exc()
- self.logError(basename(plugin.file), _("Unknown Error"), e)
+ self.logError(fname, _("Unknown Error"), e)
+
+ finally:
+ pyfile.finishIfDone()
self.manager.dispatchEvent("archive_extract_failed", pyfile)
- self.logError(basename(plugin.file), _("Extract failed"))
+ raise Exception(_("Extract failed"))
+
+
+ def getQueue(self):
+ return self.getStorage("ExtractArchive", [])
+
+
+ def addToQueue(self, item):
+ queue = self.getQueue()
+ return self.setStorage("ExtractArchive", queue + [item] if item not in queue else queue)
@Expose
- def getPasswords(self):
+ def getPasswords(self, reload=True):
""" List of saved passwords """
+ if reload:
+ self.reloadPasswords()
+
return self.passwords
def reloadPasswords(self):
- passwordfile = self.getConfig("passwordfile")
-
try:
passwords = []
- with open(passwordfile, "a+") as f:
+ with open(self.getConfig("passwordfile")) as f:
for pw in f.read().splitlines():
passwords.append(pw)
@@ -426,13 +388,10 @@ class ExtractArchive(Hook):
@Expose
def addPassword(self, pw):
""" Adds a password to saved list"""
- passwordfile = self.getConfig("passwordfile")
-
- self.passwords.insert(0, pw)
- self.passwords = uniqify(self.passwords)
-
try:
- with open(passwordfile, "wb") as f:
+ self.passwords = uniqify([pw] + self.passwords)
+
+ with open(self.getConfig("passwordfile"), "wb") as f:
for pw in self.passwords:
f.write(pw + '\n')
@@ -442,20 +401,21 @@ class ExtractArchive(Hook):
def setPermissions(self, files):
for f in files:
- if not exists(f):
+ if not os.path.exists(f):
continue
try:
if self.config['permission']['change_file']:
- if isfile(f):
- chmod(f, int(self.config['permission']['file'], 8))
- elif isdir(f):
- chmod(f, int(self.config['permission']['folder'], 8))
+ if os.path.isfile(f):
+ os.chmod(f, int(self.config['permission']['file'], 8))
+
+ elif os.path.isdir(f):
+ os.chmod(f, int(self.config['permission']['folder'], 8))
if self.config['permission']['change_dl'] and os.name != "nt":
uid = getpwnam(self.config['permission']['user'])[2]
gid = getgrnam(self.config['permission']['group'])[2]
- chown(f, uid, gid)
+ os.chown(f, uid, gid)
except Exception, e:
self.logWarning(_("Setting User and Group failed"), e)
diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py
index efd4e411d..98fa1d030 100644
--- a/module/plugins/hooks/IRCInterface.py
+++ b/module/plugins/hooks/IRCInterface.py
@@ -61,7 +61,7 @@ class IRCInterface(Thread, Hook):
try:
if self.getConfig("info_pack"):
self.response(_("Package finished: %s") % pypack.name)
- except:
+ except Exception:
pass
@@ -70,7 +70,7 @@ class IRCInterface(Thread, Hook):
if self.getConfig("info_file"):
self.response(
_("Download finished: %(name)s @ %(plugin)s ") % {"name": pyfile.name, "plugin": pyfile.pluginname})
- except:
+ except Exception:
pass
@@ -183,7 +183,7 @@ class IRCInterface(Thread, Hook):
trigger = temp[0]
if len(temp) > 1:
args = temp[1:]
- except:
+ except Exception:
pass
handler = getattr(self, "event_%s" % trigger, self.event_pass)
@@ -347,7 +347,7 @@ class IRCInterface(Thread, Hook):
return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack['name'], id)]
- except:
+ except Exception:
# create new package
id = self.core.api.addPackage(pack, links, 1)
return ["INFO: Created new Package %s [#%d] with %d links." % (pack, id, len(links))]
diff --git a/module/plugins/hooks/ImageTyperz.py b/module/plugins/hooks/ImageTyperz.py
index d448d1be9..d62fed385 100644
--- a/module/plugins/hooks/ImageTyperz.py
+++ b/module/plugins/hooks/ImageTyperz.py
@@ -69,7 +69,7 @@ class ImageTyperz(Hook):
try:
balance = float(res)
- except:
+ except Exception:
raise ImageTyperzException("Invalid response")
self.logInfo(_("Account balance: $%s left") % res)
@@ -82,7 +82,7 @@ class ImageTyperz(Hook):
req.c.setopt(LOW_SPEED_TIME, 80)
try:
- #workaround multipart-post bug in HTTPRequest.py
+ #@NOTE: Workaround multipart-post bug in HTTPRequest.py
if re.match("^\w*$", self.getConfig("passkey")):
multipart = True
data = (FORM_FILE, captcha)
diff --git a/module/plugins/hooks/LinkdecrypterCom.py b/module/plugins/hooks/LinkdecrypterCom.py
index d4924a687..f85a598bc 100644
--- a/module/plugins/hooks/LinkdecrypterCom.py
+++ b/module/plugins/hooks/LinkdecrypterCom.py
@@ -8,7 +8,7 @@ from module.plugins.internal.MultiHook import MultiHook
class LinkdecrypterCom(MultiHook):
__name__ = "LinkdecrypterCom"
__type__ = "hook"
- __version__ = "1.01"
+ __version__ = "1.02"
__config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
@@ -21,8 +21,5 @@ class LinkdecrypterCom(MultiHook):
def getCrypters(self):
- try:
- html = self.getURL("http://linkdecrypter.com/")
- return re.search(r'>Supported\(\d+\)</b>: <i>(.+?) \+ RSDF', html).group(1).split(', ')
- except Exception:
- return list()
+ return re.search(r'>Supported\(\d+\)</b>: <i>(.[\w.\-, ]+)',
+ self.getURL("http://linkdecrypter.com/").replace("(g)", "")).group(1).split(', ')
diff --git a/module/plugins/hooks/SkipRev.py b/module/plugins/hooks/SkipRev.py
index 6b4e715da..51d385bb4 100644
--- a/module/plugins/hooks/SkipRev.py
+++ b/module/plugins/hooks/SkipRev.py
@@ -18,7 +18,7 @@ def _setup(self):
class SkipRev(Hook):
__name__ = "SkipRev"
__type__ = "hook"
- __version__ = "0.23"
+ __version__ = "0.24"
__config__ = [("tokeep", "int", "Number of rev files to keep for package (-1 to auto)", -1)]
@@ -34,7 +34,7 @@ class SkipRev(Hook):
def _pyname(self, pyfile):
if hasattr(pyfile.pluginmodule, "getInfo"):
- return next(getattr(pyfile.pluginmodule, "getInfo")([pyfile.url]))[0]
+ return getattr(pyfile.pluginmodule, "getInfo")([pyfile.url]).next()[0]
else:
self.logWarning("Unable to grab file name")
return urlparse(unquote(pyfile.url)).path.split('/')[-1]
diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py
index c72699228..b6a8bac7c 100644
--- a/module/plugins/hooks/UpdateManager.py
+++ b/module/plugins/hooks/UpdateManager.py
@@ -16,14 +16,14 @@ from module.utils import save_join
class UpdateManager(Hook):
__name__ = "UpdateManager"
__type__ = "hook"
- __version__ = "0.42"
+ __version__ = "0.43"
__config__ = [("activated" , "bool" , "Activated" , True ),
("mode" , "pyLoad + plugins;plugins only", "Check updates for" , "pyLoad + plugins"),
("interval" , "int" , "Check interval in hours" , 8 ),
("autorestart" , "bool" , "Automatically restart pyLoad when required" , True ),
("reloadplugins", "bool" , "Monitor plugins for code changes in debug mode", True ),
- ("nodebugupdate", "bool" , "Don't check for updates in debug mode" , True )]
+ ("nodebugupdate", "bool" , "Don't check for updates in debug mode" , False )]
__description__ = """ Check for updates """
__license__ = "GPLv3"
@@ -117,7 +117,7 @@ class UpdateManager(Hook):
def server_request(self):
try:
return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines()
- except:
+ except Exception:
self.logWarning(_("Unable to contact server to get updates"))
@@ -192,7 +192,7 @@ class UpdateManager(Hook):
# Protect UpdateManager from self-removing
try:
blacklisted.remove(("hook", "UpdateManager"))
- except:
+ except Exception:
pass
for t, n in blacklisted:
diff --git a/module/plugins/hooks/WindowsPhoneToastNotify.py b/module/plugins/hooks/WindowsPhoneToastNotify.py
index 886d4ca6a..20686ee36 100644
--- a/module/plugins/hooks/WindowsPhoneToastNotify.py
+++ b/module/plugins/hooks/WindowsPhoneToastNotify.py
@@ -10,7 +10,7 @@ from module.plugins.Hook import Hook
class WindowsPhoneToastNotify(Hook):
__name__ = "WindowsPhoneToastNotify"
__type__ = "hook"
- __version__ = "0.04"
+ __version__ = "0.05"
__config__ = [("id" , "str" , "Push ID" , "" ),
("url" , "str" , "Push url" , "" ),
@@ -53,7 +53,7 @@ class WindowsPhoneToastNotify(Hook):
self.notify(_("Package finished"), pypack.name)
- def allDownloadsProcessed(self, thread):
+ def allDownloadsProcessed(self):
if not self.getConfig("notifyprocessed"):
return False
diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py
index 0745a6c7e..e6e30ca8f 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.30"
+ __version__ = "0.31"
__config__ = [("activated" , "bool", "Activated" , True ),
("use_hoster_list" , "bool", "Load listed hosters only" , False),
@@ -30,15 +30,15 @@ class XFileSharingPro(Hook):
HOSTER_BUILTIN = [#WORKING HOSTERS:
"180upload.com", "backin.net", "eyesfile.ca", "file4safe.com", "fileband.com", "filedwon.com",
- "fileparadox.in", "filevice.com", "hostingbulk.com", "linestorage.com", "ravishare.com", "ryushare.com",
- "salefiles.com", "sendmyway.com", "sharesix.com", "thefile.me", "verzend.be", "xvidstage.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",
#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", "zalaa.com", "zomgupload.com",
#NOT WORKING:
"amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", "laoupload.com", "rd-fs.com"]
- CRYPTER_BUILTIN = []
+ CRYPTER_BUILTIN = ["junocloud.me", "rapidfileshare.net"]
# def pluginConfigChanged(self.__name__, plugin, name, value):
diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py
index bbeab4341..b8e9fc1ad 100644
--- a/module/plugins/hooks/XMPPInterface.py
+++ b/module/plugins/hooks/XMPPInterface.py
@@ -69,7 +69,7 @@ class XMPPInterface(IRCInterface, JabberClient):
try:
if self.getConfig("info_pack"):
self.announce(_("Package finished: %s") % pypack.name)
- except:
+ except Exception:
pass
@@ -78,7 +78,7 @@ class XMPPInterface(IRCInterface, JabberClient):
if self.getConfig("info_file"):
self.announce(
_("Download finished: %(name)s @ %(plugin)s") % {"name": pyfile.name, "plugin": pyfile.pluginname})
- except:
+ except Exception:
pass
@@ -152,7 +152,7 @@ class XMPPInterface(IRCInterface, JabberClient):
trigger = temp[0]
if len(temp) > 1:
args = temp[1:]
- except:
+ except Exception:
pass
handler = getattr(self, "event_%s" % trigger, self.event_pass)
diff --git a/module/plugins/hoster/BasePlugin.py b/module/plugins/hoster/BasePlugin.py
index 6d3132e65..4f9e25a35 100644
--- a/module/plugins/hoster/BasePlugin.py
+++ b/module/plugins/hoster/BasePlugin.py
@@ -6,14 +6,14 @@ from urllib import unquote
from urlparse import urljoin, urlparse
from module.network.HTTPRequest import BadHeader
-from module.plugins.internal.SimpleHoster import create_getInfo
+from module.plugins.internal.SimpleHoster import create_getInfo, fileUrl
from module.plugins.Hoster import Hoster
class BasePlugin(Hoster):
__name__ = "BasePlugin"
__type__ = "hoster"
- __version__ = "0.30"
+ __version__ = "0.33"
__pattern__ = r'^unmatchable$'
@@ -35,7 +35,8 @@ class BasePlugin(Hoster):
def setup(self):
- self.chunkLimit = -1
+ self.chunkLimit = -1
+ self.multiDL = True
self.resumeDownload = True
@@ -49,7 +50,12 @@ class BasePlugin(Hoster):
for _i in xrange(5):
try:
- self.downloadFile(pyfile)
+ link = fileUrl(self, unquote(pyfile.url))
+
+ if link:
+ self.download(link, ref=False, disposition=True)
+ else:
+ self.fail(_("File not found"))
except BadHeader, e:
if e.code is 404:
@@ -85,33 +91,4 @@ class BasePlugin(Hoster):
self.fail(check.capitalize())
- def downloadFile(self, pyfile):
- url = pyfile.url
-
- for i in xrange(1, 7): #@TODO: retrieve the pycurl.MAXREDIRS value set by req
- header = self.load(url, ref=True, cookies=True, just_header=True, decode=True)
-
- if 'location' not in header or not header['location']:
- if 'code' in header and header['code'] not in (200, 201, 203, 206):
- self.logDebug("Received HTTP status code: %d" % header['code'])
- self.fail(_("File not found"))
- else:
- break
-
- location = header['location']
-
- self.logDebug("Redirect #%d to: %s" % (i, location))
-
- if urlparse(location).scheme:
- url = location
- else:
- p = urlparse(url)
- base = "%s://%s" % (p.scheme, p.netloc)
- url = urljoin(base, location)
- else:
- self.fail(_("Too many redirects"))
-
- self.download(unquote(url), disposition=True)
-
-
getInfo = create_getInfo(BasePlugin)
diff --git a/module/plugins/hoster/BillionuploadsCom.py b/module/plugins/hoster/BillionuploadsCom.py
index b20ace0f1..7d7e2624a 100644
--- a/module/plugins/hoster/BillionuploadsCom.py
+++ b/module/plugins/hoster/BillionuploadsCom.py
@@ -15,8 +15,6 @@ class BillionuploadsCom(XFSHoster):
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
- HOSTER_DOMAIN = "billionuploads.com"
-
NAME_PATTERN = r'<td class="dofir" title="(?P<N>.+?)"'
SIZE_PATTERN = r'<td class="dofir">(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py
index f7b4d2709..657e70e56 100644
--- a/module/plugins/hoster/BitshareCom.py
+++ b/module/plugins/hoster/BitshareCom.py
@@ -11,7 +11,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class BitshareCom(SimpleHoster):
__name__ = "BitshareCom"
__type__ = "hoster"
- __version__ = "0.52"
+ __version__ = "0.53"
__pattern__ = r'http://(?:www\.)?bitshare\.com/(files/)?(?(1)|\?f=)(?P<ID>\w+)(?(1)/(?P<NAME>.+?)\.html)'
@@ -114,7 +114,7 @@ class BitshareCom(SimpleHoster):
# Try up to 3 times
for i in xrange(3):
- challenge, response = recaptcha.challenge()
+ response, challenge = recaptcha.challenge()
res = self.load("http://bitshare.com/files-ajax/" + self.file_id + "/request.html",
post={"request" : "validateCaptcha",
"ajaxid" : self.ajaxid,
diff --git a/module/plugins/hoster/CatShareNet.py b/module/plugins/hoster/CatShareNet.py
index f2ddd64a0..339253aeb 100644
--- a/module/plugins/hoster/CatShareNet.py
+++ b/module/plugins/hoster/CatShareNet.py
@@ -9,7 +9,7 @@ from module.plugins.internal.CaptchaService import ReCaptcha
class CatShareNet(SimpleHoster):
__name__ = "CatShareNet"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.11"
__pattern__ = r'http://(?:www\.)?catshare\.net/\w{16}'
@@ -26,8 +26,9 @@ class CatShareNet(SimpleHoster):
OFFLINE_PATTERN = ur'Podany plik został usunięty\s*</div>'
IP_BLOCKED_PATTERN = ur'>Nasz serwis wykrył ÅŒe Twój adres IP nie pochodzi z Polski.<'
- SECONDS_PATTERN = 'var\scount\s=\s(\d+);'
- LINK_FREE_PATTERN = r'<form action="(.+?)" method="GET">'
+ WAIT_PATTERN = r'var\scount\s=\s(\d+);'
+
+ LINK_FREE_PATTERN = LINK_PREMIUM_PATTERN = r'<form action="(.+?)" method="GET">'
def setup(self):
@@ -43,14 +44,9 @@ class CatShareNet(SimpleHoster):
def handleFree(self, pyfile):
- m = re.search(self.SECONDS_PATTERN, self.html)
- if m:
- wait_time = int(m.group(1))
- self.wait(wait_time, True)
-
recaptcha = ReCaptcha(self)
- challenge, response = recaptcha.challenge()
+ response, challenge = recaptcha.challenge()
self.html = self.load(pyfile.url,
post={'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
diff --git a/module/plugins/hoster/CloudzillaTo.py b/module/plugins/hoster/CloudzillaTo.py
index 58b1ac0dd..ee966c280 100644
--- a/module/plugins/hoster/CloudzillaTo.py
+++ b/module/plugins/hoster/CloudzillaTo.py
@@ -47,7 +47,7 @@ class CloudzillaTo(SimpleHoster):
self.fail(ticket['error'])
if 'wait' in ticket:
- self.wait(int(ticket['wait']), int(ticket['wait']) > 5)
+ self.wait(ticket['wait'], int(ticket['wait']) > 5)
self.link = "http://%(server)s/download/%(file_id)s/%(ticket_id)s" % {'server' : ticket['server'],
'file_id' : self.info['pattern']['ID'],
diff --git a/module/plugins/hoster/CramitIn.py b/module/plugins/hoster/CramitIn.py
index f444718bc..44dac958d 100644
--- a/module/plugins/hoster/CramitIn.py
+++ b/module/plugins/hoster/CramitIn.py
@@ -15,8 +15,6 @@ class CramitIn(XFSHoster):
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
- HOSTER_DOMAIN = "cramit.in"
-
INFO_PATTERN = r'<span class=t2>\s*(?P<N>.*?)</span>.*?<small>\s*\((?P<S>.*?)\)'
LINK_PATTERN = r'href="(http://cramit\.in/file_download/.*?)"'
diff --git a/module/plugins/hoster/CrockoCom.py b/module/plugins/hoster/CrockoCom.py
index 31d0eec95..474042a5a 100644
--- a/module/plugins/hoster/CrockoCom.py
+++ b/module/plugins/hoster/CrockoCom.py
@@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class CrockoCom(SimpleHoster):
__name__ = "CrockoCom"
__type__ = "hoster"
- __version__ = "0.18"
+ __version__ = "0.19"
__pattern__ = r'http://(?:www\.)?(crocko|easy-share)\.com/\w+'
@@ -52,7 +52,7 @@ class CrockoCom(SimpleHoster):
recaptcha = ReCaptcha(self)
for _i in xrange(5):
- inputs['recaptcha_challenge_field'], inputs['recaptcha_response_field'] = recaptcha.challenge()
+ inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge()
self.download(action, post=inputs)
if self.checkDownload({"captcha": recaptcha.KEY_AJAX_PATTERN}):
diff --git a/module/plugins/hoster/DateiTo.py b/module/plugins/hoster/DateiTo.py
index 99b86e000..e5061e026 100644
--- a/module/plugins/hoster/DateiTo.py
+++ b/module/plugins/hoster/DateiTo.py
@@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DateiTo(SimpleHoster):
__name__ = "DateiTo"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.07"
__pattern__ = r'http://(?:www\.)?datei\.to/datei/(?P<ID>\w+)\.html'
@@ -52,7 +52,7 @@ class DateiTo(SimpleHoster):
data = dict(x.split('=') for x in m.group(2).split('&'))
if url.endswith('recaptcha.php'):
- data['recaptcha_challenge_field'], data['recaptcha_response_field'] = recaptcha.challenge()
+ data['recaptcha_response_field'], data['recaptcha_challenge_field'] = recaptcha.challenge()
else:
self.fail(_("Too bad..."))
diff --git a/module/plugins/hoster/DepositfilesCom.py b/module/plugins/hoster/DepositfilesCom.py
index 9d060e75d..3af309cae 100644
--- a/module/plugins/hoster/DepositfilesCom.py
+++ b/module/plugins/hoster/DepositfilesCom.py
@@ -11,7 +11,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DepositfilesCom(SimpleHoster):
__name__ = "DepositfilesCom"
__type__ = "hoster"
- __version__ = "0.52"
+ __version__ = "0.53"
__pattern__ = r'https?://(?:www\.)?(depositfiles\.com|dfiles\.(eu|ru))(/\w{1,3})?/files/(?P<ID>\w+)'
@@ -77,7 +77,7 @@ class DepositfilesCom(SimpleHoster):
if '<input type=button value="Continue" onclick="check_recaptcha' in self.html:
if 'response' in params:
self.invalidCaptcha()
- params['challenge'], params['response'] = recaptcha.challenge(captcha_key)
+ params['response'], params['challenge'] = recaptcha.challenge(captcha_key)
self.logDebug(params)
continue
@@ -95,7 +95,7 @@ class DepositfilesCom(SimpleHoster):
try:
self.download(link, disposition=True)
- except:
+ except Exception:
self.retry(wait_time=60)
diff --git a/module/plugins/hoster/DlFreeFr.py b/module/plugins/hoster/DlFreeFr.py
index ec40b64ce..4776bf470 100644
--- a/module/plugins/hoster/DlFreeFr.py
+++ b/module/plugins/hoster/DlFreeFr.py
@@ -36,7 +36,7 @@ class CustomBrowser(Browser):
class DlFreeFr(SimpleHoster):
__name__ = "DlFreeFr"
__type__ = "hoster"
- __version__ = "0.27"
+ __version__ = "0.28"
__pattern__ = r'http://(?:www\.)?dl\.free\.fr/(\w+|getfile\.pl\?file=/\w+)'
@@ -92,7 +92,8 @@ class DlFreeFr(SimpleHoster):
action, inputs = self.parseHtmlForm('action="getfile.pl"')
adyoulike = AdYouLike(self)
- inputs.update(adyoulike.challenge())
+ response, challenge = adyoulike.challenge()
+ inputs.update(response)
self.load("http://dl.free.fr/getfile.pl", post=inputs)
headers = self.getLastHeaders()
diff --git a/module/plugins/hoster/EasybytezCom.py b/module/plugins/hoster/EasybytezCom.py
index cd54bdc70..693910c1b 100644
--- a/module/plugins/hoster/EasybytezCom.py
+++ b/module/plugins/hoster/EasybytezCom.py
@@ -16,8 +16,6 @@ class EasybytezCom(XFSHoster):
("stickell", "l.stickell@yahoo.it")]
- HOSTER_DOMAIN = "easybytez.com"
-
OFFLINE_PATTERN = r'>File not available'
LINK_PATTERN = r'(http://(\w+\.(easybytez|easyload|ezbytez|zingload)\.(com|to)|\d+\.\d+\.\d+\.\d+)/files/\d+/\w+/.+?)["\'<]'
diff --git a/module/plugins/hoster/ExashareCom.py b/module/plugins/hoster/ExashareCom.py
new file mode 100644
index 000000000..536c09b6d
--- /dev/null
+++ b/module/plugins/hoster/ExashareCom.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
+
+
+class ExashareCom(XFSHoster):
+ __name__ = "ExashareCom"
+ __type__ = "hoster"
+ __version__ = "0.01"
+
+ __pattern__ = r'http://(?:www\.)?exashare\.com/\w{12}'
+
+ __description__ = """Exashare.com hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ INFO_PATTERN = r'>(?P<NAME>.+?)<small>\( (?P<S>[\d.,]+) (?P<U>[\w^_]+)'
+ LINK_FREE_PATTERN = r'file: "(.+?)"'
+
+
+ def setup(self):
+ self.multiDL = True
+ self.chunkLimit = 1
+ self.resumeDownload = self.premium
+
+
+ def handleFree(self, pyfile):
+ m = re.search(self.LINK_FREE_PATTERN, self.html)
+ if m is None:
+ self.error(_("Free download link not found"))
+ else:
+ self.link = m.group(1)
+
+
+getInfo = create_getInfo(ExashareCom)
diff --git a/module/plugins/hoster/ExtabitCom.py b/module/plugins/hoster/ExtabitCom.py
index 5c2976a29..68695faad 100644
--- a/module/plugins/hoster/ExtabitCom.py
+++ b/module/plugins/hoster/ExtabitCom.py
@@ -11,7 +11,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, s
class ExtabitCom(SimpleHoster):
__name__ = "ExtabitCom"
__type__ = "hoster"
- __version__ = "0.64"
+ __version__ = "0.65"
__pattern__ = r'http://(?:www\.)?extabit\.com/(file|go|fid)/(?P<ID>\w+)'
@@ -50,7 +50,7 @@ class ExtabitCom(SimpleHoster):
for _i in xrange(5):
get_data = {"type": "recaptcha"}
- get_data['challenge'], get_data['capture'] = recaptcha.challenge(captcha_key)
+ get_data['capture'], get_data['challenge'] = recaptcha.challenge(captcha_key)
res = json_loads(self.load("http://extabit.com/file/%s/" % fileID, get=get_data))
if "ok" in res:
self.correctCaptcha()
diff --git a/module/plugins/hoster/FilecloudIo.py b/module/plugins/hoster/FilecloudIo.py
index bc328ddbd..fb1aea58f 100644
--- a/module/plugins/hoster/FilecloudIo.py
+++ b/module/plugins/hoster/FilecloudIo.py
@@ -10,7 +10,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilecloudIo(SimpleHoster):
__name__ = "FilecloudIo"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.08"
__pattern__ = r'http://(?:www\.)?(?:filecloud\.io|ifile\.it|mihd\.net)/(?P<ID>\w+)'
@@ -59,7 +59,7 @@ class FilecloudIo(SimpleHoster):
if captcha_key is None:
self.error(_("ReCaptcha key not found"))
- challenge, response = recaptcha.challenge(captcha_key)
+ response, challenge = recaptcha.challenge(captcha_key)
self.account.form_data = {"recaptcha_challenge_field": challenge,
"recaptcha_response_field" : response}
self.account.relogin(self.user)
@@ -78,7 +78,7 @@ class FilecloudIo(SimpleHoster):
data['ctype'] = "recaptcha"
for _i in xrange(5):
- data['recaptcha_challenge'], data['recaptcha_response'] = recaptcha.challenge(captcha_key)
+ data['recaptcha_response'], data['recaptcha_challenge'] = recaptcha.challenge(captcha_key)
json_url = "http://filecloud.io/download-request.json"
res = self.load(json_url, post=data)
diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py
index 2c8ec58f4..30c1b85ec 100644
--- a/module/plugins/hoster/FilefactoryCom.py
+++ b/module/plugins/hoster/FilefactoryCom.py
@@ -56,7 +56,7 @@ class FilefactoryCom(SimpleHoster):
m = re.search(self.WAIT_PATTERN, self.html)
if m:
- self.wait(int(m.group(1)))
+ self.wait(m.group(1))
self.download(dl_link, disposition=True)
diff --git a/module/plugins/hoster/FileomCom.py b/module/plugins/hoster/FileomCom.py
index 2b6fd34db..306953b84 100644
--- a/module/plugins/hoster/FileomCom.py
+++ b/module/plugins/hoster/FileomCom.py
@@ -18,8 +18,6 @@ class FileomCom(XFSHoster):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- HOSTER_DOMAIN = "fileom.com"
-
NAME_PATTERN = r'Filename: <span>(?P<N>.+?)<'
SIZE_PATTERN = r'File Size: <span class="size">(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
diff --git a/module/plugins/hoster/FilepostCom.py b/module/plugins/hoster/FilepostCom.py
index 4dd36c6e4..25def94e8 100644
--- a/module/plugins/hoster/FilepostCom.py
+++ b/module/plugins/hoster/FilepostCom.py
@@ -12,7 +12,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilepostCom(SimpleHoster):
__name__ = "FilepostCom"
__type__ = "hoster"
- __version__ = "0.32"
+ __version__ = "0.33"
__pattern__ = r'https?://(?:www\.)?(?:filepost\.com/files|fp\.io)/(?P<ID>[^/]+)'
@@ -74,7 +74,7 @@ class FilepostCom(SimpleHoster):
for i in xrange(5):
get_dict['JsHttpRequest'] = str(int(time() * 10000)) + '-xml'
if i:
- post_dict['recaptcha_challenge_field'], post_dict['recaptcha_response_field'] = recaptcha.challenge(
+ post_dict['recaptcha_response_field'], post_dict['recaptcha_challenge_field'] = recaptcha.challenge(
captcha_key)
self.logDebug(u"RECAPTCHA: %s : %s : %s" % (
captcha_key, post_dict['recaptcha_challenge_field'], post_dict['recaptcha_response_field']))
diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py
index a668a834b..c5007e945 100644
--- a/module/plugins/hoster/FilerNet.py
+++ b/module/plugins/hoster/FilerNet.py
@@ -16,7 +16,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilerNet(SimpleHoster):
__name__ = "FilerNet"
__type__ = "hoster"
- __version__ = "0.13"
+ __version__ = "0.16"
__pattern__ = r'https?://(?:www\.)?filer\.net/get/\w+'
@@ -53,30 +53,22 @@ class FilerNet(SimpleHoster):
if 'hash' not in inputs:
self.error(_("Unable to detect hash"))
- recaptcha = ReCaptcha(self)
-
- for _i in xrange(5):
- challenge, response = recaptcha.challenge()
-
- #@NOTE: Work-around for v0.4.9 just_header issue
- #@TODO: Check for v0.4.10
- self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0)
- self.load(pyfile.url, post={'recaptcha_challenge_field': challenge,
- 'recaptcha_response_field' : response,
- 'hash' : inputs['hash']})
- self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 1)
-
- if 'location' in self.req.http.header.lower():
- self.link = re.search(r'location: (\S+)', self.req.http.header, re.I).group(1)
- self.correctCaptcha()
- break
- else:
- self.invalidCaptcha()
-
-
- def downloadLink(self, link):
- if link and isinstance(link, basestring):
- self.download(urljoin("http://filer.net/", link), disposition=True)
+ recaptcha = ReCaptcha(self)
+ response, challenge = recaptcha.challenge()
+
+ #@NOTE: Work-around for v0.4.9 just_header issue
+ #@TODO: Check for v0.4.10
+ self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0)
+ self.load(pyfile.url, post={'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field' : response,
+ 'hash' : inputs['hash']})
+ self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 1)
+
+ if 'location' in self.req.http.header.lower():
+ self.link = re.search(r'location: (\S+)', self.req.http.header, re.I).group(1)
+ self.correctCaptcha()
+ else:
+ self.invalidCaptcha()
getInfo = create_getInfo(FilerNet)
diff --git a/module/plugins/hoster/FilerioCom.py b/module/plugins/hoster/FilerioCom.py
index db81f5b16..c6ebbd444 100644
--- a/module/plugins/hoster/FilerioCom.py
+++ b/module/plugins/hoster/FilerioCom.py
@@ -15,8 +15,6 @@ class FilerioCom(XFSHoster):
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
- HOSTER_DOMAIN = "filerio.in"
-
URL_REPLACEMENTS = [(r'filekeen\.com', "filerio.in")]
OFFLINE_PATTERN = r'>&quot;File Not Found|File has been removed'
diff --git a/module/plugins/hoster/FilesMailRu.py b/module/plugins/hoster/FilesMailRu.py
index 18fca7176..7bd099282 100644
--- a/module/plugins/hoster/FilesMailRu.py
+++ b/module/plugins/hoster/FilesMailRu.py
@@ -21,7 +21,7 @@ def getInfo(urls):
url_pattern = '<a href="(.+?)" onclick="return Act\(this\, \'dlink\'\, event\)">(.+?)</a>'
file_name = re.search(url_pattern, html).group(0).split(', event)">')[1].split('</a>')[0]
result.append((file_name, 0, 2, url))
- except:
+ except Exception:
pass
# status 1=OFFLINE, 2=OK, 3=UNKNOWN
diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py
index 515ec9029..6f316cea3 100644
--- a/module/plugins/hoster/FileserveCom.py
+++ b/module/plugins/hoster/FileserveCom.py
@@ -33,7 +33,7 @@ def checkFile(plugin, urls):
class FileserveCom(Hoster):
__name__ = "FileserveCom"
__type__ = "hoster"
- __version__ = "0.53"
+ __version__ = "0.54"
__pattern__ = r'http://(?:www\.)?fileserve\.com/file/(?P<ID>[^/]+)'
@@ -161,7 +161,7 @@ class FileserveCom(Hoster):
recaptcha = ReCaptcha(self)
for _i in xrange(5):
- challenge, response = recaptcha.challenge(captcha_key)
+ response, challenge = recaptcha.challenge(captcha_key)
res = json_loads(self.load(self.URLS[2],
post={'recaptcha_challenge_field' : challenge,
'recaptcha_response_field' : response,
diff --git a/module/plugins/hoster/FourSharedCom.py b/module/plugins/hoster/FourSharedCom.py
index 78aeece44..a3f53ac5e 100644
--- a/module/plugins/hoster/FourSharedCom.py
+++ b/module/plugins/hoster/FourSharedCom.py
@@ -53,7 +53,7 @@ class FourSharedCom(SimpleHoster):
m = re.search(self.ID_PATTERN, self.html)
res = self.load('http://www.4shared.com/web/d2/getFreeDownloadLimitInfo?fileId=%s' % m.group(1))
self.logDebug(res)
- except:
+ except Exception:
pass
self.wait(20)
diff --git a/module/plugins/hoster/FshareVn.py b/module/plugins/hoster/FshareVn.py
index 872511afc..4912974ad 100644
--- a/module/plugins/hoster/FshareVn.py
+++ b/module/plugins/hoster/FshareVn.py
@@ -25,7 +25,7 @@ def doubleDecode(m):
class FshareVn(SimpleHoster):
__name__ = "FshareVn"
__type__ = "hoster"
- __version__ = "0.19"
+ __version__ = "0.20"
__pattern__ = r'http://(?:www\.)?fshare\.vn/file/.+'
@@ -58,7 +58,7 @@ class FshareVn(SimpleHoster):
self.checkErrors()
action, inputs = self.parseHtmlForm('frm_download')
- self.url = urljoin(pyfile.url, action)
+ url = urljoin(pyfile.url, action)
if not inputs:
self.error(_("No FORM"))
@@ -69,7 +69,7 @@ class FshareVn(SimpleHoster):
if password:
self.logInfo(_("Password protected link, trying ") + password)
inputs['link_file_pwd_dl'] = password
- self.html = self.load(self.url, post=inputs, decode=True)
+ self.html = self.load(url, post=inputs, decode=True)
if 'name="link_file_pwd_dl"' in self.html:
self.fail(_("Incorrect password"))
@@ -77,7 +77,7 @@ class FshareVn(SimpleHoster):
self.fail(_("No password found"))
else:
- self.html = self.load(self.url, post=inputs, decode=True)
+ self.html = self.load(url, post=inputs, decode=True)
self.checkErrors()
@@ -87,11 +87,9 @@ class FshareVn(SimpleHoster):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.error(_("LINK_FREE_PATTERN not found"))
- self.url = m.group(1)
- self.logDebug("FREE DL URL: %s" % self.url)
-
+
+ self.link = m.group(1)
self.wait()
- self.download(self.url)
def checkErrors(self):
diff --git a/module/plugins/hoster/Ftp.py b/module/plugins/hoster/Ftp.py
index 8562778c4..22fc5f67a 100644
--- a/module/plugins/hoster/Ftp.py
+++ b/module/plugins/hoster/Ftp.py
@@ -35,7 +35,7 @@ class Ftp(Hoster):
pyfile.name = parsed_url.path.rpartition('/')[2]
try:
pyfile.name = unquote(str(pyfile.name)).decode('utf8')
- except:
+ except Exception:
pass
if not "@" in netloc:
diff --git a/module/plugins/hoster/HellshareCz.py b/module/plugins/hoster/HellshareCz.py
index 47b981dd7..05caf052d 100644
--- a/module/plugins/hoster/HellshareCz.py
+++ b/module/plugins/hoster/HellshareCz.py
@@ -8,7 +8,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class HellshareCz(SimpleHoster):
__name__ = "HellshareCz"
__type__ = "hoster"
- __version__ = "0.84"
+ __version__ = "0.85"
__pattern__ = r'http://(?:www\.)?hellshare\.(?:cz|com|sk|hu|pl)/[^?]*/\d+'
@@ -32,10 +32,4 @@ class HellshareCz(SimpleHoster):
self.chunkLimit = 1
- def downloadLink(self, link):
- if link and isinstance(link, basestring):
- self.correctCaptcha()
- self.download(urljoin("http://www.hellshare.com/", link), disposition=True)
-
-
getInfo = create_getInfo(HellshareCz)
diff --git a/module/plugins/hoster/HugefilesNet.py b/module/plugins/hoster/HugefilesNet.py
index f7221f8c5..b7e599a50 100644
--- a/module/plugins/hoster/HugefilesNet.py
+++ b/module/plugins/hoster/HugefilesNet.py
@@ -17,8 +17,6 @@ class HugefilesNet(XFSHoster):
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- HOSTER_DOMAIN = "hugefiles.net"
-
SIZE_PATTERN = r'File Size:</span>\s*<span[^>]*>(?P<S>[^<]+)</span></div>'
FORM_INPUTS_MAP = {'ctype': re.compile(r'\d+')}
diff --git a/module/plugins/hoster/HundredEightyUploadCom.py b/module/plugins/hoster/HundredEightyUploadCom.py
index 4fc96a2b1..32d36ddb9 100644
--- a/module/plugins/hoster/HundredEightyUploadCom.py
+++ b/module/plugins/hoster/HundredEightyUploadCom.py
@@ -15,7 +15,5 @@ class HundredEightyUploadCom(XFSHoster):
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- HOSTER_DOMAIN = "180upload.com"
-
getInfo = create_getInfo(HundredEightyUploadCom)
diff --git a/module/plugins/hoster/JunocloudMe.py b/module/plugins/hoster/JunocloudMe.py
index 56d6588fa..415d5e2d0 100644
--- a/module/plugins/hoster/JunocloudMe.py
+++ b/module/plugins/hoster/JunocloudMe.py
@@ -15,8 +15,6 @@ class JunocloudMe(XFSHoster):
__authors__ = [("guidobelix", "guidobelix@hotmail.it")]
- HOSTER_DOMAIN = "junocloud.me"
-
URL_REPLACEMENTS = [(r'//(www\.)?junocloud', "//dl3.junocloud")]
OFFLINE_PATTERN = r'>No such file with this filename<'
diff --git a/module/plugins/hoster/Keep2shareCc.py b/module/plugins/hoster/Keep2ShareCc.py
index 05b3c639d..34bc3de54 100644
--- a/module/plugins/hoster/Keep2shareCc.py
+++ b/module/plugins/hoster/Keep2ShareCc.py
@@ -2,7 +2,7 @@
import re
-from urlparse import urljoin, urlparse
+from urlparse import urljoin
from module.plugins.internal.CaptchaService import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
@@ -11,7 +11,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class Keep2ShareCc(SimpleHoster):
__name__ = "Keep2ShareCc"
__type__ = "hoster"
- __version__ = "0.19"
+ __version__ = "0.21"
__pattern__ = r'https?://(?:www\.)?(keep2share|k2s|keep2s)\.cc/file/(?P<ID>\w+)'
@@ -29,7 +29,8 @@ class Keep2ShareCc(SimpleHoster):
OFFLINE_PATTERN = r'File not found or deleted|Sorry, this file is blocked or deleted|Error 404'
TEMP_OFFLINE_PATTERN = r'Downloading blocked due to'
- LINK_FREE_PATTERN = LINK_PREMIUM_PATTERN = r'"([^"]+url.html?file=.+?)"|window\.location\.href = \'(.+?)\';'
+ LINK_FREE_PATTERN = r'"([^"]+url.html?file=.+?)"|window\.location\.href = \'(.+?)\';'
+ LINK_PREMIUM_PATTERN = r'window\.location\.href = \'(.+?)\';'
CAPTCHA_PATTERN = r'src="(/file/captcha\.html.+?)"'
@@ -64,9 +65,9 @@ class Keep2ShareCc(SimpleHoster):
self.info.pop('error', None)
- def handleFree(self):
+ def handleFree(self, pyfile):
self.fid = re.search(r'<input type="hidden" name="slow_id" value="([^"]+)">', self.html).group(1)
- self.html = self.load(self.pyfile.url, post={'yt0': '', 'slow_id': self.fid})
+ self.html = self.load(pyfile.url, post={'yt0': '', 'slow_id': self.fid})
self.checkErrors()
@@ -77,54 +78,37 @@ class Keep2ShareCc(SimpleHoster):
self.wait(30)
- self.html = self.load(self.pyfile.url, post={'uniqueId': self.fid, 'free': 1})
-
- self.checkErrors()
+ self.html = self.load(pyfile.url)
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
- self.error(_("LINK_FREE_PATTERN not found"))
+ self.error(_("Free download link not found"))
self.link = m.group(1)
def handleCaptcha(self):
recaptcha = ReCaptcha(self)
+ post_data = {'free' : 1,
+ 'freeDownloadRequest': 1,
+ 'uniqueId' : self.fid,
+ 'yt0' : ''}
- for _i in xrange(5):
- post_data = {'free' : 1,
- 'freeDownloadRequest': 1,
- 'uniqueId' : self.fid,
- 'yt0' : ''}
-
- m = re.search(self.CAPTCHA_PATTERN, self.html)
- if m:
- captcha_url = urljoin("http://k2s.cc/", m.group(1))
- post_data['CaptchaForm[code]'] = self.decryptCaptcha(captcha_url)
- else:
- challenge, response = recaptcha.challenge()
- post_data.update({'recaptcha_challenge_field': challenge,
- 'recaptcha_response_field' : response})
-
- self.html = self.load(self.pyfile.url, post=post_data)
-
- if 'recaptcha' not in self.html:
- self.correctCaptcha()
- break
- else:
- self.invalidCaptcha()
+ m = re.search(self.CAPTCHA_PATTERN, self.html)
+ if m:
+ captcha_url = urljoin("http://k2s.cc/", m.group(1))
+ post_data['CaptchaForm[code]'] = self.decryptCaptcha(captcha_url)
else:
- self.fail(_("All captcha attempts failed"))
-
+ response, challenge = recaptcha.challenge()
+ post_data.update({'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field' : response})
- def downloadLink(self, link):
- if not link or not isinstance(link, basestring):
- return
+ self.html = self.load(self.pyfile.url, post=post_data)
- link = self.directLink(self, link, self.resumeDownload)
-
- if link:
- self.download(urljoin("http://k2s.cc/", link), disposition=True)
+ if 'verification code is incorrect' not in self.html:
+ self.correctCaptcha()
+ else:
+ self.invalidCaptcha()
getInfo = create_getInfo(Keep2ShareCc)
diff --git a/module/plugins/hoster/KingfilesNet.py b/module/plugins/hoster/KingfilesNet.py
index a75ef5f3e..eb4d34cc2 100644
--- a/module/plugins/hoster/KingfilesNet.py
+++ b/module/plugins/hoster/KingfilesNet.py
@@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class KingfilesNet(SimpleHoster):
__name__ = "KingfilesNet"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.07"
__pattern__ = r'http://(?:www\.)?kingfiles\.net/(?P<ID>\w{12})'
@@ -46,7 +46,7 @@ class KingfilesNet(SimpleHoster):
self.html = self.load(pyfile.url, post=post_data, cookies=True, decode=True)
solvemedia = SolveMedia(self)
- challenge, response = solvemedia.challenge()
+ response, challenge = solvemedia.challenge()
# Make the downloadlink appear and load the file
m = re.search(self.RAND_ID_PATTERN, self.html)
diff --git a/module/plugins/hoster/LetitbitNet.py b/module/plugins/hoster/LetitbitNet.py
index 6d5641778..cd922aea7 100644
--- a/module/plugins/hoster/LetitbitNet.py
+++ b/module/plugins/hoster/LetitbitNet.py
@@ -36,7 +36,7 @@ def getInfo(urls):
class LetitbitNet(SimpleHoster):
__name__ = "LetitbitNet"
__type__ = "hoster"
- __version__ = "0.29"
+ __version__ = "0.30"
__pattern__ = r'https?://(?:www\.)?(letitbit|shareflare)\.net/download/.+'
@@ -96,7 +96,7 @@ class LetitbitNet(SimpleHoster):
self.logDebug(res)
recaptcha = ReCaptcha(self)
- challenge, response = recaptcha.challenge()
+ response, challenge = recaptcha.challenge()
post_data = {"recaptcha_challenge_field": challenge,
"recaptcha_response_field": response,
diff --git a/module/plugins/hoster/LoadTo.py b/module/plugins/hoster/LoadTo.py
index b21a69b5f..6f4e8d73c 100644
--- a/module/plugins/hoster/LoadTo.py
+++ b/module/plugins/hoster/LoadTo.py
@@ -13,7 +13,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class LoadTo(SimpleHoster):
__name__ = "LoadTo"
__type__ = "hoster"
- __version__ = "0.19"
+ __version__ = "0.20"
__pattern__ = r'http://(?:www\.)?load\.to/\w+'
@@ -49,7 +49,7 @@ class LoadTo(SimpleHoster):
# Set Timer - may be obsolete
m = re.search(self.WAIT_PATTERN, self.html)
if m:
- self.wait(int(m.group(1)))
+ self.wait(m.group(1))
# Load.to is using solvemedia captchas since ~july 2014:
solvemedia = SolveMedia(self)
@@ -58,7 +58,7 @@ class LoadTo(SimpleHoster):
if captcha_key is None:
self.download(download_url)
else:
- challenge, response = solvemedia.challenge(captcha_key)
+ response, challenge = solvemedia.challenge(captcha_key)
self.download(download_url, post={"adcopy_challenge": challenge, "adcopy_response": response})
diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py
index 09300a41a..74bf877f1 100644
--- a/module/plugins/hoster/LuckyShareNet.py
+++ b/module/plugins/hoster/LuckyShareNet.py
@@ -11,7 +11,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class LuckyShareNet(SimpleHoster):
__name__ = "LuckyShareNet"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
__pattern__ = r'https?://(?:www\.)?luckyshare\.net/(?P<ID>\d{10,})'
@@ -47,12 +47,12 @@ class LuckyShareNet(SimpleHoster):
self.logDebug("JSON: " + rep)
json = self.parseJson(rep)
- self.wait(int(json['time']))
+ self.wait(json['time'])
recaptcha = ReCaptcha(self)
for _i in xrange(5):
- challenge, response = recaptcha.challenge()
+ response, challenge = recaptcha.challenge()
rep = self.load(r"http://luckyshare.net/download/verify/challenge/%s/response/%s/hash/%s" %
(challenge, response, json['hash']), decode=True)
self.logDebug("JSON: " + rep)
diff --git a/module/plugins/hoster/MediafireCom.py b/module/plugins/hoster/MediafireCom.py
index 81bd36f73..bc81c8202 100644
--- a/module/plugins/hoster/MediafireCom.py
+++ b/module/plugins/hoster/MediafireCom.py
@@ -33,7 +33,7 @@ def checkHTMLHeader(url):
return url, 2
else:
break
- except:
+ except Exception:
return url, 3
else:
return url, 0
@@ -54,7 +54,7 @@ def getInfo(urls):
class MediafireCom(SimpleHoster):
__name__ = "MediafireCom"
__type__ = "hoster"
- __version__ = "0.83"
+ __version__ = "0.84"
__pattern__ = r'http://(?:www\.)?mediafire\.com/(file/|(view/?|download\.php)?\?)(\w{11}|\w{15})($|/)'
@@ -121,7 +121,7 @@ class MediafireCom(SimpleHoster):
def checkCaptcha(self):
solvemedia = SolveMedia(self)
- challenge, response = solvemedia.challenge()
+ response, challenge = solvemedia.challenge()
self.html = self.load(self.link,
post={'adcopy_challenge': challenge,
'adcopy_response' : response},
diff --git a/module/plugins/hoster/MegaCoNz.py b/module/plugins/hoster/MegaCoNz.py
index fbd34c563..4ad20b265 100644
--- a/module/plugins/hoster/MegaCoNz.py
+++ b/module/plugins/hoster/MegaCoNz.py
@@ -124,7 +124,7 @@ class MegaCoNz(Hoster):
df = open(file_decrypted, "wb")
except IOError, e:
- self.fail(str(e))
+ self.fail(e)
chunk_size = 2 ** 15 # buffer size, 32k
# file_mac = [0, 0, 0, 0] # calculate CBC-MAC for checksum
@@ -160,7 +160,7 @@ class MegaCoNz(Hoster):
# if file_mac[0] ^ file_mac[1], file_mac[2] ^ file_mac[3] != meta_mac:
# os.remove(file_decrypted)
- # self.fail("Checksum mismatch")
+ # self.fail(_("Checksum mismatch"))
os.remove(file_crypted)
self.lastDownload = fs_decode(file_decrypted)
diff --git a/module/plugins/hoster/MovReelCom.py b/module/plugins/hoster/MovReelCom.py
index 9bb63701c..9b8679c10 100644
--- a/module/plugins/hoster/MovReelCom.py
+++ b/module/plugins/hoster/MovReelCom.py
@@ -15,8 +15,6 @@ class MovReelCom(XFSHoster):
__authors__ = [("JorisV83", "jorisv83-pyload@yahoo.com")]
- HOSTER_DOMAIN = "movreel.com"
-
LINK_PATTERN = r'<a href="([^"]+)">Download Link'
diff --git a/module/plugins/hoster/MultihostersCom.py b/module/plugins/hoster/MultihostersCom.py
index c5a48310e..bcd7c6237 100644
--- a/module/plugins/hoster/MultihostersCom.py
+++ b/module/plugins/hoster/MultihostersCom.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
-from module.plugins.hosters.ZeveraCom import ZeveraCom
+from module.plugins.hoster.ZeveraCom import ZeveraCom
class MultihostersCom(ZeveraCom):
__name__ = "MultihostersCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
__pattern__ = r'https?://(?:www\.)multihosters\.com/(getFiles\.ashx|Members/download\.ashx)\?.*ourl=.+'
diff --git a/module/plugins/hoster/NetloadIn.py b/module/plugins/hoster/NetloadIn.py
index 35c814656..3efbdce23 100644
--- a/module/plugins/hoster/NetloadIn.py
+++ b/module/plugins/hoster/NetloadIn.py
@@ -23,7 +23,7 @@ def getInfo(urls):
for url in chunk:
match = id_regex.search(url)
if match:
- ids = ids + match.group(1) + ";"
+ ids = ids + match.group('ID') + ";"
api = getURL(apiurl,
get={'auth' : "Zf9SnQh9WiReEsb18akjvQGqT0I830e8",
@@ -62,9 +62,9 @@ def getInfo(urls):
class NetloadIn(Hoster):
__name__ = "NetloadIn"
__type__ = "hoster"
- __version__ = "0.47"
+ __version__ = "0.49"
- __pattern__ = r'https?://(?:[^/]*\.)?netload\.in/(?:datei(.*?)(?:\.htm|/)|index\.php?id=10&file_id=)'
+ __pattern__ = r'https?://(?:www\.)?netload\.in/(?P<PATH>datei|index\.php\?id=10&file_id=)(?P<ID>\w+)'
__description__ = """Netload.in hoster plugin"""
__license__ = "GPLv3"
@@ -73,6 +73,9 @@ class NetloadIn(Hoster):
("Gregy", "gregy@gregy.cz")]
+ RECAPTCHA_KEY = "6LcLJMQSAAAAAJzquPUPKNovIhbK6LpSqCjYrsR1"
+
+
def setup(self):
self.multiDL = self.resumeDownload = self.premium
@@ -118,7 +121,7 @@ class NetloadIn(Hoster):
if match:
#normalize url
- self.url = 'http://www.netload.in/datei%s.htm' % match.group(1)
+ self.url = 'http://www.netload.in/datei%s.htm' % match.group('ID')
self.logDebug("URL: %s" % self.url)
else:
self.api_data = False
@@ -126,7 +129,7 @@ class NetloadIn(Hoster):
apiurl = "http://api.netload.in/info.php"
html = self.load(apiurl, cookies=False,
- get={"file_id": match.group(1), "auth": "Zf9SnQh9WiReEsb18akjvQGqT0I830e8", "bz": "1",
+ get={"file_id": match.group('ID'), "auth": "Zf9SnQh9WiReEsb18akjvQGqT0I830e8", "bz": "1",
"md5": "1"}, decode=True).strip()
if not html and n <= 3:
self.setWait(2)
@@ -235,7 +238,7 @@ class NetloadIn(Hoster):
recaptcha = ReCaptcha(self)
for _i in xrange(5):
- challenge, response = recaptcha.challenge()
+ response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
response_page = self.load("http://www.netload.in/index.php?id=10",
post={'captcha_check' : '1',
@@ -254,7 +257,7 @@ class NetloadIn(Hoster):
download_url = self.get_file_url(response_page)
self.logDebug("Download URL after get_file: " + download_url)
if not download_url.startswith("http://"):
- self.error("download url: %s" % download_url)
+ self.error(_("Download url: %s") % download_url)
self.wait()
self.url = download_url
diff --git a/module/plugins/hoster/NitroflareCom.py b/module/plugins/hoster/NitroflareCom.py
index 2367493e5..e21d067b3 100644
--- a/module/plugins/hoster/NitroflareCom.py
+++ b/module/plugins/hoster/NitroflareCom.py
@@ -16,64 +16,86 @@ from module.plugins.internal.SimpleHoster import SimpleHoster
class NitroflareCom(SimpleHoster):
__name__ = "NitroflareCom"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.07"
__pattern__ = r'https?://(?:www\.)?nitroflare\.com/view/(?P<ID>[\w^_]+)'
__description__ = """Nitroflare.com hoster plugin"""
__license__ = "GPLv3"
- __authors__ = [("sahil", ""),
+ __authors__ = [("sahil", "sahilshekhawat01@gmail.com"),
("Walter Purcaro", "vuolter@gmail.com")]
-
# URL_REPLACEMENTS = [("http://", "https://")]
- LINK_FREE_PATTERN = r'(https?://[\w\\-]+\\.nitroflare\\.com/[^<>\"]*?)"'
+ 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/.+?)"'
+
+ RECAPTCHA_KEY = "6Lenx_USAAAAAF5L1pmTWvWcH73dipAEzNnmNLgy"
+
+ PREMIUM_ONLY_PATTERN = r'This file is available with Premium only'
+ WAIT_PATTERN = r'You have to wait .+?<'
+ ERROR_PATTERN = r'downloading is not possible'
+
+
+ def checkErrors(self):
+ if not self.html:
+ return
+
+ if not self.premium and re.search(self.PREMIUM_ONLY_PATTERN, self.html):
+ self.fail(_("Link require a premium account to be handled"))
+
+ elif hasattr(self, 'WAIT_PATTERN'):
+ m = re.search(self.WAIT_PATTERN, self.html)
+ if m:
+ wait_time = sum([int(v) * {"hr": 3600, "hour": 3600, "min": 60, "sec": 1}[u.lower()] for v, u in
+ re.findall(r'(\d+)\s*(hr|hour|min|sec)', m.group(0), re.I)])
+ self.wait(wait_time, wait_time > 300)
+ return
+
+ elif hasattr(self, 'ERROR_PATTERN'):
+ m = re.search(self.ERROR_PATTERN, self.html)
+ if m:
+ errmsg = self.info['error'] = m.group(1)
+ self.error(errmsg)
+
+ self.info.pop('error', None)
def handleFree(self, pyfile):
- file_info = self.load("https://nitroflare.com/api/getDownloadLink",
- get={'file': self.info['pattern']['ID']})
-
- self.logWarning(file_info[3:])
- file_info = json_loads(file_info[3:]) # removing non ascii characters
- if file_info['type'] == "success":
- result = file_info['result'] # already a dict
- if result['linkType'] == "free":
- delay = result['delay'] # Don't need the delay for free downloads
- captch_key = result['recaptchaPublic']
- filename = result['name']
- recaptcha = ReCaptcha(self)
- # try upto 3 times to solve reCaptcha
- for i in xrange(3):
- challenge, response = recaptcha.challenge(key=captch_key)
- res = self.load("https://nitroflare.com/ajax/freeDownload.php",
- post={"method": "fetchDownload",
- "recaptcha_challenge_field": challenge,
- "recaptcha_response_field": response})
- if self.handleCaptchaErrors(res):
- break
- if "The captcha wasn't entered correctly" or "You have to fill the captcha" in res:
- continue
- else:
- break
-
- if "The captcha wasn't entered correctly" or "You have to fill the captcha" in res:
- self.logError("Captcha Failed")
- self.offline()
- # Captcha failed
- else:
- self.logInfo("result of the captcha is")
- self.logInfo(res)
- # self.offline()
- download_link = re.search(self.DOWNLOAD_PATTERN, res)
- if download_link is None:
- print "downloasd link failed"
- # Download link failed
- else:
- self.download(download_link)
- else:
- print "link is invalid"
- self.offline()
- # Link is invalid
- # self.download()
+ # used here to load the cookies which will be required later
+ self.load(pyfile.url, post={'goToFreePage': ""})
+
+ self.html = self.load("http://nitroflare.com/ajax/freeDownload.php",
+ post={'method': "startTimer", 'fileId': self.info['pattern']['ID']})[4:]
+
+ self.checkErrors()
+
+ try:
+ js_file = self.load("http://nitroflare.com/js/downloadFree.js?v=1.0.1")
+ var_time = re.search("var time = (\\d+);", js_file)
+ wait_time = int(var_time.groups()[0])
+
+ except Exception:
+ wait_time = 60
+
+ self.wait(wait_time)
+
+ recaptcha = ReCaptcha(self)
+ response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
+
+ self.html = self.load("http://nitroflare.com/ajax/freeDownload.php",
+ post={'method' : "fetchDownload",
+ 'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field' : response})[3:]
+
+ self.logDebug(self.html)
+
+ if "The captcha wasn't entered correctly" in self.html:
+ return
+
+ if "You have to fill the captcha" in self.html:
+ return
+
+ self.link = re.search(self.LINK_FREE_PATTERN, self.html)
diff --git a/module/plugins/hoster/NoPremiumPl.py b/module/plugins/hoster/NoPremiumPl.py
index 361d48c2d..43ae8b3cc 100644
--- a/module/plugins/hoster/NoPremiumPl.py
+++ b/module/plugins/hoster/NoPremiumPl.py
@@ -83,14 +83,14 @@ class NoPremiumPl(MultiHoster):
# error code isn't yet added to plugin
self.fail(
parsed["errstring"]
- or "Unknown error (code: %s)" % parsed["errno"]
+ or _("Unknown error (code: %s)") % parsed["errno"]
)
if "sdownload" in parsed:
if parsed["sdownload"] == "1":
self.fail(
- "Download from %s is possible only using NoPremium.pl webiste \
- directly. Update this plugin." % parsed["hosting"])
+ _("Download from %s is possible only using NoPremium.pl website \
+ directly") % parsed["hosting"])
pyfile.name = parsed["filename"]
pyfile.size = parsed["filesize"]
diff --git a/module/plugins/hoster/NosuploadCom.py b/module/plugins/hoster/NosuploadCom.py
index 8a03d7090..aeedd54f6 100644
--- a/module/plugins/hoster/NosuploadCom.py
+++ b/module/plugins/hoster/NosuploadCom.py
@@ -17,8 +17,6 @@ class NosuploadCom(XFSHoster):
__authors__ = [("igel", "igelkun@myopera.com")]
- HOSTER_DOMAIN = "nosupload.com"
-
SIZE_PATTERN = r'<p><strong>Size:</strong> (?P<S>[\d.,]+) (?P<U>[\w^_]+)</p>'
LINK_PATTERN = r'<a class="select" href="(http://.+?)">Download</a>'
diff --git a/module/plugins/hoster/NovafileCom.py b/module/plugins/hoster/NovafileCom.py
index 9754ceed1..bdd66473b 100644
--- a/module/plugins/hoster/NovafileCom.py
+++ b/module/plugins/hoster/NovafileCom.py
@@ -20,8 +20,6 @@ class NovafileCom(XFSHoster):
("stickell", "l.stickell@yahoo.it")]
- HOSTER_DOMAIN = "novafile.com"
-
ERROR_PATTERN = r'class="alert[^"]*alert-separate"[^>]*>\s*(?:<p>)?(.*?)\s*</'
WAIT_PATTERN = r'<p>Please wait <span id="count"[^>]*>(\d+)</span> seconds</p>'
diff --git a/module/plugins/hoster/OboomCom.py b/module/plugins/hoster/OboomCom.py
index 588d8f64a..725763345 100644
--- a/module/plugins/hoster/OboomCom.py
+++ b/module/plugins/hoster/OboomCom.py
@@ -13,7 +13,7 @@ from module.plugins.internal.CaptchaService import ReCaptcha
class OboomCom(Hoster):
__name__ = "OboomCom"
__type__ = "hoster"
- __version__ = "0.30"
+ __version__ = "0.31"
__pattern__ = r'https?://(?:www\.)?oboom\.com/(#(id=|/)?)?(?P<ID>\w{8})'
@@ -74,7 +74,7 @@ class OboomCom(Hoster):
recaptcha = ReCaptcha(self)
for _i in xrange(5):
- challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY)
+ response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
apiUrl = "https://www.oboom.com/1.0/download/ticket"
params = {"recaptcha_challenge_field": challenge,
"recaptcha_response_field": response,
diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py
index f9c0dbe85..2e9e52813 100644
--- a/module/plugins/hoster/OneFichierCom.py
+++ b/module/plugins/hoster/OneFichierCom.py
@@ -8,7 +8,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class OneFichierCom(SimpleHoster):
__name__ = "OneFichierCom"
__type__ = "hoster"
- __version__ = "0.76"
+ __version__ = "0.77"
__pattern__ = r'https?://(?:www\.)?(?:(?P<ID1>\w+)\.)?(?P<HOST>1fichier\.com|alterupload\.com|cjoint\.net|d(es)?fichiers\.com|dl4free\.com|megadl\.fr|mesfichiers\.org|piecejointe\.net|pjointe\.com|tenvoi\.com)(?:/\?(?P<ID2>\w+))?'
@@ -54,7 +54,7 @@ class OneFichierCom(SimpleHoster):
def handlePremium(self, pyfile):
- return self.handleFree(pyfile)
+ self.download(pyfile.url, post={'dl': "Download", 'did': 0})
getInfo = create_getInfo(OneFichierCom)
diff --git a/module/plugins/hoster/PutdriveCom.py b/module/plugins/hoster/PutdriveCom.py
index 67732a4cd..7f4b7b6cc 100644
--- a/module/plugins/hoster/PutdriveCom.py
+++ b/module/plugins/hoster/PutdriveCom.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
-from module.plugins.hosters.ZeveraCom import ZeveraCom
+from module.plugins.hoster.ZeveraCom import ZeveraCom
class PutdriveCom(ZeveraCom):
__name__ = "PutdriveCom"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.02"
__pattern__ = r'https?://(?:www\.)putdrive\.com/(getFiles\.ashx|Members/download\.ashx)\?.*ourl=.+'
diff --git a/module/plugins/hoster/RapideoPl.py b/module/plugins/hoster/RapideoPl.py
index 2f7365e3b..85591f51f 100644
--- a/module/plugins/hoster/RapideoPl.py
+++ b/module/plugins/hoster/RapideoPl.py
@@ -83,14 +83,14 @@ class RapideoPl(MultiHoster):
# error code isn't yet added to plugin
self.fail(
parsed["errstring"]
- or "Unknown error (code: %s)" % parsed["errno"]
+ or _("Unknown error (code: %s)") % parsed["errno"]
)
if "sdownload" in parsed:
if parsed["sdownload"] == "1":
self.fail(
- "Download from %s is possible only using Rapideo.pl webiste \
- directly. Update this plugin." % parsed["hosting"])
+ _("Download from %s is possible only using Rapideo.pl website \
+ directly") % parsed["hosting"])
pyfile.name = parsed["filename"]
pyfile.size = parsed["filesize"]
diff --git a/module/plugins/hoster/RapidfileshareNet.py b/module/plugins/hoster/RapidfileshareNet.py
index 3473b1c7c..0bbaed57f 100644
--- a/module/plugins/hoster/RapidfileshareNet.py
+++ b/module/plugins/hoster/RapidfileshareNet.py
@@ -15,8 +15,6 @@ class RapidfileshareNet(XFSHoster):
__authors__ = [("guidobelix", "guidobelix@hotmail.it")]
- HOSTER_DOMAIN = "rapidfileshare.net"
-
NAME_PATTERN = r'<input type="hidden" name="fname" value="(?P<N>.+?)">'
SIZE_PATTERN = r'>http://www.rapidfileshare.net/\w+?</font> \((?P<S>[\d.,]+) (?P<U>[\w^_]+)\)</font>'
diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py
index 84c3b20d6..f7e6534f2 100644
--- a/module/plugins/hoster/RapidgatorNet.py
+++ b/module/plugins/hoster/RapidgatorNet.py
@@ -13,7 +13,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, s
class RapidgatorNet(SimpleHoster):
__name__ = "RapidgatorNet"
__type__ = "hoster"
- __version__ = "0.29"
+ __version__ = "0.31"
__pattern__ = r'http://(?:www\.)?(rapidgator\.net|rg\.to)/file/\w+'
@@ -46,7 +46,7 @@ class RapidgatorNet(SimpleHoster):
def setup(self):
if self.account:
- self.sid = self.account.getAccountInfo(self.user).get('SID', None)
+ self.sid = self.account.getAccountInfo(self.user).get('sid', None)
else:
self.sid = None
@@ -107,7 +107,7 @@ class RapidgatorNet(SimpleHoster):
jsvars.get('startTimerUrl', '/download/AjaxStartTimer'), jsvars['fid'])
jsvars.update(self.getJsonResponse(url))
- self.wait(int(jsvars.get('secs', 45)), False)
+ self.wait(jsvars.get('secs', 45), False)
url = "http://rapidgator.net%s?sid=%s" % (
jsvars.get('getDownloadUrl', '/download/AjaxGetDownload'), jsvars['sid'])
@@ -128,7 +128,7 @@ class RapidgatorNet(SimpleHoster):
break
else:
captcha, captcha_key = self.getCaptcha()
- challenge, response = captcha.challenge(captcha_key)
+ response, challenge = captcha.challenge(captcha_key)
self.html = self.load(url, post={'DownloadCaptchaForm[captcha]': "",
'adcopy_challenge' : challenge,
@@ -146,17 +146,17 @@ class RapidgatorNet(SimpleHoster):
m = re.search(self.ADSCAPTCHA_PATTERN, self.html)
if m:
captcha_key = m.group(1)
- captcha = AdsCaptcha(self)
+ captcha = AdsCaptcha(self)
else:
m = re.search(self.RECAPTCHA_PATTERN, self.html)
if m:
captcha_key = m.group(1)
- captcha = ReCaptcha(self)
+ captcha = ReCaptcha(self)
else:
m = re.search(self.SOLVEMEDIA_PATTERN, self.html)
if m:
captcha_key = m.group(1)
- captcha = SolveMedia(self)
+ captcha = SolveMedia(self)
else:
self.error(_("Captcha"))
diff --git a/module/plugins/hoster/RapiduNet.py b/module/plugins/hoster/RapiduNet.py
index 0c40d95b9..b6806e49b 100644
--- a/module/plugins/hoster/RapiduNet.py
+++ b/module/plugins/hoster/RapiduNet.py
@@ -13,7 +13,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class RapiduNet(SimpleHoster):
__name__ = "RapiduNet"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
__pattern__ = r'https?://(?:www\.)?rapidu\.net/(?P<ID>\d{10})'
@@ -59,7 +59,7 @@ class RapiduNet(SimpleHoster):
recaptcha = ReCaptcha(self)
for _i in xrange(10):
- challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY)
+ response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
jsvars = self.getJsonResponse("https://rapidu.net/ajax.php",
get={'a': "getCheckCaptcha"},
diff --git a/module/plugins/hoster/RarefileNet.py b/module/plugins/hoster/RarefileNet.py
index 2be952efe..a45e4ed4d 100644
--- a/module/plugins/hoster/RarefileNet.py
+++ b/module/plugins/hoster/RarefileNet.py
@@ -17,8 +17,6 @@ class RarefileNet(XFSHoster):
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
- HOSTER_DOMAIN = "rarefile.net"
-
LINK_PATTERN = r'<a href="(.+?)">\1</a>'
diff --git a/module/plugins/hoster/RemixshareCom.py b/module/plugins/hoster/RemixshareCom.py
index 11c9f3b0f..590f8daf5 100644
--- a/module/plugins/hoster/RemixshareCom.py
+++ b/module/plugins/hoster/RemixshareCom.py
@@ -54,7 +54,7 @@ class RemixshareCom(SimpleHoster):
seconds = re.search(self.WAIT_PATTERN, self.html)
if seconds:
self.logDebug("Wait " + seconds.group(1))
- self.wait(int(seconds.group(1)))
+ self.wait(seconds.group(1))
# Finally start downloading...
self.download(dl_url, disposition=True)
diff --git a/module/plugins/hoster/SafesharingEu.py b/module/plugins/hoster/SafesharingEu.py
index bb6e0f646..08612e413 100644
--- a/module/plugins/hoster/SafesharingEu.py
+++ b/module/plugins/hoster/SafesharingEu.py
@@ -15,8 +15,6 @@ class SafesharingEu(XFSHoster):
__authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")]
- HOSTER_DOMAIN = "safesharing.eu"
-
ERROR_PATTERN = r'(?:<div class="alert alert-danger">)(.+?)(?:</div>)'
diff --git a/module/plugins/hoster/SecureUploadEu.py b/module/plugins/hoster/SecureUploadEu.py
index 64e6456a9..6bfbce328 100644
--- a/module/plugins/hoster/SecureUploadEu.py
+++ b/module/plugins/hoster/SecureUploadEu.py
@@ -15,8 +15,6 @@ class SecureUploadEu(XFSHoster):
__authors__ = [("z00nx", "z00nx0@gmail.com")]
- HOSTER_DOMAIN = "secureupload.eu"
-
INFO_PATTERN = r'<h3>Downloading (?P<N>[^<]+) \((?P<S>[^<]+)\)</h3>'
diff --git a/module/plugins/hoster/Share4webCom.py b/module/plugins/hoster/Share4WebCom.py
index 7a276c1fe..7a276c1fe 100644
--- a/module/plugins/hoster/Share4webCom.py
+++ b/module/plugins/hoster/Share4WebCom.py
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index 636e5824d..6f49711b8 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -14,7 +14,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class ShareonlineBiz(SimpleHoster):
__name__ = "ShareonlineBiz"
__type__ = "hoster"
- __version__ = "0.47"
+ __version__ = "0.48"
__pattern__ = r'https?://(?:www\.)?(share-online\.biz|egoshare\.com)/(download\.php\?id=|dl/)(?P<ID>\w+)'
@@ -69,7 +69,7 @@ class ShareonlineBiz(SimpleHoster):
recaptcha = ReCaptcha(self)
for _i in xrange(5):
- challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY)
+ response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
m = re.search(r'var wait=(\d+);', self.html)
self.setWait(int(m.group(1)) if m else 30)
@@ -164,7 +164,7 @@ class ShareonlineBiz(SimpleHoster):
try:
self.logError(errmsg, re.search(self.ERROR_PATTERN, self.html).group(1))
- except:
+ except Exception:
self.logError("Unknown error occurred", errmsg)
if errmsg is "invalid":
diff --git a/module/plugins/hoster/SpeedyshareCom.py b/module/plugins/hoster/SpeedyshareCom.py
index 0acdb7647..f21b0a3a7 100644
--- a/module/plugins/hoster/SpeedyshareCom.py
+++ b/module/plugins/hoster/SpeedyshareCom.py
@@ -13,7 +13,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class SpeedyshareCom(SimpleHoster):
__name__ = "SpeedyshareCom"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
__pattern__ = r'https?://(?:www\.)?(speedyshare\.com|speedy\.sh)/\w+'
@@ -38,10 +38,7 @@ class SpeedyshareCom(SimpleHoster):
def handleFree(self, pyfile):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
- self.error(_("Download link not found"))
-
- dl_link = urljoin("http://www.speedyshare.com", m.group(1))
- self.download(dl_link, disposition=True)
+ self.link = m.group(1)
getInfo = create_getInfo(SpeedyshareCom)
diff --git a/module/plugins/hoster/StreamcloudEu.py b/module/plugins/hoster/StreamcloudEu.py
index b9d6d9ae6..54f430508 100644
--- a/module/plugins/hoster/StreamcloudEu.py
+++ b/module/plugins/hoster/StreamcloudEu.py
@@ -17,8 +17,6 @@ class StreamcloudEu(XFSHoster):
__authors__ = [("seoester", "seoester@googlemail.com")]
- HOSTER_DOMAIN = "streamcloud.eu"
-
WAIT_PATTERN = r'var count = (\d+)'
LINK_PATTERN = r'file: "(http://(stor|cdn)\d+\.streamcloud\.eu:?\d*/.*/video\.(mp4|flv))",'
diff --git a/module/plugins/hoster/TurbobitNet.py b/module/plugins/hoster/TurbobitNet.py
index ccca76018..03e18a9cd 100644
--- a/module/plugins/hoster/TurbobitNet.py
+++ b/module/plugins/hoster/TurbobitNet.py
@@ -17,7 +17,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, t
class TurbobitNet(SimpleHoster):
__name__ = "TurbobitNet"
__type__ = "hoster"
- __version__ = "0.17"
+ __version__ = "0.19"
__pattern__ = r'http://(?:www\.)?turbobit\.net/(?:download/free/)?(?P<ID>\w+)'
@@ -35,15 +35,15 @@ class TurbobitNet(SimpleHoster):
SIZE_PATTERN = r'class="file-size">(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
OFFLINE_PATTERN = r'<h2>File Not Found</h2>|html\(\'File (?:was )?not found'
- LINK_PATTERN = r'(/download/redirect/[^"\']+)'
+ LINK_FREE_PATTERN = LINK_PREMIUM_PATTERN = r'(/download/redirect/[^"\']+)'
LIMIT_WAIT_PATTERN = r'<div id=\'timeout\'>(\d+)<'
CAPTCHA_PATTERN = r'<img alt="Captcha" src="(.+?)"'
def handleFree(self, pyfile):
- self.url = "http://turbobit.net/download/free/%s" % self.info['pattern']['ID']
- self.html = self.load(self.url, ref=True, decode=True)
+ self.html = self.load("http://turbobit.net/download/free/%s" % self.info['pattern']['ID'],
+ decode=True)
rtUpdate = self.getRtUpdate()
@@ -51,14 +51,13 @@ class TurbobitNet(SimpleHoster):
self.req.http.c.setopt(HTTPHEADER, ["X-Requested-With: XMLHttpRequest"])
- self.url = self.getDownloadUrl(rtUpdate)
-
- self.wait()
- self.html = self.load(self.url)
+ self.html = self.load(self.getDownloadUrl(rtUpdate))
self.req.http.c.setopt(HTTPHEADER, ["X-Requested-With:"])
- self.downloadFile()
+ m = re.search(self.LINK_FREE_PATTERN, self.html)
+ if m:
+ self.link = m.group(1)
def solveCaptcha(self):
@@ -76,7 +75,7 @@ class TurbobitNet(SimpleHoster):
if inputs['captcha_type'] == 'recaptcha':
recaptcha = ReCaptcha(self)
- inputs['recaptcha_challenge_field'], inputs['recaptcha_response_field'] = recaptcha.challenge()
+ inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge()
else:
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m is None:
@@ -141,13 +140,17 @@ class TurbobitNet(SimpleHoster):
self.logDebug("URL", self.js.engine, out)
if out.startswith('/download/'):
return "http://turbobit.net%s" % out.strip()
+
except Exception, e:
self.logError(e)
else:
if self.retries >= 2:
# retry with updated js
self.delStorage("rtUpdate")
- self.retry()
+ else:
+ self.retry()
+
+ self.wait()
def decrypt(self, data):
@@ -161,17 +164,4 @@ class TurbobitNet(SimpleHoster):
return "%s GMT%+03d%02d" % (time.strftime("%a %b %d %Y %H:%M:%S", lt), -tz // 3600, tz % 3600)
- def handlePremium(self, pyfile):
- self.logDebug("Premium download as user %s" % self.user)
- self.downloadFile()
-
-
- def downloadFile(self):
- m = re.search(self.LINK_PATTERN, self.html)
- if m is None:
- self.error(_("Download link not found"))
- self.url = "http://turbobit.net" + m.group(1)
- self.download(self.url)
-
-
getInfo = create_getInfo(TurbobitNet)
diff --git a/module/plugins/hoster/TusfilesNet.py b/module/plugins/hoster/TusfilesNet.py
index 9d0a86fe9..9fdb6eae1 100644
--- a/module/plugins/hoster/TusfilesNet.py
+++ b/module/plugins/hoster/TusfilesNet.py
@@ -17,8 +17,6 @@ class TusfilesNet(XFSHoster):
("guidobelix", "guidobelix@hotmail.it")]
- HOSTER_DOMAIN = "tusfiles.net"
-
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'
diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py
index cadd51149..3552942ff 100644
--- a/module/plugins/hoster/UlozTo.py
+++ b/module/plugins/hoster/UlozTo.py
@@ -15,7 +15,7 @@ def convertDecimalPrefix(m):
class UlozTo(SimpleHoster):
__name__ = "UlozTo"
__type__ = "hoster"
- __version__ = "1.02"
+ __version__ = "1.04"
__pattern__ = r'http://(?:www\.)?(uloz\.to|ulozto\.(cz|sk|net)|bagruj\.cz|zachowajto\.pl)/(?:live/)?(?P<ID>\w+/[^/?]*)'
@@ -39,6 +39,7 @@ class UlozTo(SimpleHoster):
def setup(self):
+ self.chunkLimit = 16 if self.premium else 1
self.multiDL = self.premium
self.resumeDownload = True
@@ -55,7 +56,7 @@ class UlozTo(SimpleHoster):
self.error(_("TOKEN_PATTERN not found"))
token = m.group(1)
- self.html = self.load(pyfile.url, get={"do": "askAgeForm-submit"},
+ self.html = self.load(pyfile.url, get={'do': "askAgeForm-submit"},
post={"agree": "Confirm", "_token_": token}, cookies=True)
if self.PASSWD_PATTERN in self.html:
@@ -63,7 +64,7 @@ class UlozTo(SimpleHoster):
if password:
self.logInfo(_("Password protected link, trying ") + password)
- self.html = self.load(pyfile.url, get={"do": "passwordProtectedForm-submit"},
+ self.html = self.load(pyfile.url, get={'do': "passwordProtectedForm-submit"},
post={"password": password, "password_send": 'Send'}, cookies=True)
if self.PASSWD_PATTERN in self.html:
@@ -72,7 +73,7 @@ class UlozTo(SimpleHoster):
self.fail(_("No password found"))
if re.search(self.VIPLINK_PATTERN, self.html):
- self.html = self.load(pyfile.url, get={"disclaimer": "1"})
+ self.html = self.load(pyfile.url, get={'disclaimer': "1"})
self.getFileInfo()
@@ -104,7 +105,7 @@ class UlozTo(SimpleHoster):
# New version - better to get new parameters (like captcha reload) because of image url - since 6.12.2013
self.logDebug('Using "new" version')
- xapca = self.load("http://www.ulozto.net/reloadXapca.php", get={"rnd": str(int(time.time()))})
+ xapca = self.load("http://www.ulozto.net/reloadXapca.php", get={'rnd': str(int(time.time()))})
self.logDebug("xapca = " + str(xapca))
data = json_loads(xapca)
@@ -120,7 +121,7 @@ class UlozTo(SimpleHoster):
def handlePremium(self, pyfile):
- self.download(pyfile.url, get={'do': directDownload}, disposition=True)
+ self.download(pyfile.url, get={'do': "directDownload"}, disposition=True)
def doCheckDownload(self):
diff --git a/module/plugins/hoster/UnibytesCom.py b/module/plugins/hoster/UnibytesCom.py
index cd4e506c4..16b1f82ab 100644
--- a/module/plugins/hoster/UnibytesCom.py
+++ b/module/plugins/hoster/UnibytesCom.py
@@ -62,7 +62,7 @@ class UnibytesCom(SimpleHoster):
if last_step == 'timer':
m = re.search(self.WAIT_PATTERN, self.html)
- self.wait(int(m.group(1)) if m else 60, False)
+ self.wait(m.group(1) if m else 60, False)
elif last_step in ("captcha", "last"):
post_data['captcha'] = self.decryptCaptcha(urljoin(domain, "/captcha.jpg"))
diff --git a/module/plugins/hoster/UpleaCom.py b/module/plugins/hoster/UpleaCom.py
index 4ea4e345f..c544c1222 100644
--- a/module/plugins/hoster/UpleaCom.py
+++ b/module/plugins/hoster/UpleaCom.py
@@ -19,8 +19,6 @@ class UpleaCom(XFSHoster):
__authors__ = [("Redleon", None)]
- HOSTER_DOMAIN = "uplea.com"
-
NAME_PATTERN = r'class="agmd size18">(?P<N>.+?)<'
SIZE_PATTERN = r'size14">(?P<S>[\d.,]+) (?P<U>[\w^_])</span>'
@@ -41,13 +39,13 @@ class UpleaCom(XFSHoster):
def handleFree(self, pyfile):
m = re.search(self.STEP_PATTERN, self.html)
if m is None:
- self.error("STEP_PATTERN not found")
+ self.error(_("STEP_PATTERN not found"))
self.html = self.load(urljoin("http://uplea.com/", m.group(1)))
m = re.search(self.WAIT_PATTERN, self.html)
if m:
- self.wait(int(m.group(1)), True)
+ self.wait(m.group(1), True)
self.retry()
m = re.search(self.LINK_PATTERN, self.html)
diff --git a/module/plugins/hoster/UploadableCh.py b/module/plugins/hoster/UploadableCh.py
index e28944ab9..be4cb5b06 100644
--- a/module/plugins/hoster/UploadableCh.py
+++ b/module/plugins/hoster/UploadableCh.py
@@ -11,7 +11,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UploadableCh(SimpleHoster):
__name__ = "UploadableCh"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.07"
__pattern__ = r'http://(?:www\.)?uploadable\.ch/file/(?P<ID>\w+)'
@@ -46,7 +46,7 @@ class UploadableCh(SimpleHoster):
recaptcha = ReCaptcha(self)
- challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY)
+ response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
# Submit the captcha solution
self.load("http://www.uploadable.ch/checkReCaptcha.php",
diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py
index 833468a80..9aef13cde 100644
--- a/module/plugins/hoster/UploadedTo.py
+++ b/module/plugins/hoster/UploadedTo.py
@@ -9,237 +9,120 @@ import re
from time import sleep
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.utils import html_unescape, parseFileSize
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-key = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=".decode('base64')
-
-
-def getID(url):
- """ returns id from file url"""
- m = re.match(UploadedTo.__pattern__, url)
- return m.group('ID')
-
-
-def getAPIData(urls):
- post = {"apikey": key}
-
- idMap = {}
-
- for i, url in enumerate(urls):
- id = getID(url)
- post['id_%s' % i] = id
- idMap[id] = url
-
- for _i in xrange(5):
- api = unicode(getURL("http://uploaded.net/api/filemultiple", post=post, decode=False), 'iso-8859-1')
- if api != "can't find request":
- break
- else:
- sleep(3)
-
- result = {}
-
- if api:
- for line in api.splitlines():
- data = line.split(",", 4)
- if data[1] in idMap:
- result[data[1]] = (data[0], data[2], data[4], data[3], idMap[data[1]])
-
- return result
-
-
-def parseFileInfo(self, url='', html=''):
- if not html and hasattr(self, "html"):
- html = self.html
+class UploadedTo(SimpleHoster):
+ __name__ = "UploadedTo"
+ __type__ = "hoster"
+ __version__ = "0.78"
- name = url
- size = 0
- fileid = None
+ __pattern__ = r'https?://(?:www\.)?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)'
- if re.search(self.OFFLINE_PATTERN, html):
- # File offline
- status = 1
- else:
- m = re.search(self.INFO_PATTERN, html)
- if m:
- name, fileid = html_unescape(m.group('N')), m.group('ID')
- size = parseFileSize(m.group('S'))
- status = 2
- else:
- status = 3
+ __description__ = """Uploaded.net hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- return name, size, status, fileid
+ API_KEY = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=" #@NOTE: base64 encoded
-def getInfo(urls):
- for chunk in chunks(urls, 80):
- result = []
+ URL_REPLACEMENTS = [(__pattern__ + ".*", r'http://uploaded.net/file/\g<ID>')]
- api = getAPIData(chunk)
+ INFO_PATTERN = r'<a href="file/(?P<ID>\w+)" id="filename">(?P<N>[^<]+)</a> &nbsp;\s*<small[^>]*>(?P<S>[^<]+)</small>'
+ OFFLINE_PATTERN = r'<small class="cL">Error: 404'
- for data in api.itervalues():
- if data[0] == "online":
- result.append((html_unescape(data[2]), data[1], 2, data[4]))
+ LINK_PREMIUM_PATTERN = r'<div class="tfree".*\s*<form method="post" action="(.+?)"'
- elif data[0] == "offline":
- result.append((data[4], 0, 1, data[4]))
+ DL_LIMIT_ERROR = r'You have reached the max. number of possible free downloads for this hour'
- yield result
+ @classmethod
+ def apiInfo(cls, url="", get={}, post={}):
+ info = super(UploadedTo, cls).apiInfo(url)
-class UploadedTo(Hoster):
- __name__ = "UploadedTo"
- __type__ = "hoster"
- __version__ = "0.75"
+ for _i in xrange(5):
+ api = getURL("http://uploaded.net/api/filemultiple",
+ post={"apikey": cls.API_KEY.decode('base64'), 'id_0': re.match(cls.__pattern__, url).group('ID')},
+ decode=True)
+ if api != "can't find request":
+ api = api.splitlines()[0].split(",", 4)
- __pattern__ = r'https?://(?:www\.)?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)'
+ if api[0] == "online":
+ info.update({'name': api[4], 'size': api[2], 'status': 2})
- __description__ = """Uploaded.net hoster plugin"""
- __license__ = "GPLv3"
- __authors__ = [("spoob", "spoob@pyload.org"),
- ("mkaay", "mkaay@mkaay.de"),
- ("zoidberg", "zoidberg@mujmail.cz"),
- ("netpok", "netpok@gmail.com"),
- ("stickell", "l.stickell@yahoo.it")]
+ elif api[0] == "offline":
+ info['status'] = 1
+ break
+ else:
+ sleep(3)
- INFO_PATTERN = r'<a href="file/(?P<ID>\w+)" id="filename">(?P<N>[^<]+)</a> &nbsp;\s*<small[^>]*>(?P<S>[^<]+)</small>'
- OFFLINE_PATTERN = r'<small class="cL">Error: 404</small>'
- DL_LIMIT_PATTERN = r'You have reached the max. number of possible free downloads for this hour'
+ return info
def setup(self):
self.multiDL = self.resumeDownload = self.premium
self.chunkLimit = 1 # critical problems with more chunks
-
- self.fileID = getID(self.pyfile.url)
- self.pyfile.url = "http://uploaded.net/file/%s" % self.fileID
-
-
- def process(self, pyfile):
self.load("http://uploaded.net/language/en", just_header=True)
- api = getAPIData([pyfile.url])
- # TODO: fallback to parse from site, because api sometimes delivers wrong status codes
+ def checkErrors(self):
+ if 'var free_enabled = false;' in self.html:
+ self.logError(_("Free-download capacities exhausted"))
+ self.retry(24, 5 * 60)
- if not api:
- self.logWarning(_("No response for API call"))
+ m = re.search(r"Current waiting period: <span>(\d+)</span> seconds", self.html)
+ if m:
+ self.wait(m.group(1))
+ else:
+ self.fail(_("File not downloadable for free users"))
- self.html = unicode(self.load(pyfile.url, decode=False), 'iso-8859-1')
- name, size, status, self.fileID = parseFileInfo(self)
- self.logDebug(name, size, status, self.fileID)
- if status == 1:
- self.offline()
- elif status == 2:
- pyfile.name, pyfile.size = name, size
- else:
- self.error(_("file info"))
+ if "limit-size" in self.html:
+ self.fail(_("File too big for free download"))
- elif api == 'Access denied':
- self.fail(_("API key invalid"))
+ elif "limit-slot" in self.html: # Temporary restriction so just wait a bit
+ self.wait(30 * 60, True)
+ self.retry()
- else:
- if self.fileID not in api:
- self.offline()
+ elif "limit-parallel" in self.html:
+ self.fail(_("Cannot download in parallel"))
- self.data = api[self.fileID]
- if self.data[0] != "online":
- self.offline()
+ elif "limit-dl" in self.html or self.DL_LIMIT_ERROR in self.html: # limit-dl
+ self.wait(3 * 60 * 60, True)
+ self.retry()
- pyfile.name = html_unescape(self.data[2])
+ elif '"err":"captcha"' in self.html:
+ self.invalidCaptcha()
- # pyfile.name = self.get_file_name()
- if self.premium:
- self.handlePremium()
- else:
- self.handleFree()
-
-
- def handlePremium(self):
- info = self.account.getAccountInfo(self.user, True)
- self.logDebug("%(name)s: Use Premium Account (%(left)sGB left)" % {"name": self.__name__,
- "left": info['trafficleft'] / 1024 / 1024})
- if int(self.data[1]) / 1024 > info['trafficleft']:
- self.logInfo(_("Not enough traffic left"))
- self.account.empty(self.user)
- self.resetAccount()
- self.fail(_("Traffic exceeded"))
-
- header = self.load("http://uploaded.net/file/%s" % self.fileID, just_header=True)
- if 'location' in header:
- #Direct download
- self.logDebug("Direct download link detected")
- self.download(header['location'])
- else:
- #Indirect download
- self.html = self.load("http://uploaded.net/file/%s" % self.fileID)
- m = re.search(r'<div class="tfree".*\s*<form method="post" action="(.*?)"', self.html)
- if m is None:
- self.fail(_("Download URL not m. Try to enable direct downloads"))
- url = m.group(1)
- self.download(url, post={})
+ def handleFree(self, pyfile):
+ self.html = self.load("http://uploaded.net/js/download.js", decode=True)
+ recaptcha = ReCaptcha(self)
+ response, challenge = recaptcha.challenge()
- def handleFree(self):
- self.html = self.load(self.pyfile.url, decode=True)
+ self.html = self.load("http://uploaded.net/io/ticket/captcha/%s" % self.info['pattern']['ID'],
+ post={'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field' : response})
- if 'var free_enabled = false;' in self.html:
- self.logError(_("Free-download capacities exhausted"))
- self.retry(24, 5 * 60)
+ if "type:'download'" in self.html:
+ self.correctCaptcha()
+ try:
+ self.link = re.search("url:'([^']+)", self.html).group(1)
- m = re.search(r"Current waiting period: <span>(\d+)</span> seconds", self.html)
- if m is None:
- self.fail(_("File not downloadable for free users"))
- self.setWait(int(m.group(1)))
+ except Exception:
+ pass
- self.html = self.load("http://uploaded.net/js/download.js", decode=True)
+ self.checkErrors()
- url = "http://uploaded.net/io/ticket/captcha/%s" % self.fileID
- downloadURL = ""
- recaptcha = ReCaptcha(self)
+ def checkFile(self):
+ if self.checkDownload({'limit-dl': self.DL_LIMIT_ERROR}):
+ self.wait(3 * 60 * 60, True)
+ self.retry()
- for _i in xrange(5):
- challenge, response = recaptcha.challenge()
- options = {"recaptcha_challenge_field": challenge, "recaptcha_response_field": response}
- self.wait()
-
- result = self.load(url, post=options)
- self.logDebug("Result: %s" % result)
-
- if "limit-size" in result:
- self.fail(_("File too big for free download"))
- elif "limit-slot" in result: # Temporary restriction so just wait a bit
- self.setWait(30 * 60, True)
- self.wait()
- self.retry()
- elif "limit-parallel" in result:
- self.fail(_("Cannot download in parallel"))
- elif "limit-dl" in result or self.DL_LIMIT_PATTERN in result: # limit-dl
- self.setWait(3 * 60 * 60, True)
- self.wait()
- self.retry()
- elif '"err":"captcha"' in result:
- self.invalidCaptcha()
- elif "type:'download'" in result:
- self.correctCaptcha()
- downloadURL = re.search("url:'([^']+)", result).group(1)
- break
- else:
- self.error(_("Unknown error: %s") % result)
+ return super(UploadedTo, self).checkFile()
- if not downloadURL:
- self.fail(_("No Download url retrieved/all captcha attempts failed"))
- self.download(downloadURL, disposition=True)
- check = self.checkDownload({"limit-dl": self.DL_LIMIT_PATTERN})
- if check == "limit-dl":
- self.setWait(3 * 60 * 60, True)
- self.wait()
- self.retry()
+getInfo = create_getInfo(UploadedTo)
diff --git a/module/plugins/hoster/UpstoreNet.py b/module/plugins/hoster/UpstoreNet.py
index f287a2b51..db9fa53a1 100644
--- a/module/plugins/hoster/UpstoreNet.py
+++ b/module/plugins/hoster/UpstoreNet.py
@@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UpstoreNet(SimpleHoster):
__name__ = "UpstoreNet"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
__pattern__ = r'https?://(?:www\.)?upstore\.net/'
@@ -52,7 +52,7 @@ class UpstoreNet(SimpleHoster):
self.wait(wait_time)
# then, handle the captcha
- challenge, response = recaptcha.challenge()
+ response, challenge = recaptcha.challenge()
post_data.update({'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
diff --git a/module/plugins/hoster/UptoboxCom.py b/module/plugins/hoster/UptoboxCom.py
index 21d781f55..dedb6ed1f 100644
--- a/module/plugins/hoster/UptoboxCom.py
+++ b/module/plugins/hoster/UptoboxCom.py
@@ -15,8 +15,6 @@ class UptoboxCom(XFSHoster):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- HOSTER_DOMAIN = "uptobox.com"
-
INFO_PATTERN = r'"para_title">(?P<N>.+) \((?P<S>[\d.,]+) (?P<U>[\w^_]+)\)'
OFFLINE_PATTERN = r'>(File not found|Access Denied|404 Not Found)'
diff --git a/module/plugins/hoster/VidPlayNet.py b/module/plugins/hoster/VidPlayNet.py
index 76af05edd..f1a32a897 100644
--- a/module/plugins/hoster/VidPlayNet.py
+++ b/module/plugins/hoster/VidPlayNet.py
@@ -18,8 +18,6 @@ class VidPlayNet(XFSHoster):
__authors__ = [("t4skforce", "t4skforce1337[AT]gmail[DOT]com")]
- HOSTER_DOMAIN = "vidplay.net"
-
NAME_PATTERN = r'<b>Password:</b></div>\s*<h[1-6]>(?P<N>[^<]+)</h[1-6]>'
diff --git a/module/plugins/hoster/Vipleech4uCom.py b/module/plugins/hoster/Vipleech4UCom.py
index 2ae41b942..2ae41b942 100644
--- a/module/plugins/hoster/Vipleech4uCom.py
+++ b/module/plugins/hoster/Vipleech4UCom.py
diff --git a/module/plugins/hoster/WebshareCz.py b/module/plugins/hoster/WebshareCz.py
index e3424fc21..98187d46a 100644
--- a/module/plugins/hoster/WebshareCz.py
+++ b/module/plugins/hoster/WebshareCz.py
@@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class WebshareCz(SimpleHoster):
__name__ = "WebshareCz"
__type__ = "hoster"
- __version__ = "0.15"
+ __version__ = "0.16"
__pattern__ = r'https?://(?:www\.)?webshare\.cz/(?:#/)?file/(?P<ID>\w+)'
@@ -21,7 +21,7 @@ class WebshareCz(SimpleHoster):
@classmethod
def getInfo(cls, url="", html=""):
- info = super(WebshareCz, self).getInfo(url, html)
+ info = super(WebshareCz, cls).getInfo(url, html)
if url:
info['pattern'] = re.match(cls.__pattern__, url).groupdict()
diff --git a/module/plugins/hoster/YibaishiwuCom.py b/module/plugins/hoster/YibaishiwuCom.py
index adc403de4..cf1550ebc 100644
--- a/module/plugins/hoster/YibaishiwuCom.py
+++ b/module/plugins/hoster/YibaishiwuCom.py
@@ -50,7 +50,7 @@ class YibaishiwuCom(SimpleHoster):
self.logDebug("Trying URL: " + url)
self.download(url)
break
- except:
+ except Exception:
continue
else:
self.fail(_("No working link found"))
diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py
index 90c6df3c2..5c2489d3c 100644
--- a/module/plugins/hoster/YoutubeCom.py
+++ b/module/plugins/hoster/YoutubeCom.py
@@ -13,40 +13,36 @@ from module.utils import html_unescape
def which(program):
"""Works exactly like the unix command which
-
Courtesy of http://stackoverflow.com/a/377028/675646"""
- def is_exe(fpath):
- return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+ isExe = lambda x: os.path.isfile(x) and os.access(x, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
- if is_exe(program):
+ if isExe(program):
return program
else:
for path in os.environ['PATH'].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
- if is_exe(exe_file):
+ if isExe(exe_file):
return exe_file
- return None
-
class YoutubeCom(Hoster):
__name__ = "YoutubeCom"
__type__ = "hoster"
- __version__ = "0.40"
+ __version__ = "0.41"
- __pattern__ = r'https?://(?:[^/]*\.)?(?:youtube\.com|youtu\.be)/watch.*?[?&]v=.+'
- __config__ = [("quality", "sd;hd;fullhd;240p;360p;480p;720p;1080p;3072p", "Quality Setting", "hd"),
- ("fmt", "int", "FMT/ITAG Number (5-102, 0 for auto)", 0),
- (".mp4", "bool", "Allow .mp4", True),
- (".flv", "bool", "Allow .flv", True),
- (".webm", "bool", "Allow .webm", False),
- (".3gp", "bool", "Allow .3gp", False),
- ("3d", "bool", "Prefer 3D", False)]
+ __pattern__ = r'https?://(?:[^/]*\.)?(youtube\.com|youtu\.be)/watch\?(?:.*&)?v=.+'
+ __config__ = [("quality", "sd;hd;fullhd;240p;360p;480p;720p;1080p;3072p", "Quality Setting" , "hd" ),
+ ("fmt" , "int" , "FMT/ITAG Number (0 for auto)", 0 ),
+ (".mp4" , "bool" , "Allow .mp4" , True ),
+ (".flv" , "bool" , "Allow .flv" , True ),
+ (".webm" , "bool" , "Allow .webm" , False),
+ (".3gp" , "bool" , "Allow .3gp" , False),
+ ("3d" , "bool" , "Prefer 3D" , False)]
__description__ = """Youtube.com hoster plugin"""
__license__ = "GPLv3"
@@ -90,7 +86,7 @@ class YoutubeCom(Hoster):
def process(self, pyfile):
pyfile.url = replace_patterns(pyfile.url, self.URL_REPLACEMENTS)
- html = self.load(pyfile.url, decode=True)
+ html = self.load(pyfile.url, decode=True)
if re.search(r'<div id="player-unavailable" class="\s*player-width player-height\s*">', html):
self.offline()
@@ -100,32 +96,40 @@ class YoutubeCom(Hoster):
#get config
use3d = self.getConfig("3d")
+
if use3d:
quality = {"sd": 82, "hd": 84, "fullhd": 85, "240p": 83, "360p": 82,
"480p": 82, "720p": 84, "1080p": 85, "3072p": 85}
else:
quality = {"sd": 18, "hd": 22, "fullhd": 37, "240p": 5, "360p": 18,
"480p": 35, "720p": 22, "1080p": 37, "3072p": 38}
+
desired_fmt = self.getConfig("fmt")
- if desired_fmt and desired_fmt not in self.formats:
- self.logWarning(_("FMT %d unknown, using default") % desired_fmt)
- desired_fmt = 0
+
if not desired_fmt:
desired_fmt = quality.get(self.getConfig("quality"), 18)
+ elif desired_fmt not in self.formats:
+ self.logWarning(_("FMT %d unknown, using default") % desired_fmt)
+ desired_fmt = 0
+
#parse available streams
- streams = re.search(r'"url_encoded_fmt_stream_map": "(.*?)",', html).group(1)
+ streams = re.search(r'"url_encoded_fmt_stream_map":"(.+?)",', html).group(1)
streams = [x.split('\u0026') for x in streams.split(',')]
streams = [dict((y.split('=', 1)) for y in x) for x in streams]
streams = [(int(x['itag']), unquote(x['url'])) for x in streams]
- #self.logDebug("Found links: %s" % streams)
+
+ # self.logDebug("Found links: %s" % streams)
+
self.logDebug("AVAILABLE STREAMS: %s" % [x[0] for x in streams])
#build dictionary of supported itags (3D/2D)
allowed = lambda x: self.getConfig(self.formats[x][0])
streams = [x for x in streams if x[0] in self.formats and allowed(x[0])]
+
if not streams:
self.fail(_("No available stream meets your preferences"))
+
fmt_dict = dict([x for x in streams if self.formats[x[0]][4] == use3d] or streams)
self.logDebug("DESIRED STREAM: ITAG:%d (%s) %sfound, %sallowed" %
@@ -136,15 +140,18 @@ class YoutubeCom(Hoster):
if desired_fmt in fmt_dict and allowed(desired_fmt):
fmt = desired_fmt
else:
- sel = lambda x: self.formats[x][3] # select quality index
+ sel = lambda x: self.formats[x][3] # select quality index
comp = lambda x, y: abs(sel(x) - sel(y))
self.logDebug("Choosing nearest fmt: %s" % [(x, allowed(x), comp(x, desired_fmt)) for x in fmt_dict.keys()])
+
fmt = reduce(lambda x, y: x if comp(x, desired_fmt) <= comp(y, desired_fmt) and
sel(x) > sel(y) else y, fmt_dict.keys())
self.logDebug("Chosen fmt: %s" % fmt)
+
url = fmt_dict[fmt]
+
self.logDebug("URL: %s" % url)
#set file name
@@ -167,9 +174,9 @@ class YoutubeCom(Hoster):
m = "0"
pyfile.name += " (starting at %s:%s)" % (m, s)
- pyfile.name += file_suffix
- filename = self.download(url)
+ pyfile.name += file_suffix
+ filename = self.download(url)
if ffmpeg and time:
inputfile = filename + "_"
diff --git a/module/plugins/hoster/ZeveraCom.py b/module/plugins/hoster/ZeveraCom.py
index fb251142e..665b64789 100644
--- a/module/plugins/hoster/ZeveraCom.py
+++ b/module/plugins/hoster/ZeveraCom.py
@@ -10,7 +10,7 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class ZeveraCom(MultiHoster):
__name__ = "ZeveraCom"
__type__ = "hoster"
- __version__ = "0.27"
+ __version__ = "0.28"
__pattern__ = r'https?://(?:www\.)zevera\.com/(getFiles\.ashx|Members/download\.ashx)\?.*ourl=.+'
@@ -21,7 +21,7 @@ class ZeveraCom(MultiHoster):
def handlePremium(self, pyfile):
- return "https://%s/getFiles.ashx?ourl=%s" % (self.account.HOSTER_DOMAIN, pyfile.url)
+ self.link = "https://%s/getFiles.ashx?ourl=%s" % (self.account.HOSTER_DOMAIN, pyfile.url)
def checkFile(self):
diff --git a/module/plugins/hoster/ZippyshareCom.py b/module/plugins/hoster/ZippyshareCom.py
index 2648f532f..f32c5877f 100644
--- a/module/plugins/hoster/ZippyshareCom.py
+++ b/module/plugins/hoster/ZippyshareCom.py
@@ -2,42 +2,51 @@
import re
-from urlparse import urljoin
-
+from module.plugins.internal.CaptchaService import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class ZippyshareCom(SimpleHoster):
__name__ = "ZippyshareCom"
__type__ = "hoster"
- __version__ = "0.66"
+ __version__ = "0.68"
- __pattern__ = r'(?P<HOST>http://www\d{0,2}\.zippyshare\.com)/v(?:/|iew\.jsp.*key=)(?P<KEY>\d+)'
+ __pattern__ = r'http://www\d{0,2}\.zippyshare\.com/v(/|iew\.jsp.*key=)(?P<KEY>[\w^_]+)'
__description__ = """Zippyshare.com hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- NAME_PATTERN = r'("\d{6,}/"[ ]*\+.+?"/|<title>Zippyshare.com - )(?P<N>.+?)("|</title>)'
- SIZE_PATTERN = r'>Size:.+?">(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
+ COOKIES = [("zippyshare.com", "ziplocale", "en")]
- OFFLINE_PATTERN = r'>File does not exist on this server<'
+ NAME_PATTERN = r'("\d{6,}/"[ ]*\+.+?"/|<title>Zippyshare.com - )(?P<N>.+?)("|</title>)'
+ SIZE_PATTERN = r'>Size:.+?">(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
+ OFFLINE_PATTERN = r'>File does not exist on this server'
- COOKIES = [("zippyshare.com", "ziplocale", "en")]
+ LINK_PREMIUM_PATTERN = r'document.location = \'(.+?)\''
def setup(self):
- self.multiDL = True
self.chunkLimit = -1
+ self.multiDL = True
self.resumeDownload = True
def handleFree(self, pyfile):
- checksum = self.get_checksum()
- p_url = '/'.join(("d", self.info['pattern']['KEY'], str(checksum), self.pyfile.name))
+ recaptcha = ReCaptcha(self)
+ captcha_key = recaptcha.detect_key()
+
+ if captcha_key:
+ try:
+ self.link = re.search(self.LINK_PREMIUM_PATTERN, self.html)
+ recaptcha.challenge()
- self.link = urljoin(self.info['pattern']['HOST'], p_url)
+ except Exception, e:
+ self.error(e)
+
+ else:
+ self.link = '/'.join(("d", self.info['pattern']['KEY'], str(self.get_checksum()), self.pyfile.name))
def get_checksum(self):
@@ -51,8 +60,8 @@ class ZippyshareCom(SimpleHoster):
c1, c2 = map(int, re.search(r'\(\'downloadB\'\).omg\) \* \((\d+)%(\d+)', self.html).groups())
b = (a1 % a2) * (c1 % c2) + 18
- except Exception, e:
- self.error(_("Unable to calculate checksum"), e)
+ except Exception:
+ self.error(_("Unable to calculate checksum"))
else:
return b
diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py
index b429fd6e0..c6e83fe7d 100644
--- a/module/plugins/internal/CaptchaService.py
+++ b/module/plugins/internal/CaptchaService.py
@@ -1,24 +1,24 @@
# -*- coding: utf-8 -*-
import re
+import time
-from base64 import urlsafe_b64encode
-from random import random
+from base64 import b64encode
+from random import random, randint
+from urlparse import urljoin, urlparse
from module.common.json_layer import json_loads
class CaptchaService:
__name__ = "CaptchaService"
- __version__ = "0.16"
+ __version__ = "0.20"
__description__ = """Base captcha service plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- KEY_PATTERN = None
-
key = None #: last key detected
@@ -27,25 +27,10 @@ class CaptchaService:
def detect_key(self, html=None):
- if not html:
- if hasattr(self.plugin, "html") and self.plugin.html:
- html = self.plugin.html
- else:
- errmsg = _("%s html not found") % self.__name__
- self.plugin.fail(errmsg) #@TODO: replace all plugin.fail(errmsg) with plugin.error(errmsg) in 0.4.10
- raise TypeError(errmsg)
-
- m = re.search(self.KEY_PATTERN, html)
- if m:
- self.key = m.group(1).strip()
- self.plugin.logDebug("%s key: %s" % (self.__name__, self.key))
- return self.key
- else:
- self.plugin.logDebug("%s key not found" % self.__name__)
- return None
+ raise NotImplementedError
- def challenge(self, key=None):
+ def challenge(self, key=None, html=None):
raise NotImplementedError
@@ -55,15 +40,17 @@ class CaptchaService:
class ReCaptcha(CaptchaService):
__name__ = "ReCaptcha"
- __version__ = "0.09"
+ __version__ = "0.11"
__description__ = """ReCaptcha captcha service plugin"""
__license__ = "GPLv3"
- __authors__ = [("pyLoad Team", "admin@pyload.org")]
+ __authors__ = [("pyLoad Team", "admin@pyload.org"),
+ ("Walter Purcaro", "vuolter@gmail.com"),
+ ("zapp-brannigan", "fuerst.reinje@web.de")]
- KEY_PATTERN = r'(?:class="g-recaptcha"\s+data-sitekey="|recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=)([\w-]+)'
- KEY_AJAX_PATTERN = r'Recaptcha\.create\s*\(\s*["\']([\w-]+)'
+ KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)'
+ KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)'
def detect_key(self, html=None):
@@ -75,7 +62,7 @@ class ReCaptcha(CaptchaService):
self.plugin.fail(errmsg)
raise TypeError(errmsg)
- m = re.search(self.KEY_PATTERN, html) or re.search(self.KEY_AJAX_PATTERN, 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.plugin.logDebug("ReCaptcha key: %s" % self.key)
@@ -85,9 +72,24 @@ class ReCaptcha(CaptchaService):
return None
- def challenge(self, key=None, userverify=False):
+ def challenge(self, key=None, html=None, version=None):
+ if not html:
+ if hasattr(self.plugin, "html") and self.plugin.html:
+ html = self.plugin.html
+ else:
+ errmsg = _("ReCaptcha html not found")
+ self.plugin.fail(errmsg)
+ raise TypeError(errmsg)
+
+ challenge = "challenge_v%s" % (version if version in (1, 2) else
+ 2 if re.search(self.KEY_V2_PATTERN, html) else 1)
+
+ return getattr(self, challenge)(key, html)
+
+
+ def challenge_v1(self, key=None, html=None):
if not key:
- if self.detect_key():
+ if self.detect_key(html):
key = self.key
else:
errmsg = _("ReCaptcha key not found")
@@ -106,22 +108,7 @@ class ReCaptcha(CaptchaService):
self.plugin.logDebug("ReCaptcha challenge: %s" % challenge)
- response = challenge, self.result(server, challenge)
-
- return self.userverify(*response) if userverify else response
-
-
- def userverify(self, challenge, result):
- response = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify",
- post={'c' : challenge,
- 'response': urlsafe_b64encode('{"response":"%s"}' % result)})
- try:
- return re.search(r'"uvresp","(.+?)"', response).group(1)
-
- except AttributeError:
- errmsg = _("ReCaptcha userverify response not found")
- self.plugin.fail(errmsg)
- raise AttributeError(errmsg)
+ return self.result(server, challenge), challenge
def result(self, server, challenge):
@@ -136,9 +123,122 @@ class ReCaptcha(CaptchaService):
return result
+ def _collectApiInfo(self):
+ html = self.plugin.req.load("http://www.google.com/recaptcha/api.js")
+ a = re.search(r'po.src = \'(.*?)\';', html).group(1)
+ vers = a.split("/")[5]
+
+ self.plugin.logDebug("ReCaptcha API version: %s" %vers)
+
+ language = a.split("__")[1].split(".")[0]
+
+ self.plugin.logDebug("ReCaptcha 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.plugin.logDebug("ReCaptcha 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.plugin.logDebug("ReCaptcha time: %s" % millis)
+
+ rand = randint(1, 99999999)
+ a = "0.%s" % str(rand * 2147483647)
+ rpc = int(100000000 * float(a))
+
+ self.plugin.logDebug("ReCaptcha rpc-token: %s" % rpc)
+
+ return millis, rpc
+
+
+ def challenge_v2(self, key=None, html=None):
+ if not key:
+ if self.detect_key(html):
+ key = self.key
+ else:
+ errmsg = _("ReCaptcha key not found")
+ self.plugin.fail(errmsg)
+ raise TypeError(errmsg)
+
+ try:
+ parent = urljoin("http://", urlparse(self.plugin.pyfile.url).netloc)
+
+ except Exception:
+ parent = ""
+
+ botguardstring = "!A"
+ vers, language, jsh = self._collectApiInfo()
+ millis, rpc = self._prepareTimeAndRpc()
+
+ html = self.plugin.req.load("https://www.google.com/recaptcha/api2/anchor",
+ get={'k' : key,
+ 'hl' : language,
+ 'v' : vers,
+ 'usegapi' : "1",
+ 'jsh' : "%s#id=IO_%s" % (jsh, millis),
+ 'parent' : parent,
+ 'pfname' : "",
+ 'rpctoken': rpc})
+
+ token1 = re.search(r'id="recaptcha-token" value="(.*?)">', html)
+ self.plugin.logDebug("ReCaptcha 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,
+ 'usegapi': "1",
+ 'jsh' : jsh}).decode('unicode-escape')
+
+ token2 = re.search(r'"finput","(.*?)",', html)
+ self.plugin.logDebug("ReCaptcha token #2: %s" % token2.group(1))
+
+ token3 = re.search(r'."asconf".\s.\s,"(.*?)".', html)
+ self.plugin.logDebug("ReCaptcha token #3: %s" % token3.group(1))
+
+ html = self.plugin.req.load("https://www.google.com/recaptcha/api2/reload",
+ post={'c' : token2.group(1),
+ 'reason': "fi",
+ 'fbg' : token3.group(1)})
+
+ token4 = re.search(r'"rresp","(.*?)",', html)
+ self.plugin.logDebug("ReCaptcha token #4: %s" % token4.group(1))
+
+ millis_captcha_loading = int(round(time.time() * 1000))
+ captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload",
+ get={'c':token4.group(1)}, forceUser=True)
+ response = b64encode('{"response":"%s"}' % captcha_response)
+
+ self.plugin.logDebug("ReCaptcha result: %s" % response)
+
+ timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading
+ timeToSolveMore = timeToSolve + int(float("0." + str(randint(1, 99999999))) * 500)
+
+ html = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify",
+ post={'c' : token4.group(1),
+ 'response': response,
+ 't' : timeToSolve,
+ 'ct' : timeToSolveMore,
+ 'bg' : botguardstring})
+
+ token5 = re.search(r'"uvresp","(.*?)",', html)
+ self.plugin.logDebug("ReCaptcha token #5: %s" % token5.group(1))
+
+ return token5.group(1), None
+
+
class AdsCaptcha(CaptchaService):
__name__ = "AdsCaptcha"
- __version__ = "0.06"
+ __version__ = "0.07"
__description__ = """AdsCaptcha captcha service plugin"""
__license__ = "GPLv3"
@@ -169,9 +269,9 @@ class AdsCaptcha(CaptchaService):
return None
- def challenge(self, key=None):
+ def challenge(self, key=None, html=None):
if not key:
- if self.detect_key():
+ if self.detect_key(html):
key = self.key
else:
errmsg = _("AdsCaptcha key not found")
@@ -192,7 +292,7 @@ class AdsCaptcha(CaptchaService):
self.plugin.logDebug("AdsCaptcha challenge: %s" % challenge)
- return challenge, self.result(server, challenge)
+ return self.result(server, challenge), challenge
def result(self, server, challenge):
@@ -208,7 +308,7 @@ class AdsCaptcha(CaptchaService):
class SolveMedia(CaptchaService):
__name__ = "SolveMedia"
- __version__ = "0.06"
+ __version__ = "0.08"
__description__ = """SolveMedia captcha service plugin"""
__license__ = "GPLv3"
@@ -218,9 +318,28 @@ class SolveMedia(CaptchaService):
KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']'
- def challenge(self, key=None):
+ def detect_key(self, html=None):
+ if not html:
+ if hasattr(self.plugin, "html") and self.plugin.html:
+ html = self.plugin.html
+ else:
+ errmsg = _("SolveMedia html not found")
+ self.plugin.fail(errmsg)
+ raise TypeError(errmsg)
+
+ m = re.search(self.KEY_PATTERN, html)
+ if m:
+ self.key = m.group(1).strip()
+ self.plugin.logDebug("SolveMedia key: %s" % self.key)
+ return self.key
+ else:
+ self.plugin.logDebug("SolveMedia key not found")
+ return None
+
+
+ def challenge(self, key=None, html=None):
if not key:
- if self.detect_key():
+ if self.detect_key(html):
key = self.key
else:
errmsg = _("SolveMedia key not found")
@@ -240,7 +359,7 @@ class SolveMedia(CaptchaService):
self.plugin.logDebug("SolveMedia challenge: %s" % challenge)
- return challenge, self.result(server, challenge)
+ return self.result(server, challenge), challenge
def result(self, server, challenge):
@@ -253,7 +372,7 @@ class SolveMedia(CaptchaService):
class AdYouLike(CaptchaService):
__name__ = "AdYouLike"
- __version__ = "0.02"
+ __version__ = "0.04"
__description__ = """AdYouLike captcha service plugin"""
__license__ = "GPLv3"
@@ -284,9 +403,9 @@ class AdYouLike(CaptchaService):
return None
- def challenge(self, key=None):
+ def challenge(self, key=None, html=None):
if not key:
- if self.detect_key():
+ if self.detect_key(html):
key = self.key
else:
errmsg = _("AdYouLike key not found")
@@ -313,7 +432,7 @@ class AdYouLike(CaptchaService):
self.plugin.logDebug("AdYouLike challenge: %s" % challenge)
- return self.result(ayl, challenge)
+ return self.result(ayl, challenge), challenge
def result(self, server, challenge):
diff --git a/module/plugins/internal/DeadCrypter.py b/module/plugins/internal/DeadCrypter.py
index 0fa23eef3..866d177cf 100644
--- a/module/plugins/internal/DeadCrypter.py
+++ b/module/plugins/internal/DeadCrypter.py
@@ -1,8 +1,5 @@
# -*- coding: utf-8 -*-
-from urllib import unquote
-from urlparse import urlparse
-
from module.plugins.internal.SimpleCrypter import create_getInfo
from module.plugins.Crypter import Crypter as _Crypter
diff --git a/module/plugins/internal/DeadHoster.py b/module/plugins/internal/DeadHoster.py
index cc7adf4df..a6ad92607 100644
--- a/module/plugins/internal/DeadHoster.py
+++ b/module/plugins/internal/DeadHoster.py
@@ -1,8 +1,5 @@
# -*- coding: utf-8 -*-
-from urllib import unquote
-from urlparse import urlparse
-
from module.plugins.internal.SimpleHoster import create_getInfo
from module.plugins.Hoster import Hoster as _Hoster
diff --git a/module/plugins/internal/Extractor.py b/module/plugins/internal/Extractor.py
index 0b2462dac..ddf0f8a85 100644
--- a/module/plugins/internal/Extractor.py
+++ b/module/plugins/internal/Extractor.py
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
+import os
+
+from module.PyFile import PyFile
+from module.utils import fs_encode
+
+
class ArchiveError(Exception):
pass
@@ -14,7 +20,7 @@ class PasswordError(Exception):
class Extractor:
__name__ = "Extractor"
- __version__ = "0.13"
+ __version__ = "0.15"
__description__ = """Base extractor plugin"""
__license__ = "GPLv3"
@@ -26,6 +32,12 @@ class Extractor:
@classmethod
+ def isArchive(cls, filename):
+ name = os.path.basename(filename).lower()
+ return any(name.endswith(ext) for ext in cls.EXTENSIONS)
+
+
+ @classmethod
def checkDeps(cls):
""" Check if system statisfy dependencies
:return: boolean
@@ -34,46 +46,36 @@ class Extractor:
@classmethod
- def isArchive(cls, file):
- raise NotImplementedError
-
-
- @classmethod
def getTargets(cls, files_ids):
""" Filter suited targets from list of filename id tuple list
:param files_ids: List of filepathes
:return: List of targets, id tuple list
"""
- targets = []
-
- for file, id in files_ids:
- if cls.isArchive(file):
- targets.append((file, id))
-
- return targets
-
+ raise NotImplementedError
- def __init__(self, m, file, out, password, fullpath, overwrite, excludefiles, renice, delete, keepbroken):
- """Initialize extractor for specific file
- :param m: ExtractArchive Hook plugin
- :param file: Absolute filepath
- :param out: Absolute path to destination directory
- :param fullpath: extract to fullpath
- :param overwrite: Overwrite existing archives
- :param renice: Renice value
- """
- self.m = m
- self.file = file
- self.out = out
- self.password = password
- self.fullpath = fullpath
- self.overwrite = overwrite
- self.excludefiles = excludefiles
- self.renice = renice
- self.delete = delete
- self.keepbroken = keepbroken
- self.files = [] #: Store extracted files here
+ def __init__(self, manager, filename, out,
+ fullpath=True,
+ overwrite=False,
+ excludefiles=[],
+ renice=0,
+ delete=False,
+ keepbroken=False,
+ fid=None):
+ """ Initialize extractor for specific file """
+ self.manager = manager
+ self.target = fs_encode(filename)
+ self.out = out
+ self.fullpath = fullpath
+ self.overwrite = overwrite
+ self.excludefiles = excludefiles
+ self.renice = renice
+ self.delete = delete
+ self.keepbroken = keepbroken
+ self.files = [] #: Store extracted files here
+
+ pyfile = self.manager.core.files.getFile(fid) if fid else None
+ self.notifyProgress = lambda x: pyfile.setProgress(x) if pyfile else lambda x: None
def init(self):
@@ -81,44 +83,31 @@ class Extractor:
pass
- def verify(self):
+ def checkArchive(self):
"""Check if password if needed. Raise ArchiveError if integrity is
questionable.
+ :return: boolean
:raises ArchiveError
"""
- pass
+ return False
- def isPassword(self, password):
+ def checkPassword(self, password):
""" Check if the given password is/might be correct.
If it can not be decided at this point return true.
:param password:
:return: boolean
"""
- if isinstance(password, basestring):
- return True
- else:
- return False
-
-
- def setPassword(self, password):
- if self.isPassword(password):
- self.password = password
- return True
- else:
- return False
-
-
- def repair(self):
- return False
+ return True
- def extract(self, progress=lambda x: None):
+ def extract(self, password=None):
"""Extract the archive. Raise specific errors in case of failure.
:param progress: Progress function, call this to update status
+ :param password password to use
:raises PasswordError
:raises CRCError
:raises ArchiveError
@@ -132,7 +121,7 @@ class Extractor:
:return: List with paths of files to delete
"""
- raise NotImplementedError
+ return [self.target]
def getExtractedFiles(self):
diff --git a/module/plugins/internal/MultiHook.py b/module/plugins/internal/MultiHook.py
index 795565d73..652443098 100644
--- a/module/plugins/internal/MultiHook.py
+++ b/module/plugins/internal/MultiHook.py
@@ -11,7 +11,7 @@ from module.utils import decode, remove_chars
class MultiHook(Hook):
__name__ = "MultiHook"
__type__ = "hook"
- __version__ = "0.36"
+ __version__ = "0.37"
__config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
@@ -201,7 +201,7 @@ class MultiHook(Hook):
self.unloadPlugin(plugin)
if self.getConfig("reload", True):
- self.interval = max(self.getConfig("reloadinterval", 12), self.MIN_INTERVAL)
+ self.interval = max(self.getConfig("reloadinterval", 12) * 60 * 60, self.MIN_INTERVAL)
else:
self.core.scheduler.removeJob(self.cb)
self.cb = None
diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py
index ba613c997..ad5b6283e 100644
--- a/module/plugins/internal/MultiHoster.py
+++ b/module/plugins/internal/MultiHoster.py
@@ -8,7 +8,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, r
class MultiHoster(SimpleHoster):
__name__ = "MultiHoster"
__type__ = "hoster"
- __version__ = "0.33"
+ __version__ = "0.36"
__pattern__ = r'^unmatchable$'
@@ -27,9 +27,10 @@ class MultiHoster(SimpleHoster):
def prepare(self):
- self.info = {}
- self.link = "" #@TODO: Move to hoster class in 0.4.10
- self.directDL = False #@TODO: Move to hoster class in 0.4.10
+ self.info = {}
+ self.html = ""
+ self.link = "" #@TODO: Move to hoster class in 0.4.10
+ self.directDL = False #@TODO: Move to hoster class in 0.4.10
if self.LOGIN_ACCOUNT and not self.account:
self.fail(_("Required account not found"))
@@ -40,7 +41,7 @@ class MultiHoster(SimpleHoster):
set_cookies(self.req.cj, self.COOKIES)
if self.DIRECT_LINK is None:
- self.directDL = self.__pattern__ != r'^unmatchable$'
+ self.directDL = self.__pattern__ != r'^unmatchable$' and re.match(self.__pattern__, self.pyfile.url)
else:
self.directDL = self.DIRECT_LINK
@@ -51,10 +52,8 @@ class MultiHoster(SimpleHoster):
def process(self, pyfile):
self.prepare()
- if self.__pattern__ != r'^unmatchable$' and re.match(self.__pattern__, pyfile.url):
- self.checkInfo()
-
if self.directDL:
+ self.checkInfo()
self.logDebug("Looking for direct download link...")
self.handleDirect(pyfile)
@@ -72,17 +71,10 @@ class MultiHoster(SimpleHoster):
self.logDebug("Handled as free download")
self.handleFree(pyfile)
- self.downloadLink(self.link)
+ self.downloadLink(self.link, True)
self.checkFile()
- #@TODO: Remove in 0.4.10
- def downloadLink(self, link):
- if link and isinstance(link, basestring):
- self.correctCaptcha()
- self.download(link, disposition=True)
-
-
def handlePremium(self, pyfile):
return self.handleFree(pyfile)
diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py
new file mode 100644
index 000000000..508cf9c8d
--- /dev/null
+++ b/module/plugins/internal/SevenZip.py
@@ -0,0 +1,163 @@
+# -*- coding: utf-8 -*-
+
+import os
+import re
+
+from subprocess import Popen, PIPE
+
+from module.plugins.internal.UnRar import UnRar, renice
+from module.utils import save_join
+
+
+class SevenZip(UnRar):
+ __name__ = "SevenZip"
+ __version__ = "0.02"
+
+ __description__ = """7-Zip extractor plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Michael Nowak", ""),
+ ("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ CMD = "7z"
+
+ EXTENSIONS = [".7z", ".xz", ".zip", ".gz", ".gzip", ".tgz", ".bz2", ".bzip2",
+ ".tbz2", ".tbz", ".tar", ".wim", ".swm", ".lzma", ".rar", ".cab",
+ ".arj", ".z", ".taz", ".cpio", ".rpm", ".deb", ".lzh", ".lha",
+ ".chm", ".chw", ".hxs", ".iso", ".msi", ".doc", ".xls", ".ppt",
+ ".dmg", ".xar", ".hfs", ".exe", ".ntfs", ".fat", ".vhd", ".mbr",
+ ".squashfs", ".cramfs", ".scap"]
+
+
+ #@NOTE: there are some more uncovered 7z formats
+ re_filelist = re.compile(r'([\d\:]+)\s+([\d\:]+)\s+([\w\.]+)\s+(\d+)\s+(\d+)\s+(.+)')
+ re_wrongpwd = re.compile(r'(Can not open encrypted archive|Wrong password)', re.I)
+ re_wrongcrc = re.compile(r'Encrypted\s+\=\s+\+', re.I)
+
+
+ @classmethod
+ def checkDeps(cls):
+ if os.name == "nt":
+ cls.CMD = os.path.join(pypath, "7z.exe")
+ p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE)
+ p.communicate()
+ else:
+ p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE)
+ p.communicate()
+
+ return True
+
+
+ def checkArchive(self):
+ p = self.call_cmd("l", "-slt", self.target)
+ out, err = p.communicate()
+
+ if p.returncode > 1:
+ raise ArchiveError("Process terminated")
+
+ # check if output or error macthes the 'wrong password'-Regexp
+ if self.re_wrongpwd.search(out):
+ return True
+
+ # check if output matches 'Encrypted = +'
+ if self.re_wrongcrc.search(out):
+ return True
+
+ # check if archive is empty
+ self.files = self.list()
+ if not self.files:
+ raise ArchiveError("Empty Archive")
+
+ return False
+
+
+ def checkPassword(self, password):
+ p = self.call_cmd("l", self.target, password=password)
+ p.communicate()
+ return p.returncode == 0
+
+
+ def extract(self, password=None):
+ command = "x" if self.fullpath else "e"
+
+ p = self.call_cmd(command, '-o' + self.out, self.target, password=password)
+
+ renice(p.pid, self.renice)
+
+ progressstring = ""
+ while True:
+ c = p.stdout.read(1)
+ # quit loop on eof
+ if not c:
+ break
+ # reading a percentage sign -> set progress and restart
+ if c == '%':
+ self.notifyProgress(int(progressstring))
+ progressstring = ""
+ # not reading a digit -> therefore restart
+ elif c not in digits:
+ progressstring = ""
+ # add digit to progressstring
+ else:
+ progressstring += c
+
+ # retrieve stderr
+ err = p.stderr.read()
+
+ if self.re_wrongpwd.search(err):
+ raise PasswordError
+
+ elif self.re_wrongcrc.search(err):
+ raise CRCError
+
+ elif err.strip(): #: raise error if anything is on stderr
+ raise ArchiveError(err.strip())
+
+ if p.returncode > 1:
+ raise ArchiveError("Process terminated")
+
+ if not self.files:
+ self.files = self.list(password)
+
+
+ def list(self, password=None):
+ command = "l" if self.fullpath else "l"
+
+ p = self.call_cmd(command, self.target, password=password)
+ out, err = p.communicate()
+ code = p.returncode
+
+ if "Can not open" in err:
+ raise ArchiveError("Cannot open file")
+
+ if code != 0:
+ raise ArchiveError("Process terminated unsuccessful")
+
+ result = set()
+ for groups in self.re_filelist.findall(out):
+ f = groups[-1].strip()
+ result.add(save_join(self.out, f))
+
+ return list(result)
+
+
+ def call_cmd(self, command, *xargs, **kwargs):
+ args = []
+
+ #overwrite flag
+ if self.overwrite:
+ args.append("-y")
+
+ #set a password
+ if "password" in kwargs and kwargs["password"]:
+ args.append("-p%s" % kwargs["password"])
+ else:
+ args.append("-p-")
+
+ #@NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue
+ call = [self.cmd, command] + args + list(xargs)
+
+ self.manager.logDebug(" ".join([decode(arg) for arg in call]))
+
+ p = Popen(call, stdout=PIPE, stderr=PIPE)
+ return p
diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py
index d33ad77e9..b2622b5e0 100644
--- a/module/plugins/internal/SimpleCrypter.py
+++ b/module/plugins/internal/SimpleCrypter.py
@@ -12,7 +12,7 @@ from module.utils import fixup
class SimpleCrypter(Crypter, SimpleHoster):
__name__ = "SimpleCrypter"
__type__ = "crypter"
- __version__ = "0.39"
+ __version__ = "0.42"
__pattern__ = r'^unmatchable$'
__config__ = [("use_subfolder", "bool", "Save package to subfolder", True), #: Overrides core.config['general']['folder_per_package']
@@ -71,12 +71,12 @@ class SimpleCrypter(Crypter, SimpleHoster):
#@TODO: Remove in 0.4.10
def init(self):
account_name = (self.__name__ + ".py").replace("Folder.py", "").replace(".py", "")
- account = self.core.accountManager.getAccountPlugin(account_name)
+ account = self.pyfile.m.core.accountManager.getAccountPlugin(account_name)
if account and account.canUse():
self.user, data = account.selectAccount()
- self.req = account.getAccountRequest(self.user)
- self.premium = account.isPremium(self.user)
+ self.req = account.getAccountRequest(self.user)
+ self.premium = account.isPremium(self.user)
self.account = account
@@ -85,6 +85,7 @@ class SimpleCrypter(Crypter, SimpleHoster):
self.pyfile.error = "" #@TODO: Remove in 0.4.10
self.info = {}
+ self.html = ""
self.links = [] #@TODO: Move to hoster class in 0.4.10
if self.LOGIN_PREMIUM and not self.premium:
@@ -118,7 +119,7 @@ class SimpleCrypter(Crypter, SimpleHoster):
self.packages = [(self.info['name'], self.links, self.info['folder'])]
elif not self.urls and not self.packages: #@TODO: Remove in 0.4.10
- self.fail("No link grabbed")
+ self.fail(_("No link grabbed"))
def checkNameSize(self, getinfo=True):
@@ -151,17 +152,17 @@ class SimpleCrypter(Crypter, SimpleHoster):
Returns the links extracted from self.html
You should override this only if it's impossible to extract links using only the LINK_PATTERN.
"""
- parsed = urlparse(self.pyfile.url)
- base = "%s://%s" % (parsed.scheme, parsed.netloc)
+ url_p = urlparse(self.pyfile.url)
+ baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
- return [urljoin(base, link) if not urlparse(link).scheme else link \
- for link in re.finditer(self.LINK_PATTERN, self.html)]
+ return [urljoin(baseurl, link) if not urlparse(link).scheme else link \
+ for link in re.findall(self.LINK_PATTERN, self.html)]
def handlePages(self, pyfile):
try:
pages = int(re.search(self.PAGES_PATTERN, self.html).group(1))
- except:
+ except Exception:
pages = 1
for p in xrange(2, pages + 1):
diff --git a/module/plugins/internal/SimpleDereferer.py b/module/plugins/internal/SimpleDereferer.py
index 53b80f827..bd00f5d25 100644
--- a/module/plugins/internal/SimpleDereferer.py
+++ b/module/plugins/internal/SimpleDereferer.py
@@ -5,13 +5,13 @@ import re
from urllib import unquote
from module.plugins.Crypter import Crypter
-from module.plugins.internal.SimpleHoster import directLink, set_cookies
+from module.plugins.internal.SimpleHoster import fileUrl, set_cookies
class SimpleDereferer(Crypter):
__name__ = "SimpleDereferer"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.07"
__pattern__ = r'^unmatchable$'
__config__ = [("use_subfolder", "bool", "Save package to subfolder", True),
@@ -45,7 +45,7 @@ class SimpleDereferer(Crypter):
def decrypt(self, pyfile):
- link = directLink(self, pyfile.url)
+ link = fileUrl(self, pyfile.url)
if not link:
try:
@@ -54,10 +54,6 @@ class SimpleDereferer(Crypter):
except Exception:
self.prepare()
self.preload()
-
- if self.html is None:
- self.fail(_("No html retrieved"))
-
self.checkStatus()
link = self.getLink()
@@ -66,10 +62,13 @@ class SimpleDereferer(Crypter):
self.urls = [link.strip()] #@TODO: Remove `.strip()` in 0.4.10
elif not self.urls and not self.packages: #@TODO: Remove in 0.4.10
- self.fail("No link grabbed")
+ self.fail(_("No link grabbed"))
def prepare(self):
+ self.info = {}
+ self.html = ""
+
self.req.setOption("timeout", 120)
if isinstance(self.COOKIES, list):
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index 3f14ca711..c74e33d59 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
+import mimetypes
+import os
import re
from datetime import datetime, timedelta
from inspect import isclass
-from os.path import exists
from time import time
from urllib import unquote
from urlparse import urljoin, urlparse
@@ -107,7 +108,13 @@ def parseFileInfo(plugin, url="", html=""):
info = plugin.getInfo(url, html)
res = info['name'], info['size'], info['status'], info['url']
else:
- res = urlparse(unquote(url)).path.split('/')[-1] or _("Unknown"), 0, 3, url
+ url = unquote(url)
+ res = ((urlparse(url).path.split('/')[-1]
+ or urlparse(url).query.split('=', 1)[::-1][0].split('&', 1)[0]
+ or _("Unknown")),
+ 0,
+ 3 if url else 8,
+ url)
return res
@@ -133,37 +140,86 @@ def timestamp():
#@TODO: Move to hoster class in 0.4.10
-def directLink(self, url, resumable=False):
- link = ""
+def fileUrl(self, url, follow_location=None):
+ link = ""
+ redirect = 1
- for i in xrange(5 if resumable else 1):
- header = self.load(url, ref=True, cookies=True, just_header=True, decode=True)
+ if type(follow_location) is int:
+ redirect = max(follow_location, 1)
+ else:
+ redirect = 5
+
+ for i in xrange(redirect):
+ try:
+ self.logDebug("Redirect #%d to: %s" % (i, url))
+ header = self.load(url, ref=True, cookies=True, just_header=True, decode=True)
+
+ except Exception: #: Bad bad bad...
+ req = pyreq.getHTTPRequest()
+ res = req.load(url, cookies=True, just_header=True, decode=True)
+
+ req.close()
+
+ header = {"code": req.code}
+ for line in res.splitlines():
+ line = line.strip()
+ if not line or ":" not in line:
+ continue
+
+ key, none, value = line.partition(":")
+ key = key.lower().strip()
+ value = value.strip()
+
+ if key in header:
+ if type(header[key]) == list:
+ header[key].append(value)
+ else:
+ header[key] = [header[key], value]
+ else:
+ header[key] = value
if 'content-disposition' in header:
link = url
- elif 'location' in header and header['location']:
+ elif 'location' in header and header['location'].strip():
location = header['location']
if not urlparse(location).scheme:
- parsed = urlparse(url)
- base = "%s://%s" % (parsed.scheme, parsed.netloc)
- location = urljoin(base, location)
+ url_p = urlparse(url)
+ baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
+ location = urljoin(baseurl, location)
+
+ if 'code' in header and header['code'] == 302:
+ link = location
- if resumable:
+ if follow_location:
url = location
- self.logDebug("Redirect #%d to: %s" % (++i, location))
continue
- elif 'code' in header and header['code'] == 302:
- link = location
+ else:
+ extension = os.path.splitext(urlparse(url).path.split('/')[-1])[-1]
- elif 'content-type' in header and header['content-type'] and "html" not in header['content-type']:
- link = url
+ if 'content-type' in header and header['content-type'].strip():
+ mimetype = header['content-type'].split(';')[0].strip()
+
+ elif extension:
+ mimetype = mimetypes.guess_type(extension, False)[0] or "application/octet-stream"
+
+ else:
+ mimetype = ""
+
+ if mimetype and (link or 'html' not in mimetype):
+ link = url
+ else:
+ link = ""
break
+
else:
- self.logError(_("Too many redirects"))
+ try:
+ self.logError(_("Too many redirects"))
+ except Exception:
+ pass
return link
@@ -189,7 +245,7 @@ def secondsToMidnight(gmt=0):
class SimpleHoster(Hoster):
__name__ = "SimpleHoster"
__type__ = "hoster"
- __version__ = "0.98"
+ __version__ = "1.12"
__pattern__ = r'^unmatchable$'
@@ -253,7 +309,7 @@ class SimpleHoster(Hoster):
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
- directLink = directLink #@TODO: Remove in 0.4.10
+ directLink = fileUrl #@TODO: Remove in 0.4.10
@classmethod
@@ -277,7 +333,7 @@ class SimpleHoster(Hoster):
@classmethod
def getInfo(cls, url="", html=""):
info = cls.apiInfo(url)
- online = False
+ online = False if info['status'] != 2 else True
try:
info['pattern'] = re.match(cls.__pattern__, url).groupdict() #: pattern groups will be saved here
@@ -285,12 +341,12 @@ class SimpleHoster(Hoster):
except Exception:
info['pattern'] = {}
- if not html:
+ if not html and not online:
if not url:
info['error'] = "missing url"
info['status'] = 1
- elif info['status'] is 3:
+ elif info['status'] is 3 and not fileUrl(None, url):
try:
html = getURL(url, cookies=cls.COOKIES, decode=not cls.TEXT_ENCODING)
@@ -368,6 +424,7 @@ class SimpleHoster(Hoster):
self.pyfile.error = "" #@TODO: Remove in 0.4.10
self.info = {}
+ self.html = ""
self.link = "" #@TODO: Move to hoster class in 0.4.10
self.directDL = False #@TODO: Move to hoster class in 0.4.10
self.multihost = False #@TODO: Move to hoster class in 0.4.10
@@ -434,10 +491,16 @@ class SimpleHoster(Hoster):
self.checkFile()
- def downloadLink(self, link):
+ def downloadLink(self, link, disposition=False): #@TODO: Set `disposition=True` in 0.4.10
if link and isinstance(link, basestring):
self.correctCaptcha()
- self.download(link, disposition=False) #@TODO: Set `disposition=True` in 0.4.10
+
+ if not urlparse(link).scheme:
+ url_p = urlparse(self.pyfile.url)
+ baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
+ link = urljoin(baseurl, link)
+
+ self.download(link, ref=False, disposition=disposition)
def checkFile(self):
@@ -445,7 +508,7 @@ class SimpleHoster(Hoster):
self.invalidCaptcha()
self.retry(10, reason=_("Wrong captcha"))
- elif not self.lastDownload or not exists(fs_encode(self.lastDownload)):
+ elif not self.lastDownload or not os.path.exists(fs_encode(self.lastDownload)):
self.lastDownload = ""
self.error(self.pyfile.error or _("No file downloaded"))
@@ -472,7 +535,7 @@ class SimpleHoster(Hoster):
self.logWarning(_("No html code to check"))
return
- if hasattr(self, 'PREMIUM_ONLY_PATTERN') and self.premium and re.search(self.PREMIUM_ONLY_PATTERN, self.html):
+ if hasattr(self, 'PREMIUM_ONLY_PATTERN') and not self.premium and re.search(self.PREMIUM_ONLY_PATTERN, self.html):
self.fail(_("Link require a premium account to be handled"))
elif hasattr(self, 'ERROR_PATTERN'):
@@ -577,16 +640,12 @@ class SimpleHoster(Hoster):
if not hasattr(self, 'LINK_FREE_PATTERN'):
self.logError(_("Free download not implemented"))
- try:
- m = re.search(self.LINK_FREE_PATTERN, self.html)
- if m is None:
- self.error(_("Free download link not found"))
-
+ m = re.search(self.LINK_FREE_PATTERN, self.html)
+ if m is None:
+ self.error(_("Free download link not found"))
+ else:
self.link = m.group(1)
- except Exception, e:
- self.fail(e)
-
def handlePremium(self, pyfile):
if not hasattr(self, 'LINK_PREMIUM_PATTERN'):
@@ -594,16 +653,12 @@ class SimpleHoster(Hoster):
self.logDebug("Handled as free download")
self.handleFree(pyfile)
- try:
- m = re.search(self.LINK_PREMIUM_PATTERN, self.html)
- if m is None:
- self.error(_("Premium download link not found"))
-
+ m = re.search(self.LINK_PREMIUM_PATTERN, self.html)
+ if m is None:
+ self.error(_("Premium download link not found"))
+ else:
self.link = m.group(1)
- except Exception, e:
- self.fail(e)
-
def longWait(self, wait_time=None, max_tries=3):
if wait_time and isinstance(wait_time, (int, long, float)):
diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py
index 572fe95b9..7f1b08caf 100644
--- a/module/plugins/internal/UnRar.py
+++ b/module/plugins/internal/UnRar.py
@@ -4,7 +4,6 @@ import os
import re
from glob import glob
-from os.path import basename, dirname, join
from string import digits
from subprocess import Popen, PIPE
@@ -13,30 +12,31 @@ from module.utils import save_join, decode
def renice(pid, value):
- if os.name != "nt" and value:
+ if value and os.name != "nt":
try:
Popen(["renice", str(value), str(pid)], stdout=PIPE, stderr=PIPE, bufsize=-1)
- except:
- print "Renice failed"
+ except Exception:
+ pass
class UnRar(Extractor):
__name__ = "UnRar"
- __version__ = "1.01"
+ __version__ = "1.04"
__description__ = """Rar extractor plugin"""
__license__ = "GPLv3"
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+ __authors__ = [("RaNaN", "RaNaN@pyload.org"),
+ ("Walter Purcaro", "vuolter@gmail.com")]
CMD = "unrar"
- EXTENSIONS = ["rar", "zip", "cab", "arj", "lzh", "tar", "gz", "bz2", "ace", "uue", "jar", "iso", "7z", "xz", "z"]
-
+ EXTENSIONS = [".rar", ".zip", ".cab", ".arj", ".lzh", ".tar", ".gz", ".bz2",
+ ".ace", ".uue", ".jar", ".iso", ".7z", ".xz", ".z"]
#@NOTE: there are some more uncovered rar formats
- re_rarpart = re.compile(r'(.*)\.part(\d+)\.rar$', re.I)
- re_rarfile = re.compile(r'.*\.(rar|r\d+)$', re.I)
+ re_rarpart1 = re.compile(r'\.part(\d+)\.rar$', re.I)
+ re_rarpart2 = re.compile(r'\.r(\d+)$', re.I)
re_filelist = re.compile(r'(.+)\s+(\d+)\s+(\d+)\s+|(.+)\s+(\d+)\s+\d\d-\d\d-\d\d\s+\d\d:\d\d\s+(.+)')
re_wrongpwd = re.compile(r'password', re.I)
@@ -46,7 +46,7 @@ class UnRar(Extractor):
@classmethod
def checkDeps(cls):
if os.name == "nt":
- cls.CMD = join(pypath, "UnRAR.exe")
+ cls.CMD = os.path.join(pypath, "UnRAR.exe")
p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE)
p.communicate()
else:
@@ -54,8 +54,7 @@ class UnRar(Extractor):
p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE)
p.communicate()
- except OSError:
- # fallback to rar
+ except OSError: #: fallback to rar
cls.CMD = "rar"
p = Popen([cls.CMD], stdout=PIPE, stderr=PIPE)
p.communicate()
@@ -64,97 +63,50 @@ class UnRar(Extractor):
@classmethod
- def isArchive(cls, file):
- f = basename(file).lower()
- return any(f.endswith('.%s' % ext) for ext in cls.EXTENSIONS)
-
-
- @classmethod
def getTargets(cls, files_ids):
targets = []
- for file, id in files_ids:
- if not cls.isArchive(file):
+ for filename, id in files_ids:
+ if not cls.isArchive(filename):
continue
- m = cls.re_rarpart.findall(file)
- if m:
- # only add first parts
- if int(m[0][1]) == 1:
- targets.append((file, id))
- else:
- targets.append((file, id))
+ m = cls.re_rarpart1.match(filename)
+ if not m or int(m.group(1)) is 1: #@NOTE: only add first part file
+ targets.append((filename, id))
return targets
- def check(self, out="", err=""):
- if not out or not err:
- return
-
- if err.strip():
- if self.re_wrongpwd.search(err):
- raise PasswordError
-
- elif self.re_wrongcrc.search(err):
- raise CRCError
+ def checkArchive(self):
+ p = self.call_cmd("l", "-v", self.target)
+ out, err = p.communicate()
- else: #: raise error if anything is on stderr
- raise ArchiveError(err.strip())
+ if self.re_wrongpwd.search(err):
+ return True
# output only used to check if passworded files are present
for attr in self.re_filelist.findall(out):
if attr[0].startswith("*"):
- raise PasswordError
-
-
- def verify(self):
- p = self.call_cmd("l", "-v", self.file, password=self.password)
-
- self.check(*p.communicate())
-
- if p and p.returncode:
- raise ArchiveError("Process terminated")
-
- if not self.list():
- raise ArchiveError("Empty archive")
-
-
- def isPassword(self, password):
- if isinstance(password, basestring):
- p = self.call_cmd("l", "-v", self.file, password=password)
- out, err = p.communicate()
-
- if not self.re_wrongpwd.search(err):
return True
+ self.files = self.list()
+ if not self.files:
+ raise ArchiveError("Empty Archive")
+
return False
- def repair(self):
- p = self.call_cmd("rc", self.file)
+ def checkPassword(self, password):
+ # at this point we can only verify header protected files
+ p = self.call_cmd("l", "-v", self.target, password=password)
out, err = p.communicate()
+ return False if self.re_wrongpwd.search(err) else True
- if p.returncode or err.strip():
- p = self.call_cmd("r", self.file)
- out, err = p.communicate()
-
- if p.returncode or err.strip():
- return False
- else:
- self.file = join(dirname(self.file), re.search(r'(fixed|rebuild)\.%s' % basename(self.file), out).group(0))
-
- return True
-
-
- def extract(self, progress=lambda x: None):
- self.verify()
-
- progress(0)
+ def extract(self, password=None):
command = "x" if self.fullpath else "e"
- p = self.call_cmd(command, self.file, self.out, password=self.password)
+ p = self.call_cmd(command, self.target, self.out, password=password)
renice(p.pid, self.renice)
@@ -165,8 +117,8 @@ class UnRar(Extractor):
if not c:
break
# reading a percentage sign -> set progress and restart
- if c is '%':
- progress(int(progressstring))
+ if c == '%':
+ self.notifyProgress(int(progressstring))
progressstring = ""
# not reading a digit -> therefore restart
elif c not in digits:
@@ -175,44 +127,57 @@ class UnRar(Extractor):
else:
progressstring += c
- progress(100)
+ # retrieve stderr
+ err = p.stderr.read()
- self.files = self.list()
+ if self.re_wrongpwd.search(err):
+ raise PasswordError
- # retrieve stderr
- self.check(err=p.stderr.read())
+ elif self.re_wrongcrc.search(err):
+ raise CRCError
+
+ elif err.strip(): #: raise error if anything is on stderr
+ raise ArchiveError(err.strip())
- if p.returncode:
+ if p.returncode != 0:
raise ArchiveError("Process terminated")
+ if not self.files:
+ self.files = self.list(password)
+
def getDeleteFiles(self):
- if ".part" in basename(self.file):
- return glob(re.sub("(?<=\.part)([01]+)", "*", self.file, re.I))
+ files = []
- # get files which matches .r* and filter unsuited files out
- parts = glob(re.sub(r"(?<=\.r)ar$", "*", self.file, re.I))
+ for i in [1, 2]:
+ try:
+ dir, name = os.path.split(self.target)
+ part = self.getattr(self, "re_rarpart%d" % i).match(name).group(1)
+ filename = os.path.join(dir, name.replace(part, '*', 1))
+ files.extend(glob(filename))
- return filter(lambda x: self.re_rarfile.match(x), parts)
+ except Exception:
+ continue
+ if self.target not in files:
+ files.insert(0, self.target)
- def list(self):
+ return files
+
+
+ def list(self, password=None):
command = "vb" if self.fullpath else "lb"
- p = self.call_cmd(command, "-v", self.file, password=self.password)
+ p = self.call_cmd(command, "-v", self.target, password=password)
out, err = p.communicate()
- if err.strip():
- self.m.logError(err)
- if "Cannot open" in err:
- return list()
+ if "Cannot open" in err:
+ raise ArchiveError("Cannot open file")
- if p.returncode:
- self.m.logError("Process terminated")
- return list()
+ if err.strip(): #: only log error at this point
+ self.manager.logError(err.strip())
result = set()
-
for f in decode(out).splitlines():
f = f.strip()
result.add(save_join(self.out, f))
@@ -248,6 +213,8 @@ class UnRar(Extractor):
# NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue
call = [self.CMD, command] + args + list(xargs)
- self.m.logDebug(" ".join(call))
- return Popen(call, stdout=PIPE, stderr=PIPE)
+ self.manager.logDebug(" ".join(call))
+
+ p = Popen(call, stdout=PIPE, stderr=PIPE)
+ return p
diff --git a/module/plugins/internal/UnZip.py b/module/plugins/internal/UnZip.py
index 5ec56cbdf..026503be5 100644
--- a/module/plugins/internal/UnZip.py
+++ b/module/plugins/internal/UnZip.py
@@ -2,6 +2,7 @@
from __future__ import with_statement
+import os
import sys
import zipfile
@@ -10,14 +11,15 @@ from module.plugins.internal.Extractor import Extractor, ArchiveError, CRCError,
class UnZip(Extractor):
__name__ = "UnZip"
- __version__ = "1.01"
+ __version__ = "1.03"
__description__ = """Zip extractor plugin"""
__license__ = "GPLv3"
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+ __authors__ = [("RaNaN", "RaNaN@pyload.org"),
+ ("Walter Purcaro", "vuolter@gmail.com")]
- EXTENSIONS = ["zip", "zip64"]
+ EXTENSIONS = [".zip", ".zip64"]
@classmethod
@@ -26,61 +28,25 @@ class UnZip(Extractor):
@classmethod
- def isArchive(cls, file):
- return zipfile.is_zipfile(file)
+ def getTargets(cls, files_ids):
+ return [(filename, id) for filename, id in files_ids if cls.isArchive(filename)]
- def verify(self):
+ def extract(self, password=None):
try:
- with zipfile.ZipFile(self.file, 'r', allowZip64=True) as z:
+ with zipfile.ZipFile(self.target, 'r', allowZip64=True) as z:
z.setpassword(self.password)
- badcrc = z.testzip()
+ if not z.testzip():
+ z.extractall(self.out)
+ self.files = z.namelist()
+ else:
+ raise CRCError
except (BadZipfile, LargeZipFile), e:
raise ArchiveError(e)
except RuntimeError, e:
- if 'encrypted' in e:
+ if "encrypted" in e:
raise PasswordError
else:
raise ArchiveError(e)
-
- else:
- if badcrc:
- raise CRCError
-
- if not self.list():
- raise ArchiveError("Empty archive")
-
-
- def list(self):
- try:
- with zipfile.ZipFile(self.file, 'r', allowZip64=True) as z:
- z.setpassword(self.password)
- return z.namelist()
- except Exception:
- return list()
-
-
- def extract(self, progress=lambda x: None):
- try:
- with zipfile.ZipFile(self.file, 'r', allowZip64=True) as z:
- progress(0)
- z.extractall(self.out, pwd=self.password)
- progress(100)
-
- except (BadZipfile, LargeZipFile), e:
- raise ArchiveError(e)
-
- except RuntimeError, e:
- if e is "Bad password for file":
- raise PasswordError
- else:
- raise ArchiveError(e)
-
- finally:
- self.files = self.list()
-
-
- def getDeleteFiles(self):
- return [self.file]
diff --git a/module/plugins/internal/XFSAccount.py b/module/plugins/internal/XFSAccount.py
index c350729ac..c3bd91e52 100644
--- a/module/plugins/internal/XFSAccount.py
+++ b/module/plugins/internal/XFSAccount.py
@@ -23,7 +23,7 @@ class XFSAccount(Account):
HOSTER_DOMAIN = None
HOSTER_URL = None
- COOKIES = [(HOSTER_DOMAIN, "lang", "english")]
+ COOKIES = True
PREMIUM_PATTERN = r'\(Premium only\)'
@@ -46,9 +46,15 @@ class XFSAccount(Account):
def init(self):
if not self.HOSTER_DOMAIN:
self.logError(_("Missing HOSTER_DOMAIN"))
+ self.COOKIES = False
- if not self.HOSTER_URL:
- self.HOSTER_URL = "http://www.%s/" % (self.HOSTER_DOMAIN or "")
+ else:
+ if not self.HOSTER_URL:
+ self.HOSTER_URL = "http://www.%s/" % self.HOSTER_DOMAIN
+
+ if isinstance(self.COOKIES, list):
+ self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
+ set_cookies(req.cj, self.COOKIES)
def loadAccountInfo(self, user, req):
@@ -57,6 +63,12 @@ class XFSAccount(Account):
leechtraffic = None
premium = None
+ if not self.HOSTER_URL: #@TODO: Remove in 0.4.10
+ return {'validuntil' : validuntil,
+ 'trafficleft' : trafficleft,
+ 'leechtraffic': leechtraffic,
+ 'premium' : premium}
+
html = req.load(self.HOSTER_URL, get={'op': "my_account"}, decode=True)
premium = True if re.search(self.PREMIUM_PATTERN, html) else False
@@ -136,22 +148,25 @@ class XFSAccount(Account):
else:
self.logDebug("LEECH_TRAFFIC_PATTERN not found")
- return {'validuntil': validuntil, 'trafficleft': trafficleft, 'leechtraffic': leechtraffic, 'premium': premium}
+ return {'validuntil' : validuntil,
+ 'trafficleft' : trafficleft,
+ 'leechtraffic': leechtraffic,
+ 'premium' : premium}
def login(self, user, data, req):
- if isinstance(self.COOKIES, list):
- set_cookies(req.cj, self.COOKIES)
+ if not self.HOSTER_URL: #@TODO: Remove in 0.4.10
+ raise Exception(_("Missing HOSTER_DOMAIN"))
url = urljoin(self.HOSTER_URL, "login.html")
html = req.load(url, decode=True)
action, inputs = parseHtmlForm('name="FL"', html)
if not inputs:
- inputs = {'op': "login",
+ inputs = {'op' : "login",
'redirect': self.HOSTER_URL}
- inputs.update({'login': user,
+ inputs.update({'login' : user,
'password': data['password']})
html = req.load(self.HOSTER_URL, post=inputs, decode=True)
diff --git a/module/plugins/internal/XFSCrypter.py b/module/plugins/internal/XFSCrypter.py
index 3cb837aac..665e13b18 100644
--- a/module/plugins/internal/XFSCrypter.py
+++ b/module/plugins/internal/XFSCrypter.py
@@ -6,7 +6,7 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class XFSCrypter(SimpleCrypter):
__name__ = "XFSCrypter"
__type__ = "crypter"
- __version__ = "0.05"
+ __version__ = "0.06"
__pattern__ = r'^unmatchable$'
@@ -19,10 +19,27 @@ class XFSCrypter(SimpleCrypter):
URL_REPLACEMENTS = [(r'&?per_page=\d+', ""), (r'[?/&]+$', ""), (r'(.+/[^?]+)$', r'\1?'), (r'$', r'&per_page=10000')]
- COOKIES = [(HOSTER_DOMAIN, "lang", "english")]
-
LINK_PATTERN = r'<(?:td|TD).*?>\s*<a href="(.+?)".*?>.+?(?:</a>)?\s*</(?:td|TD)>'
NAME_PATTERN = r'<[tT]itle>.*?\: (?P<N>.+) folder</[tT]itle>'
OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed)'
TEMP_OFFLINE_PATTERN = r'>\s*\w+ server (is in )?(maintenance|maintainance)'
+
+
+ def prepare(self):
+ if not self.HOSTER_DOMAIN:
+ if self.account:
+ account = self.account
+ else:
+ account_name = (self.__name__ + ".py").replace("Folder.py", "").replace(".py", "")
+ account = self.pyfile.m.core.accountManager.getAccountPlugin(account_name)
+
+ if account and hasattr(account, "HOSTER_DOMAIN") and account.HOSTER_DOMAIN:
+ self.HOSTER_DOMAIN = account.HOSTER_DOMAIN
+ else:
+ self.fail(_("Missing HOSTER_DOMAIN"))
+
+ if isinstance(self.COOKIES, list):
+ self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
+
+ return super(XFSCrypter, self).prepare()
diff --git a/module/plugins/internal/XFSHoster.py b/module/plugins/internal/XFSHoster.py
index b32f5978f..2054b1824 100644
--- a/module/plugins/internal/XFSHoster.py
+++ b/module/plugins/internal/XFSHoster.py
@@ -4,6 +4,7 @@ import re
from random import random
from time import sleep
+from urlparse import urljoin, urlparse
from pycurl import FOLLOWLOCATION, LOW_SPEED_TIME
@@ -15,7 +16,7 @@ from module.utils import html_unescape
class XFSHoster(SimpleHoster):
__name__ = "XFSHoster"
__type__ = "hoster"
- __version__ = "0.35"
+ __version__ = "0.41"
__pattern__ = r'^unmatchable$'
@@ -29,7 +30,6 @@ class XFSHoster(SimpleHoster):
HOSTER_DOMAIN = None
TEXT_ENCODING = False
- COOKIES = [(HOSTER_DOMAIN, "lang", "english")]
DIRECT_LINK = None
MULTI_HOSTER = True #@NOTE: Should be default to False for safe, but I'm lazy...
@@ -56,17 +56,28 @@ class XFSHoster(SimpleHoster):
def setup(self):
- self.chunkLimit = 1
+ self.chunkLimit = -1 if self.premium else 1
self.resumeDownload = self.multiDL = self.premium
def prepare(self):
""" Initialize important variables """
if not self.HOSTER_DOMAIN:
- self.fail(_("Missing HOSTER_DOMAIN"))
+ if self.account:
+ account = self.account
+ else:
+ account = self.pyfile.m.core.accountManager.getAccountPlugin(self.__name__)
+
+ if account and hasattr(account, "HOSTER_DOMAIN") and account.HOSTER_DOMAIN:
+ self.HOSTER_DOMAIN = account.HOSTER_DOMAIN
+ else:
+ self.fail(_("Missing HOSTER_DOMAIN"))
+
+ if isinstance(self.COOKIES, list):
+ self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
if not self.LINK_PATTERN:
- pattern = r'(https?://(www\.)?([^/]*?%s|\d+\.\d+\.\d+\.\d+)(\:\d+)?(/d/|(/files)?/\d+/\w+/).+?)["\'<]'
+ pattern = r'(https?://(?:www\.)?([^/]*?%s|\d+\.\d+\.\d+\.\d+)(\:\d+)?(/d/|(/files)?/\d+/\w+/).+?)["\'<]'
self.LINK_PATTERN = pattern % self.HOSTER_DOMAIN.replace('.', '\.')
self.captcha = None
@@ -75,15 +86,19 @@ class XFSHoster(SimpleHoster):
super(XFSHoster, self).prepare()
if self.DIRECT_LINK is None:
- self.directDL = bool(self.premium)
+ self.directDL = self.premium
- def downloadLink(self, link):
+ def downloadLink(self, link, disposition=False): #@TODO: Set `disposition=True` in 0.4.10
if link and isinstance(link, basestring):
- if self.captcha:
- self.correctCaptcha()
+ self.correctCaptcha()
+
+ if not urlparse(link).scheme:
+ url_p = urlparse(self.pyfile.url)
+ baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
+ link = urljoin(baseurl, link)
- self.download(link, ref=True, cookies=True, disposition=False) #@TODO: Set `disposition=True` in 0.4.10
+ self.download(link, ref=False, disposition=disposition)
elif self.errmsg:
if 'captcha' in self.errmsg:
@@ -311,25 +326,25 @@ class XFSHoster(SimpleHoster):
recaptcha = ReCaptcha(self)
try:
captcha_key = re.search(self.RECAPTCHA_PATTERN, self.html).group(1)
- except:
+ except Exception:
captcha_key = recaptcha.detect_key()
else:
self.logDebug("ReCaptcha key: %s" % captcha_key)
if captcha_key:
- inputs['recaptcha_challenge_field'], inputs['recaptcha_response_field'] = recaptcha.challenge(captcha_key)
+ inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge(captcha_key)
return 3
solvemedia = SolveMedia(self)
try:
captcha_key = re.search(self.SOLVEMEDIA_PATTERN, self.html).group(1)
- except:
+ except Exception:
captcha_key = solvemedia.detect_key()
else:
self.logDebug("SolveMedia key: %s" % captcha_key)
if captcha_key:
- inputs['adcopy_challenge'], inputs['adcopy_response'] = solvemedia.challenge(captcha_key)
+ inputs['adcopy_response'], inputs['adcopy_challenge'] = solvemedia.challenge(captcha_key)
return 4
return 0