summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorGravatar Arno-Nymous <Arno-Nymous@users.noreply.github.com> 2015-12-22 02:10:05 +0100
committerGravatar Arno-Nymous <Arno-Nymous@users.noreply.github.com> 2015-12-22 02:10:05 +0100
commit988d734890dda4171f1aabe258cfec45062c824f (patch)
tree6157337f13a89aac066073ade90867aaa279c057 /module
parentInitial release of WarezWorld hook (diff)
parent[UgouploadNet] update (diff)
downloadpyload-988d734890dda4171f1aabe258cfec45062c824f.tar.xz
Merge remote-tracking branch 'pyload/stable' into stable
Diffstat (limited to 'module')
-rw-r--r--module/plugins/accounts/FileParadoxIn.py17
-rw-r--r--module/plugins/accounts/RapiduNet.py6
-rw-r--r--module/plugins/crypter/HflixIn.py28
-rw-r--r--module/plugins/hooks/ClickNLoad.py31
-rw-r--r--module/plugins/hooks/UpdateManager.py100
-rw-r--r--module/plugins/hooks/XFileSharing.py2
-rw-r--r--module/plugins/hoster/NitroflareCom.py1
-rw-r--r--module/plugins/hoster/OneFichierCom.py35
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py2
-rw-r--r--module/plugins/hoster/UgouploadNet.py56
-rw-r--r--module/plugins/hoster/UpstoreNet.py36
-rw-r--r--module/plugins/internal/Extractor.py3
-rw-r--r--module/plugins/internal/Hoster.py4
-rw-r--r--module/plugins/internal/SimpleCrypter.py12
-rw-r--r--module/plugins/internal/SimpleHoster.py15
15 files changed, 219 insertions, 129 deletions
diff --git a/module/plugins/accounts/FileParadoxIn.py b/module/plugins/accounts/FileParadoxIn.py
deleted file mode 100644
index 1a3949583..000000000
--- a/module/plugins/accounts/FileParadoxIn.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from module.plugins.internal.XFSAccount import XFSAccount
-
-
-class FileParadoxIn(XFSAccount):
- __name__ = "FileParadoxIn"
- __type__ = "account"
- __version__ = "0.05"
- __status__ = "testing"
-
- __description__ = """FileParadox.in account plugin"""
- __license__ = "GPLv3"
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
-
-
- PLUGIN_DOMAIN = "fileparadox.in"
diff --git a/module/plugins/accounts/RapiduNet.py b/module/plugins/accounts/RapiduNet.py
index cde39a361..5a852b906 100644
--- a/module/plugins/accounts/RapiduNet.py
+++ b/module/plugins/accounts/RapiduNet.py
@@ -10,7 +10,7 @@ from module.plugins.internal.utils import json
class RapiduNet(Account):
__name__ = "RapiduNet"
__type__ = "account"
- __version__ = "0.10"
+ __version__ = "0.11"
__status__ = "testing"
__description__ = """Rapidu.net account plugin"""
@@ -23,7 +23,7 @@ class RapiduNet(Account):
VALID_UNTIL_PATTERN = r'>Account: <b>\w+ \((\d+)'
- TRAFFIC_LEFT_PATTERN = r'class="tipsyS"><b>(.+?)<'
+ TRAFFIC_LEFT_PATTERN = r'class="tipsyS"><b>([\d.,]+)\s*([\w^_]*)<'
def grab_info(self, user, password, data):
@@ -42,7 +42,7 @@ class RapiduNet(Account):
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
if m is not None:
- trafficleft = self.parse_traffic(m.group(1))
+ trafficleft = self.parse_traffic(m.group(1), m.group(2))
return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
diff --git a/module/plugins/crypter/HflixIn.py b/module/plugins/crypter/HflixIn.py
new file mode 100644
index 000000000..f0bcd7d3a
--- /dev/null
+++ b/module/plugins/crypter/HflixIn.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.internal.Crypter import Crypter
+
+class HflixIn(Crypter):
+ __name__ = "HflixIn"
+ __type__ = "crypter"
+ __version__ = "0.1"
+ __status__ = "testing"
+
+ __pattern__ = r"http://hflix.in/\w{5}"
+
+ __description__ = """Hflix.in Decrypter Plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("GammaC0de", "nitzo2001[AT]yahoo[DOT]com")]
+
+
+ def decrypt(self, pyfile):
+ headers = self.load(pyfile.url, just_header=True)
+ if 'refresh' in headers and headers['refresh']:
+ m = re.search("\d+;url=(.+)", headers['refresh'])
+ if m and "http://hflix.in/admin" not in m.group(1):
+ self.packages.append((pyfile.package().name, [m.group(1)], pyfile.package().name))
+
+ else:
+ self.offline()
diff --git a/module/plugins/hooks/ClickNLoad.py b/module/plugins/hooks/ClickNLoad.py
index 722e4fbe0..79bf66c09 100644
--- a/module/plugins/hooks/ClickNLoad.py
+++ b/module/plugins/hooks/ClickNLoad.py
@@ -27,7 +27,7 @@ def forward(source, destination):
class ClickNLoad(Addon):
__name__ = "ClickNLoad"
__type__ = "hook"
- __version__ = "0.49"
+ __version__ = "0.51"
__status__ = "testing"
__config__ = [("activated", "bool" , "Activated" , True ),
@@ -37,19 +37,22 @@ class ClickNLoad(Addon):
__description__ = """Click'n'Load support"""
__license__ = "GPLv3"
- __authors__ = [("RaNaN" , "RaNaN@pyload.de" ),
- ("Walter Purcaro", "vuolter@gmail.com")]
+ __authors__ = [("RaNaN" , "RaNaN@pyload.de" ),
+ ("Walter Purcaro", "vuolter@gmail.com" ),
+ ("GammaC0de" , "nitzo2001[AT]yahoo[DOT]com")]
def activate(self):
if not self.pyload.config.get("webinterface", "activated"):
return
- ip = "" if self.get_config('extern') else "127.0.0.1"
- webport = self.pyload.config.get("webinterface", "port")
+ cnlip = "" if self.get_config('extern') else "127.0.0.1"
cnlport = self.get_config('port')
+ webip = "127.0.0.1" if any(_ip == self.pyload.config.get("webinterface", "host") for _ip in ("0.0.0.0", "")) \
+ else self.pyload.config.get("webinterface", "host")
+ webport = self.pyload.config.get("webinterface", "port")
- self.pyload.scheduler.addJob(5, self.proxy, [ip, webport, cnlport], threaded=False)
+ self.pyload.scheduler.addJob(5, self.proxy, [cnlip, cnlport, webip, webport], threaded=False)
@threaded
@@ -66,10 +69,10 @@ class ClickNLoad(Addon):
@threaded
- def proxy(self, ip, webport, cnlport):
- self.log_info(_("Proxy listening on %s:%s") % (ip or "0.0.0.0", cnlport))
+ def proxy(self, cnlip, cnlport, webip, webport):
+ self.log_info(_("Proxy listening on %s:%s") % (cnlip or "0.0.0.0", cnlport))
- self._server(ip, webport, cnlport)
+ self._server(cnlip, cnlport, webip, webport)
lock = threading.Lock()
lock.acquire()
@@ -77,10 +80,10 @@ class ClickNLoad(Addon):
@threaded
- def _server(self, ip, webport, cnlport):
+ def _server(self, cnlip, cnlport, webip, webport):
try:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- dock_socket.bind((ip, cnlport))
+ dock_socket.bind((cnlip, cnlport))
dock_socket.listen(5)
while True:
@@ -103,16 +106,16 @@ class ClickNLoad(Addon):
client_socket.close()
continue
- server_socket.connect(("127.0.0.1", webport))
+ server_socket.connect((webip, webport))
self.forward(client_socket, server_socket, self.get_config('dest') is "queue")
self.forward(server_socket, client_socket)
except socket.timeout:
self.log_debug("Connection timed out, retrying...")
- return self._server(ip, webport, cnlport)
+ return self._server(cnlip, cnlport, webip, webport)
except socket.error, e:
self.log_error(e)
time.sleep(240)
- return self._server(ip, webport, cnlport)
+ return self._server(cnlip, cnlport, webip, webport)
diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py
index 13f8a3704..e235b0e47 100644
--- a/module/plugins/hooks/UpdateManager.py
+++ b/module/plugins/hooks/UpdateManager.py
@@ -15,7 +15,7 @@ from module.plugins.internal.utils import encode, exists, fs_join
class UpdateManager(Addon):
__name__ = "UpdateManager"
__type__ = "hook"
- __version__ = "1.03"
+ __version__ = "1.04"
__status__ = "testing"
__config__ = [("activated" , "bool", "Activated" , True ),
@@ -101,21 +101,21 @@ class UpdateManager(Addon):
m.__name__.count(".") >= 2, sys.modules.values()
)
for m in modules:
- root, type, name = m.__name__.rsplit(".", 2)
- id = (type, name)
- if type in self.pyload.pluginManager.plugins:
+ root, plugin_type, plugin_name = m.__name__.rsplit(".", 2)
+ plugin_id = (plugin_type, plugin_name)
+ if plugin_type in self.pyload.pluginManager.plugins:
f = m.__file__.replace(".pyc", ".py")
if not os.path.isfile(f):
continue
mtime = os.path.getmtime(f)
- if id not in self.mtimes:
- self.mtimes[id] = mtime
+ if plugin_id not in self.mtimes:
+ self.mtimes[plugin_id] = mtime
- elif self.mtimes[id] < mtime:
- reloads.append(id)
- self.mtimes[id] = mtime
+ elif self.mtimes[plugin_id] < mtime:
+ reloads.append(plugin_id)
+ self.mtimes[plugin_id] = mtime
return True if self.pyload.pluginManager.reloadPlugins(reloads) else False
@@ -186,12 +186,12 @@ class UpdateManager(Addon):
@Expose
def update_plugins(self):
- updates = self.server_response()
+ server_data = self.server_response()
- if not updates or updates[0] != "None":
+ if not server_data or server_data[0] != "None":
return 0
- updated = self._update_plugins(updates)
+ updated = self._update_plugins(server_data)
if updated:
self.log_info(_("*** Plugins updated ***"))
@@ -215,15 +215,15 @@ class UpdateManager(Addon):
return exitcode
- def parse_list(self, list):
- schema = list[2].split('|')
+ def parse_updates(self, server_data):
+ schema = server_data[2].split('|')
- if "BLACKLIST" in list:
- blacklist = list[list.index('BLACKLIST') + 1:]
- updatelist = list[3:list.index('BLACKLIST')]
+ if "BLACKLIST" in server_data:
+ blacklist = server_data[server_data.index('BLACKLIST') + 1:]
+ updatelist = server_data[3:server_data.index('BLACKLIST')]
else:
blacklist = []
- updatelist = list[3:]
+ updatelist = server_data[3:]
for l in updatelist, blacklist:
nl = []
@@ -239,51 +239,51 @@ class UpdateManager(Addon):
return updatelist, blacklist
- def _update_plugins(self, updates):
+ def _update_plugins(self, server_data):
"""
Check for plugin updates
"""
updated = []
- updatelist, blacklist = self.parse_list(updates)
+ updatelist, blacklist = self.parse_updates(server_data)
- url = updates[1]
+ url = server_data[1]
req = self.pyload.requestFactory.getRequest(self.classname)
if blacklist:
#@NOTE: Protect UpdateManager from self-removing
- type_plugins = [(plugin['type'], plugin['name']) for plugin in blacklist \
+ blacklisted_plugins = [(plugin['type'], plugin['name']) for plugin in blacklist \
if plugin['name'] is not self.classname and plugin['type'] is not self.__type__]
c = 1
- l = len(type_plugins)
+ l = len(blacklisted_plugins)
for idx, plugin in enumerate(updatelist):
if c > l:
break
- name = plugin['name']
- type = plugin['type']
- for t, n in type_plugins:
- if n != name or t != type:
+ plugin_name = plugin['name']
+ plugin_type = plugin['type']
+ for t, n in blacklisted_plugins:
+ if n != plugin_name or t != plugin_type:
continue
updatelist.pop(idx)
c += 1
break
- for t, n in self.remove_plugins(type_plugins):
+ for t, n in self.remove_plugins(blacklisted_plugins):
self.log_info(_("Removed blacklisted plugin: %(type)s %(name)s") % {
'type': t.upper(),
'name': n,
})
for plugin in updatelist:
- name = plugin['name']
- type = plugin['type']
- version = plugin['version']
+ plugin_name = plugin['name']
+ plugin_type = plugin['type']
+ plugin_version = plugin['version']
- plugins = getattr(self.pyload.pluginManager, "%sPlugins" % type.rstrip('s')) #@TODO: Remove rstrip in 0.4.10
+ plugins = getattr(self.pyload.pluginManager, "%sPlugins" % plugin_type.rstrip('s')) #@TODO: Remove rstrip in 0.4.10
- oldver = float(plugins[name]['v']) if name in plugins else None
- newver = float(version)
+ oldver = float(plugins[plugin_name]['v']) if plugin_name in plugins else None
+ newver = float(plugin_version)
if not oldver:
msg = "New plugin: %(type)s %(name)s (v%(newver).2f)"
@@ -292,8 +292,8 @@ class UpdateManager(Addon):
else:
continue
- self.log_info(_(msg) % {'type' : type.rstrip('s').upper(), #@TODO: Remove rstrip in 0.4.10
- 'name' : name,
+ self.log_info(_(msg) % {'type' : plugin_type.rstrip('s').upper(), #@TODO: Remove rstrip in 0.4.10
+ 'name' : plugin_name,
'oldver': oldver,
'newver': newver})
try:
@@ -303,16 +303,16 @@ class UpdateManager(Addon):
raise Exception(_("URL not found"))
m = self._VERSION.search(content)
- if m and m.group(2) == version:
- with open(fs_join("userplugins", type, name + ".py"), "wb") as f:
+ if m and m.group(2) == plugin_version:
+ with open(fs_join("userplugins", plugin_type, plugin_name + ".py"), "wb") as f:
f.write(encode(content))
- updated.append((type, name))
+ updated.append((plugin_type, plugin_name))
else:
raise Exception(_("Version mismatch"))
except Exception, e:
- self.log_error(_("Error updating plugin: %s %s") % (type.rstrip('s').upper(), name), e) #@TODO: Remove rstrip in 0.4.10
+ self.log_error(_("Error updating plugin: %s %s") % (plugin_type.rstrip('s').upper(), plugin_name), e) #@TODO: Remove rstrip in 0.4.10
return updated
@@ -327,27 +327,27 @@ class UpdateManager(Addon):
@Expose
- def remove_plugins(self, type_plugins):
+ def remove_plugins(self, plugin_ids):
"""
Delete plugins from disk
"""
- if not type_plugins:
+ if not plugin_ids:
return
removed = set()
- self.log_debug("Requested deletion of plugins: %s" % type_plugins)
+ self.log_debug("Requested deletion of plugins: %s" % plugin_ids)
- for type, name in type_plugins:
+ for plugin_type, plugin_name in plugin_ids:
rootplugins = os.path.join(pypath, "module", "plugins")
- for dir in ("userplugins", rootplugins):
- py_filename = fs_join(dir, type, name + ".py")
+ for basedir in ("userplugins", rootplugins):
+ py_filename = fs_join(basedir, plugin_type, plugin_name + ".py")
pyc_filename = py_filename + "c"
- if type is "hook":
+ if plugin_type is "hook":
try:
- self.manager.deactivateHook(name)
+ self.manager.deactivateHook(plugin_name)
except Exception, e:
self.log_debug(e, trace=True)
@@ -363,7 +363,7 @@ class UpdateManager(Addon):
self.log_warning(_("Error removing `%s`") % filename, e)
else:
- id = (type, name)
- removed.add(id)
+ plugin_id = (plugin_type, plugin_name)
+ removed.add(plugin_id)
return list(removed) #: Return a list of the plugins successfully removed
diff --git a/module/plugins/hooks/XFileSharing.py b/module/plugins/hooks/XFileSharing.py
index 3c09fff4e..26dea3ec6 100644
--- a/module/plugins/hooks/XFileSharing.py
+++ b/module/plugins/hooks/XFileSharing.py
@@ -9,7 +9,7 @@ from module.plugins.internal.Addon import Addon
class XFileSharing(Addon):
__name__ = "XFileSharing"
__type__ = "hook"
- __version__ = "0.51"
+ __version__ = "0.52"
__status__ = "testing"
__config__ = [("activated" , "bool", "Activated" , True ),
diff --git a/module/plugins/hoster/NitroflareCom.py b/module/plugins/hoster/NitroflareCom.py
index 7970ae460..9ca6ab187 100644
--- a/module/plugins/hoster/NitroflareCom.py
+++ b/module/plugins/hoster/NitroflareCom.py
@@ -29,6 +29,7 @@ class NitroflareCom(SimpleHoster):
OFFLINE_PATTERN = r'>File doesn\'t exist'
LINK_PREMIUM_PATTERN = LINK_FREE_PATTERN = r'(https?://[\w\-]+\.nitroflare\.com/.+?)"'
+ DIRECT_LINK = False
RECAPTCHA_KEY = "6Lenx_USAAAAAF5L1pmTWvWcH73dipAEzNnmNLgy"
PREMIUM_ONLY_PATTERN = r'This file is available with Premium only'
diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py
index b657fe484..ef6f49da3 100644
--- a/module/plugins/hoster/OneFichierCom.py
+++ b/module/plugins/hoster/OneFichierCom.py
@@ -9,10 +9,10 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class OneFichierCom(SimpleHoster):
__name__ = "OneFichierCom"
__type__ = "hoster"
- __version__ = "0.95"
+ __version__ = "0.97"
__status__ = "testing"
- __pattern__ = r'https?://(?:www\.)?(?:\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)(?:/\?\w+)?'
+ __pattern__ = r'https?://(?:www\.)?(?:\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)(?:/\?\w+)?'
__config__ = [("activated" , "bool", "Activated" , True),
("use_premium" , "bool", "Use premium account if available" , True),
("fallback" , "bool", "Fallback to free download if premium fails" , True),
@@ -28,22 +28,24 @@ class OneFichierCom(SimpleHoster):
("stickell", "l.stickell@yahoo.it"),
("Elrick69", "elrick69[AT]rocketmail[DOT]com"),
("Walter Purcaro", "vuolter@gmail.com"),
- ("Ludovic Lehmann", "ludo.lehmann@gmail.com")]
+ ("Ludovic Lehmann", "ludo.lehmann@gmail.com"),
+ ("GammaC0de", "nitzo2001[AT]yahoo[DOT]com")]
+ DISPOSITION = False #@TODO: Remove disposition in 0.4.10
URL_REPLACEMENTS = [("https:", "http:")] #@TODO: Remove in 0.4.10
- COOKIES = [("1fichier.com", "LG", "en")]
+ COOKIES = [("1fichier.com", "LG", "en")]
- NAME_PATTERN = r'>File\s*Name :</td>\s*<td.*>(?P<N>.+?)<'
- SIZE_PATTERN = r'>Size :</td>\s*<td.*>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
- OFFLINE_PATTERN = r'File not found !\s*<'
-
- WAIT_PATTERN = r'>You must wait \d+ minutes'
+ NAME_PATTERN = r'>File\s*Name :</td>\s*<td.*>(?P<N>.+?)<'
+ SIZE_PATTERN = r'>Size :</td>\s*<td.*>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
+ OFFLINE_PATTERN = r'File not found !\s*<'
+ LINK_PATTERN = r'<a href="(.+?)".*>Click here to download the file</a>'
+ WAIT_PATTERN = r'>You must wait \d+ minutes'
def setup(self):
- self.multiDL = self.premium
+ self.multiDL = self.premium
self.resume_download = True
@@ -52,7 +54,7 @@ class OneFichierCom(SimpleHoster):
redirect = url
for i in xrange(10):
try:
- headers = dict(re.findall(r"(?P<name>.+?): (?P<value>.+?)\r?\n", get_url(redirect, just_header=True).lower()))
+ headers = dict((k.lower(), v) for k,v in re.findall(r"(?P<name>.+?): (?P<value>.+?)\r?\n", get_url(redirect, just_header=True)))
if 'location' in headers and headers['location']:
redirect = headers['location']
else:
@@ -94,13 +96,16 @@ class OneFichierCom(SimpleHoster):
if "pass" in inputs:
inputs['pass'] = self.get_password()
- inputs['submit'] = "Download"
+ inputs['dl_no_ssl'] = "on"
+
+ self.data=self.load(url, post=inputs)
- self.download(url, post=inputs)
+ m = re.search(self.LINK_PATTERN, self.data)
+ if m:
+ self.link = m.group(1)
def handle_premium(self, pyfile):
- self.download(pyfile.url, post={'did': 0, 'dl_no_ssl': "on"})
+ self.download(pyfile.url, post={'did': 0, 'dl_no_ssl': "on"}, disposition=False) #@TODO: Remove disposition in 0.4.10
-getInfo = create_getInfo(OneFichierCom)
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index 24c25a43a..06c9f6cfe 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -12,7 +12,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class ShareonlineBiz(SimpleHoster):
__name__ = "ShareonlineBiz"
__type__ = "hoster"
- __version__ = "0.63"
+ __version__ = "0.64"
__status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(share-online\.biz|egoshare\.com)/(download\.php\?id=|dl/)(?P<ID>\w+)'
diff --git a/module/plugins/hoster/UgouploadNet.py b/module/plugins/hoster/UgouploadNet.py
new file mode 100644
index 000000000..fec2e11d1
--- /dev/null
+++ b/module/plugins/hoster/UgouploadNet.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+
+
+class UgouploadNet(SimpleHoster):
+ __name__ = "UgouploadNet"
+ __type__ = "hoster"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r'https?://(?:www)?\.ugoupload\.net/\w{4}/.+'
+ __config__ = [("activated" , "bool", "Activated" , True),
+ ("use_premium" , "bool", "Use premium account if available" , True),
+ ("fallback" , "bool", "Fallback to free download if premium fails" , True),
+ ("chk_filesize", "bool", "Check file size" , True),
+ ("max_wait" , "int" , "Reconnect if waiting time is greater than minutes", 10 )]
+
+ __description__ = """ugoupload.net hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("GammaC0de", "nitzo2001[AT]yahoo[DOT]com")]
+
+
+ NAME_PATTERN = r'<div class="heading-1 animated".*>(.+?)</div>'
+ SIZE_PATTERN = r'\((?P<S>[\d.,]+) (?P<U>[\w^_]+)\)<br/>'
+
+ WAIT_PATTERN = r'var seconds = (\d+);'
+ LINK_FREE_PATTERN = r"<a class='btn btn-free' href='(.+?)'"
+
+ RECAPTCHA_KEY = "6LeuAc4SAAAAAOSry8eo2xW64K1sjHEKsQ5CaS10"
+
+
+ def setup(self):
+ self.resume_download = False
+ self.multiDL = False
+
+
+ def handle_free(self, pyfile):
+ if self.req.code == 404:
+ self.offline()
+
+ self.check_errors()
+
+ m = re.search(self.LINK_FREE_PATTERN, self.data)
+ if m:
+ recaptcha = ReCaptcha(self)
+ response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
+
+ self.download(m.group(1), post={'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field': response,
+ 'submit': "Submit",
+ 'submitted': "1",
+ 'd': "1"})
diff --git a/module/plugins/hoster/UpstoreNet.py b/module/plugins/hoster/UpstoreNet.py
index c863dff9d..4fcf6dcfa 100644
--- a/module/plugins/hoster/UpstoreNet.py
+++ b/module/plugins/hoster/UpstoreNet.py
@@ -9,16 +9,10 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UpstoreNet(SimpleHoster):
__name__ = "UpstoreNet"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.10"
__status__ = "testing"
__pattern__ = r'https?://(?:www\.)?upstore\.net/'
- __config__ = [("activated" , "bool", "Activated" , True),
- ("use_premium" , "bool", "Use premium account if available" , True),
- ("fallback" , "bool", "Fallback to free download if premium fails" , True),
- ("chk_filesize", "bool", "Check file size" , True),
- ("max_wait" , "int" , "Reconnect if waiting time is greater than minutes", 10 )]
-
__description__ = """Upstore.Net File Download Hoster"""
__license__ = "GPLv3"
__authors__ = [("igel", "igelkun@myopera.com")]
@@ -27,9 +21,12 @@ class UpstoreNet(SimpleHoster):
INFO_PATTERN = r'<div class="comment">.*?</div>\s*\n<h2 style="margin:0">(?P<N>.*?)</h2>\s*\n<div class="comment">\s*\n\s*(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
OFFLINE_PATTERN = r'<span class="error">File not found</span>'
+ LONG_WAIT_PATTERN = r'You should wait (\d+) min. before downloading next'
WAIT_PATTERN = r'var sec = (\d+)'
CHASH_PATTERN = r'<input type="hidden" name="hash" value="(.+?)">'
LINK_FREE_PATTERN = r'<a href="(https?://.*?)" target="_blank"><b>'
+ WRONG_CAPTCHA_PATTERN = r'Wrong captcha'
+ PREMIUM_ONLY_PATTERN = r'available only for Premium'
def handle_free(self, pyfile):
@@ -42,6 +39,7 @@ class UpstoreNet(SimpleHoster):
#: Continue to stage2
post_data = {'hash': chash, 'free': 'Slow download'}
self.data = self.load(pyfile.url, post=post_data)
+ self.check_errors()
#: STAGE 2: solv captcha and wait
#: First get the infos we need: recaptcha key and wait time
@@ -64,13 +62,31 @@ class UpstoreNet(SimpleHoster):
self.data = self.load(pyfile.url, post=post_data)
- #: STAGE 3: get direct link
+ # check whether the captcha was wrong
+ m = re.search(self.WRONG_CAPTCHA_PATTERN, self.data, re.S)
+ if m is not None:
+ continue
+
+
+ # STAGE 3: get direct link or wait time
+ m = re.search(self.LONG_WAIT_PATTERN, self.data, re.S)
+ if m is not None:
+ wait_time = 60* int(m.group(1))
+ self.wantReconnect = True
+ self.retry(wait=wait_time, reason=_("Please wait to download this file"))
+
m = re.search(self.LINK_FREE_PATTERN, self.data, re.S)
if m is not None:
+ self.link = m.group(1)
break
- if m is not None:
- self.link = m.group(1)
+ # sometimes, upstore just restarts the countdown without saying anything...
+ # in this case we'll just wait 1h and retry
+ self.wantReconnect = True
+ self.retry(wait_time=3600, reason=_("Upstore doesn't like us today"))
+
+
getInfo = create_getInfo(UpstoreNet)
+
diff --git a/module/plugins/internal/Extractor.py b/module/plugins/internal/Extractor.py
index e821f7aa4..41ba4d429 100644
--- a/module/plugins/internal/Extractor.py
+++ b/module/plugins/internal/Extractor.py
@@ -23,7 +23,7 @@ class PasswordError(Exception):
class Extractor(Plugin):
__name__ = "Extractor"
__type__ = "extractor"
- __version__ = "0.40"
+ __version__ = "0.41"
__status__ = "stable"
__description__ = """Base extractor plugin"""
@@ -80,7 +80,6 @@ class Extractor(Plugin):
fullpath=True,
overwrite=False,
excludefiles=[],
- renice=False,
priority=0,
keepbroken=False,
fid=None):
diff --git a/module/plugins/internal/Hoster.py b/module/plugins/internal/Hoster.py
index bbe37f39f..f5ba13875 100644
--- a/module/plugins/internal/Hoster.py
+++ b/module/plugins/internal/Hoster.py
@@ -15,7 +15,7 @@ from module.plugins.internal.utils import encode, exists, fixurl, fs_join, parse
class Hoster(Base):
__name__ = "Hoster"
__type__ = "hoster"
- __version__ = "0.45"
+ __version__ = "0.46"
__status__ = "stable"
__pattern__ = r'^unmatchable$'
@@ -226,7 +226,7 @@ class Hoster(Base):
disposition=disposition)
except BadHeader, e:
- self.req.code = e.code
+ self.req.http.code = e.code
raise BadHeader(e)
finally:
diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py
index 59b9acc31..5a9bd5c84 100644
--- a/module/plugins/internal/SimpleCrypter.py
+++ b/module/plugins/internal/SimpleCrypter.py
@@ -5,13 +5,13 @@ import re
from module.network.HTTPRequest import BadHeader
from module.network.RequestFactory import getURL as get_url
from module.plugins.internal.Crypter import Crypter, create_getInfo, parse_fileInfo
-from module.plugins.internal.utils import replace_patterns, set_cookie, set_cookies
+from module.plugins.internal.utils import parse_name, replace_patterns, set_cookie, set_cookies
class SimpleCrypter(Crypter):
__name__ = "SimpleCrypter"
__type__ = "crypter"
- __version__ = "0.79"
+ __version__ = "0.80"
__status__ = "testing"
__pattern__ = r'^unmatchable$'
@@ -41,7 +41,7 @@ class SimpleCrypter(Crypter):
example: TEMP_OFFLINE_PATTERN = r'Server maintainance'
- You can override the getLinks method if you need a more sophisticated way to extract the links.
+ You can override the get_links method if you need a more sophisticated way to extract the links.
If the links are splitted on multiple pages you can define the PAGES_PATTERN regex:
@@ -49,7 +49,7 @@ class SimpleCrypter(Crypter):
PAGES_PATTERN: (optional) group(1) should be the number of overall pages containing the links
example: PAGES_PATTERN = r'Pages: (\d+)'
- and its loadPage method:
+ and its load_page method:
def load_page(self, page_n):
return the html of the page number page_n
@@ -256,11 +256,11 @@ class SimpleCrypter(Crypter):
"""
if self.premium:
self.log_info(_("Decrypting as premium link..."))
- self.handle_premium(pyfile)
+ self.handle_premium(self.pyfile)
elif not self.LOGIN_ACCOUNT:
self.log_info(_("Decrypting as free link..."))
- self.handle_free(pyfile)
+ self.handle_free(self.pyfile)
return self.links
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index b67c12da7..4d7697d57 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -16,7 +16,7 @@ from module.plugins.internal.utils import (encode, parse_name, parse_size,
class SimpleHoster(Hoster):
__name__ = "SimpleHoster"
__type__ = "hoster"
- __version__ = "2.08"
+ __version__ = "2.14"
__status__ = "stable"
__pattern__ = r'^unmatchable$'
@@ -277,6 +277,9 @@ class SimpleHoster(Hoster):
self.log_info(_("Processing as free download..."))
self.handle_free(pyfile)
+ if not self.link and not self.last_download:
+ self.error(_("%s download link not found") % ("Premium" if self.premium else "Free"))
+
if not self.last_download:
self.log_info(_("Downloading file..."))
self.download(self.link, disposition=self.DISPOSITION)
@@ -428,12 +431,10 @@ class SimpleHoster(Hoster):
def handle_free(self, pyfile):
if not self.LINK_FREE_PATTERN:
- self.log_warning(_("Free download not implemented"))
+ self.error(_("Free download not implemented"))
m = re.search(self.LINK_FREE_PATTERN, self.data)
- if m is None:
- self.error(_("Free download link not found"))
- else:
+ if m is not None:
self.link = m.group(1)
@@ -443,7 +444,5 @@ class SimpleHoster(Hoster):
self.restart(premium=False)
m = re.search(self.LINK_PREMIUM_PATTERN, self.data)
- if m is None:
- self.error(_("Premium download link not found"))
- else:
+ if m is not None:
self.link = m.group(1)