summaryrefslogtreecommitdiffstats
path: root/module/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins')
-rw-r--r--module/plugins/accounts/EasybytezCom.py10
-rw-r--r--module/plugins/accounts/FreeWayMe.py67
-rw-r--r--module/plugins/accounts/OverLoadMe.py31
-rw-r--r--module/plugins/accounts/ShareFilesCo.py13
-rw-r--r--module/plugins/crypter/DlProtectCom.py75
-rw-r--r--module/plugins/crypter/FilestubeCom.py6
-rw-r--r--module/plugins/crypter/NosvideoCom.py13
-rw-r--r--module/plugins/crypter/TusfilesNetFolder.py54
-rw-r--r--module/plugins/hooks/FreeWayMe.py39
-rw-r--r--module/plugins/hooks/OverLoadMe.py28
-rw-r--r--module/plugins/hoster/ARD.py83
-rw-r--r--module/plugins/hoster/CloudzerNet.py79
-rw-r--r--module/plugins/hoster/CyberlockerCh.py15
-rw-r--r--module/plugins/hoster/FastshareCz.py95
-rw-r--r--module/plugins/hoster/FileomCom.py53
-rw-r--r--module/plugins/hoster/FreeWayMe.py48
-rw-r--r--module/plugins/hoster/Keep2shareCC.py21
-rw-r--r--module/plugins/hoster/LoadTo.py99
-rw-r--r--module/plugins/hoster/NosuploadCom.py38
-rw-r--r--module/plugins/hoster/OneFichierCom.py34
-rw-r--r--module/plugins/hoster/OverLoadMe.py78
-rw-r--r--module/plugins/hoster/PutlockerCom.py100
-rw-r--r--module/plugins/hoster/RapidgatorNet.py155
-rw-r--r--module/plugins/hoster/ShareFilesCo.py24
-rw-r--r--module/plugins/hoster/SockshareCom.py110
-rw-r--r--module/plugins/hoster/UptoboxCom.py35
-rw-r--r--module/plugins/hoster/XFileSharingPro.py52
-rw-r--r--module/plugins/hoster/ZDF.py7
-rw-r--r--module/plugins/hoster/ZippyshareCom.py14
29 files changed, 973 insertions, 503 deletions
diff --git a/module/plugins/accounts/EasybytezCom.py b/module/plugins/accounts/EasybytezCom.py
index 72f37b699..ffd132ba3 100644
--- a/module/plugins/accounts/EasybytezCom.py
+++ b/module/plugins/accounts/EasybytezCom.py
@@ -18,7 +18,7 @@
"""
import re
-from time import mktime, strptime
+from time import mktime, strptime, gmtime
from module.plugins.Account import Account
from module.plugins.internal.SimpleHoster import parseHtmlForm
@@ -27,7 +27,7 @@ from module.utils import parseFileSize
class EasybytezCom(Account):
__name__ = "EasybytezCom"
- __version__ = "0.03"
+ __version__ = "0.04"
__type__ = "account"
__description__ = """EasyBytez.com account plugin"""
__author_name__ = ("zoidberg")
@@ -44,19 +44,19 @@ class EasybytezCom(Account):
found = re.search(self.VALID_UNTIL_PATTERN, html)
if found:
- premium = True
- trafficleft = -1
try:
self.logDebug("Expire date: " + found.group(1))
validuntil = mktime(strptime(found.group(1), "%d %B %Y"))
except Exception, e:
self.logError(e)
+ if validuntil > mktime(gmtime()):
+ premium = True
+ trafficleft = -1
else:
found = re.search(self.TRAFFIC_LEFT_PATTERN, html)
if found:
trafficleft = found.group(1)
if "Unlimited" in trafficleft:
- premium = True
trafficleft = -1
else:
trafficleft = parseFileSize(trafficleft) / 1024
diff --git a/module/plugins/accounts/FreeWayMe.py b/module/plugins/accounts/FreeWayMe.py
new file mode 100644
index 000000000..0222ad65f
--- /dev/null
+++ b/module/plugins/accounts/FreeWayMe.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+
+"""
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ @author: Nicolas Giese
+"""
+
+from module.plugins.Account import Account
+from module.common.json_layer import json_loads
+
+
+class FreeWayMe(Account):
+ __name__ = "FreeWayMe"
+ __version__ = "0.11"
+ __type__ = "account"
+ __description__ = """FreeWayMe account plugin"""
+ __author_name__ = ("Nicolas Giese")
+ __author_mail__ = ("james@free-way.me")
+
+ def loadAccountInfo(self, user, req):
+ status = self.getAccountStatus(user, req)
+ if not status:
+ return False
+ self.logDebug(status)
+
+ account_info = {"validuntil": -1, "premium": False}
+ if status["premium"] == "Free":
+ account_info["trafficleft"] = int(status["guthaben"]) * 1024
+ elif status["premium"] == "Spender":
+ account_info["trafficleft"] = -1
+ elif status["premium"] == "Flatrate":
+ account_info = {"validuntil": int(status["Flatrate"]),
+ "trafficleft": -1,
+ "premium": True}
+
+ return account_info
+
+ def getpw(self, user):
+ return self.accounts[user]["password"]
+
+ def login(self, user, data, req):
+ status = self.getAccountStatus(user, req)
+
+ # Check if user and password are valid
+ if not status:
+ self.wrongPassword()
+
+ def getAccountStatus(self, user, req):
+ answer = req.load("https://www.free-way.me/ajax/jd.php",
+ get={"id": 4, "user": user, "pass": self.accounts[user]["password"]})
+ self.logDebug("login: %s" % answer)
+ if answer == "Invalid login":
+ self.wrongPassword()
+ return False
+ return json_loads(answer)
diff --git a/module/plugins/accounts/OverLoadMe.py b/module/plugins/accounts/OverLoadMe.py
new file mode 100644
index 000000000..e288181eb
--- /dev/null
+++ b/module/plugins/accounts/OverLoadMe.py
@@ -0,0 +1,31 @@
+from module.plugins.Account import Account
+from module.common.json_layer import json_loads
+
+
+class OverLoadMe(Account):
+ __name__ = "OverLoadMe"
+ __version__ = "0.01"
+ __type__ = "account"
+ __description__ = """Over-Load.me account plugin"""
+ __author_name__ = ("marley")
+ __author_mail__ = ("marley@over-load.me")
+
+ def loadAccountInfo(self, user, req):
+ data = self.getAccountData(user)
+ page = req.load("https://api.over-load.me/account.php", get={"user": user, "auth": data["password"]}).strip()
+ data = json_loads(page)
+
+ # Check for premium
+ if data["membership"] == "Free":
+ return {"premium": False}
+
+ account_info = {"validuntil": data["expirationunix"], "trafficleft": -1}
+ return account_info
+
+ def login(self, user, data, req):
+ jsondata = req.load("https://api.over-load.me/account.php",
+ get={"user": user, "auth": data["password"]}).strip()
+ data = json_loads(jsondata)
+
+ if data["err"] == 1:
+ self.wrongPassword()
diff --git a/module/plugins/accounts/ShareFilesCo.py b/module/plugins/accounts/ShareFilesCo.py
deleted file mode 100644
index cff52d570..000000000
--- a/module/plugins/accounts/ShareFilesCo.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- coding: utf-8 -*-
-from module.plugins.internal.XFSPAccount import XFSPAccount
-
-
-class ShareFilesCo(XFSPAccount):
- __name__ = "ShareFilesCo"
- __version__ = "0.01"
- __type__ = "account"
- __description__ = """ShareFilesCo account plugin"""
- __author_name__ = ("stickell")
- __author_mail__ = ("l.stickell@yahoo.it")
-
- MAIN_PAGE = "http://sharefiles.co/"
diff --git a/module/plugins/crypter/DlProtectCom.py b/module/plugins/crypter/DlProtectCom.py
new file mode 100644
index 000000000..d93455a55
--- /dev/null
+++ b/module/plugins/crypter/DlProtectCom.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: Walter Purcaro
+###############################################################################
+
+import re
+from base64 import urlsafe_b64encode
+from time import time
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class DlProtectCom(SimpleCrypter):
+ __name__ = "DlProtectCom"
+ __type__ = "crypter"
+ __pattern__ = r"http://(?:www\.)?dl-protect\.com/((en|fr)/)?(?P<ID>\w+)"
+ __version__ = "0.01"
+ __description__ = """dl-protect.com decrypter plugin"""
+ __author_name__ = "Walter Purcaro"
+ __author_mail__ = "vuolter@gmail.com"
+
+ OFFLINE_PATTERN = ">Unfortunately, the link you are looking for is not found"
+
+ def getLinks(self):
+ # Direct link with redirect
+ if not re.match(r"http://(?:www\.)?dl-protect\.com", self.req.http.lastEffectiveURL):
+ return [self.req.http.lastEffectiveURL]
+
+ #id = re.match(self.__pattern__, self.pyfile.url).group("ID")
+ key = re.search(r'name="id_key" value="(.+?)"', self.html).group(1)
+
+ post_req = {"id_key": key, "submitform": ""}
+
+ if self.OFFLINE_PATTERN in self.html:
+ self.offline()
+ elif ">Please click on continue to see the content" in self.html:
+ post_req.update({"submitform": "Continue"})
+ else:
+ mstime = int(round(time() * 1000))
+ b64time = "_" + urlsafe_b64encode(str(mstime)).replace("=", "%3D")
+
+ post_req.update({"i": b64time, "submitform": "Decrypt+link"})
+
+ if ">Password :" in self.html:
+ post_req["pwd"] = self.getPassword()
+
+ if ">Security Code" in self.html:
+ captcha_id = re.search(r'/captcha\.php\?uid=(.+?)"', self.html).group(1)
+ captcha_url = "http://www.dl-protect.com/captcha.php?uid=" + captcha_id
+ captcha_code = self.decryptCaptcha(captcha_url, imgtype="gif")
+
+ post_req["secure"] = captcha_code
+
+ self.html = self.load(self.pyfile.url, post=post_req)
+
+ for errmsg in (">The password is incorrect", ">The security code is incorrect"):
+ if errmsg in self.html:
+ self.fail(errmsg[1:])
+
+ pattern = r'<a href="([^/].+?)" target="_blank">'
+ return re.findall(pattern, self.html)
diff --git a/module/plugins/crypter/FilestubeCom.py b/module/plugins/crypter/FilestubeCom.py
index 24e2ca137..bb90e63b8 100644
--- a/module/plugins/crypter/FilestubeCom.py
+++ b/module/plugins/crypter/FilestubeCom.py
@@ -22,10 +22,10 @@ class FilestubeCom(SimpleCrypter):
__name__ = "FilestubeCom"
__type__ = "crypter"
__pattern__ = r"http://(?:w{3}.)?filestube\.(?:com|to)/\w+"
- __version__ = "0.02"
+ __version__ = "0.03"
__description__ = """Filestube.com Plugin"""
__author_name__ = ("stickell")
__author_mail__ = ("l.stickell@yahoo.it")
- LINK_PATTERN = r"link_download'\]\); renderGo\('(http://[^)]+)'\);"
- TITLE_PATTERN = r"<title>(?P<title>.+) download"
+ LINK_PATTERN = r"<a class=\"file-link-main(?: noref)?\" [^>]* href=\"(http://[^\"]+)"
+ TITLE_PATTERN = r"<h1\s*> (?P<title>.+) download\s*</h1>"
diff --git a/module/plugins/crypter/NosvideoCom.py b/module/plugins/crypter/NosvideoCom.py
new file mode 100644
index 000000000..49b932fc0
--- /dev/null
+++ b/module/plugins/crypter/NosvideoCom.py
@@ -0,0 +1,13 @@
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class NosvideoCom(SimpleCrypter):
+ __name__ = "NosvideoCom"
+ __type__ = "crypter"
+ __pattern__ = r"http://(?:www\.)?nosvideo\.com/\?v=\w+"
+ __version__ = "0.01"
+ __description__ = """Nosvideo.com Plugin"""
+ __author_name__ = "igel"
+
+ LINK_PATTERN = r'href="(http://(?:w{3}\.)?nosupload.com/\?d=\w+)"'
+ TITLE_PATTERN = r"<[tT]itle>Watch (?P<title>.+)</[tT]itle>"
diff --git a/module/plugins/crypter/TusfilesNetFolder.py b/module/plugins/crypter/TusfilesNetFolder.py
new file mode 100644
index 000000000..f364aabe7
--- /dev/null
+++ b/module/plugins/crypter/TusfilesNetFolder.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: Walter Purcaro
+###############################################################################
+
+import math
+import re
+from urlparse import urljoin
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class TusfilesNetFolder(SimpleCrypter):
+ __name__ = "TusfilesNetFolder"
+ __type__ = "crypter"
+ __pattern__ = r'https?://(?:www\.)?tusfiles\.net/go/(?P<ID>\w+)/?'
+ __version__ = "0.01"
+ __description__ = """Tusfiles.net folder decrypter plugin"""
+ __author_name__ = ("Walter Purcaro", "stickell")
+ __author_mail__ = ("vuolter@gmail.com", "l.stickell@yahoo.it")
+
+ LINK_PATTERN = r'<TD align=left><a href="(.*?)">'
+ TITLE_PATTERN = r'<Title>.*?\: (?P<title>.+) folder</Title>'
+ PAGES_PATTERN = r'>\((?P<pages>\d+) \w+\)<'
+
+ FILE_URL_REPLACEMENTS = [(__pattern__, r'https://www.tusfiles.net/go/\g<ID>/')]
+
+ def loadPage(self, page_n):
+ return self.load(urljoin(self.pyfile.url, str(page_n)), decode=True)
+
+ def handleMultiPages(self):
+ pages = re.search(self.PAGES_PATTERN, self.html)
+ if pages:
+ pages = int(math.ceil(int(pages.group('pages')) / 25.0))
+ else:
+ return
+
+ for p in xrange(2, pages + 1):
+ self.html = self.loadPage(p)
+ self.package_links += self.getLinks()
diff --git a/module/plugins/hooks/FreeWayMe.py b/module/plugins/hooks/FreeWayMe.py
new file mode 100644
index 000000000..30d76cb8e
--- /dev/null
+++ b/module/plugins/hooks/FreeWayMe.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+"""
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ @author: Nicolas Giese
+"""
+
+from module.network.RequestFactory import getURL
+from module.plugins.internal.MultiHoster import MultiHoster
+
+class FreeWayMe(MultiHoster):
+ __name__ = "FreeWayMe"
+ __version__ = "0.11"
+ __type__ = "hook"
+ __description__ = """FreeWayMe hook plugin"""
+ __config__ = [("activated", "bool", "Activated", "False"),
+ ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"),
+ ("hosterList", "str", "Hoster list (comma separated)", ""),
+ ("unloadFailing", "bool", "Revert to stanard download if download fails", "False"),
+ ("interval", "int", "Reload interval in hours (0 to disable)", "24")]
+ __author_name__ = ("Nicolas Giese")
+ __author_mail__ = ("james@free-way.me")
+
+ def getHoster(self):
+ hostis = getURL("https://www.free-way.me/ajax/jd.php", get={"id": 3}).replace("\"", "").strip()
+ self.logDebug("hosters: %s" % hostis)
+ return [x.strip() for x in hostis.split(",") if x.strip()]
diff --git a/module/plugins/hooks/OverLoadMe.py b/module/plugins/hooks/OverLoadMe.py
new file mode 100644
index 000000000..bc8f9f5cb
--- /dev/null
+++ b/module/plugins/hooks/OverLoadMe.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+from module.network.RequestFactory import getURL
+from module.plugins.internal.MultiHoster import MultiHoster
+
+
+class OverLoadMe(MultiHoster):
+ __name__ = "OverLoadMe"
+ __version__ = "0.01"
+ __type__ = "hook"
+ __config__ = [("activated", "bool", "Activated", "False"),
+ ("https", "bool", "Enable HTTPS", "True"),
+ ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported):", "all"),
+ ("hosterList", "str", "Hoster list (comma separated)", ""),
+ ("unloadFailing", "bool", "Revert to standard download if download fails", "False"),
+ ("interval", "int", "Reload interval in hours (0 to disable)", "12")]
+ __description__ = """Over-Load.me hook plugin"""
+ __author_name__ = ("marley")
+ __author_email__ = ("marley@over-load.me")
+
+ def getHoster(self):
+ https = "https" if self.getConfig("https") else "http"
+ page = getURL(https + "://api.over-load.me/hoster.php",
+ get={"auth": "0001-cb1f24dadb3aa487bda5afd3b76298935329be7700cd7-5329be77-00cf-1ca0135f"}
+ ).replace("\"", "").strip()
+ self.logDebug("Hosterlist: %s" % page)
+
+ return [x.strip() for x in page.split(",") if x.strip()]
diff --git a/module/plugins/hoster/ARD.py b/module/plugins/hoster/ARD.py
deleted file mode 100644
index 12cb6c95a..000000000
--- a/module/plugins/hoster/ARD.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import subprocess
-import re
-import os.path
-import os
-
-from module.utils import save_join, save_path
-from module.plugins.Hoster import Hoster
-
-# Requires rtmpdump
-# by Roland Beermann
-
-
-class RTMP:
- # TODO: Port to some RTMP-library like rtmpy or similar
- # TODO?: Integrate properly into the API of pyLoad
-
- command = "rtmpdump"
-
- @classmethod
- def download_rtmp_stream(cls, url, output_file, playpath=None):
- opts = [
- "-r", url,
- "-o", output_file,
- ]
- if playpath:
- opts.append("--playpath")
- opts.append(playpath)
-
- cls._invoke_rtmpdump(opts)
-
- @classmethod
- def _invoke_rtmpdump(cls, opts):
- args = [
- cls.command
- ]
- args.extend(opts)
-
- return subprocess.check_call(args)
-
-
-class ARD(Hoster):
- __name__ = "ARD Mediathek"
- __version__ = "0.12"
- __pattern__ = r"http://www\.ardmediathek\.de/.*"
- __config__ = []
-
- def process(self, pyfile):
- site = self.load(pyfile.url)
-
- avail_videos = re.findall(
- r'mediaCollection.addMediaStream\(0, ([0-9]*), "([^\"]*)", "([^\"]*)", "[^\"]*"\);', site)
- avail_videos.sort(key=lambda videodesc: int(videodesc[0]),
- reverse=True) # The higher the number, the better the quality
-
- quality, url, playpath = avail_videos[0]
-
- pyfile.name = re.search(r"<h1>([^<]*)</h1>", site).group(1)
-
- if url.startswith("http"):
- # Best quality is available over HTTP. Very rare.
- self.download(url)
- else:
- pyfile.setStatus("downloading")
-
- download_folder = self.config['general']['download_folder']
-
- location = save_join(download_folder, pyfile.package().folder)
-
- if not os.path.exists(location):
- os.makedirs(location, int(self.config["permission"]["folder"], 8))
-
- if self.config["permission"]["change_dl"] and os.name != "nt":
- try:
- uid = getpwnam(self.config["permission"]["user"])[2]
- gid = getgrnam(self.config["permission"]["group"])[2]
-
- chown(location, uid, gid)
- except Exception, e:
- self.logWarning(_("Setting User and Group failed: %s") % str(e))
-
- output_file = save_join(location, save_path(pyfile.name)) + os.path.splitext(playpath)[1]
-
- RTMP.download_rtmp_stream(url, playpath=playpath, output_file=output_file)
diff --git a/module/plugins/hoster/CloudzerNet.py b/module/plugins/hoster/CloudzerNet.py
index 8253c35b9..d0a19a945 100644
--- a/module/plugins/hoster/CloudzerNet.py
+++ b/module/plugins/hoster/CloudzerNet.py
@@ -1,85 +1,16 @@
# -*- coding: utf-8 -*-
-import re
-from module.plugins.internal.SimpleHoster import SimpleHoster
-from module.common.json_layer import json_loads
-from module.plugins.internal.CaptchaService import ReCaptcha
-from module.network.RequestFactory import getURL
-from module.utils import parseFileSize
+from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
-def getInfo(urls):
- for url in urls:
- header = getURL(url, just_header=True)
- if 'Location: http://cloudzer.net/404' in header:
- file_info = (url, 0, 1, url)
- else:
- fid = re.search(CloudzerNet.__pattern__, url).group('ID')
- api_data = getURL('http://cloudzer.net/file/%s/status' % fid)
- name, size = api_data.splitlines()
- size = parseFileSize(size)
- file_info = (name, size, 2, url)
- yield file_info
-
-
-class CloudzerNet(SimpleHoster):
+class CloudzerNet(DeadHoster):
__name__ = "CloudzerNet"
__type__ = "hoster"
- __pattern__ = r"http://(www\.)?(cloudzer\.net/file/|clz\.to/(file/)?)(?P<ID>\w+).*"
- __version__ = "0.04"
+ __pattern__ = r"https?://(?:www\.)?(cloudzer\.net/file/|clz\.to/(file/)?)\w+"
+ __version__ = "0.05"
__description__ = """Cloudzer.net hoster plugin"""
__author_name__ = ("gs", "z00nx", "stickell")
__author_mail__ = ("I-_-I-_-I@web.de", "z00nx0@gmail.com", "l.stickell@yahoo.it")
- WAIT_PATTERN = '<meta name="wait" content="(\d+)">'
- CAPTCHA_KEY = '6Lcqz78SAAAAAPgsTYF3UlGf2QFQCNuPMenuyHF3'
-
- def handleFree(self):
- found = re.search(self.WAIT_PATTERN, self.html)
- seconds = int(found.group(1))
- self.logDebug("Found wait", seconds)
- self.setWait(seconds + 1)
- self.wait()
- response = self.load('http://cloudzer.net/io/ticket/slot/%s' % self.file_info['ID'], post=' ', cookies=True)
- self.logDebug("Download slot request response", response)
- response = json_loads(response)
- if response["succ"] is not True:
- self.fail("Unable to get a download slot")
-
- recaptcha = ReCaptcha(self)
- challenge, response = recaptcha.challenge(self.CAPTCHA_KEY)
- post_data = {"recaptcha_challenge_field": challenge, "recaptcha_response_field": response}
- response = json_loads(self.load('http://cloudzer.net/io/ticket/captcha/%s' % self.file_info['ID'],
- post=post_data, cookies=True))
- self.logDebug("Captcha check response", response)
- self.logDebug("First check")
-
- if "err" in response:
- if response["err"] == "captcha":
- self.logDebug("Wrong captcha")
- self.invalidCaptcha()
- self.retry()
- elif "Sie haben die max" in response["err"] or "You have reached the max" in response["err"]:
- self.logDebug("Download limit reached, waiting an hour")
- self.setWait(3600, True)
- self.wait()
- if "type" in response:
- if response["type"] == "download":
- url = response["url"]
- self.logDebug("Download link", url)
- self.download(url, disposition=True)
-
- def getFileInfo(self):
- self.logDebug("URL: %s" % self.pyfile.url)
-
- header = getURL(self.pyfile.url, just_header=True)
-
- if 'Location: http://cloudzer.net/404' in header:
- self.offline()
- else:
- self.fid = re.search(self.__pattern__, self.pyfile.url).group('ID')
- api_data = getURL('http://cloudzer.net/file/%s/status' % self.fid)
- self.pyfile.name, size = api_data.splitlines()
- self.pyfile.size = parseFileSize(size)
- self.logDebug("FILE NAME: %s FILE SIZE: %s" % (self.pyfile.name, self.pyfile.size))
+getInfo = create_getInfo(CloudzerNet)
diff --git a/module/plugins/hoster/CyberlockerCh.py b/module/plugins/hoster/CyberlockerCh.py
index 19a4473b3..a08bf8518 100644
--- a/module/plugins/hoster/CyberlockerCh.py
+++ b/module/plugins/hoster/CyberlockerCh.py
@@ -1,17 +1,16 @@
# -*- coding: utf-8 -*-
-from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo
+from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
-class CyberlockerCh(XFileSharingPro):
+
+class CyberlockerCh(DeadHoster):
__name__ = "CyberlockerCh"
__type__ = "hoster"
- __pattern__ = r"http://(www\.)?cyberlocker\.ch/\w{12}"
- __version__ = "0.01"
+ __pattern__ = r'http://(?:www\.)?cyberlocker\.ch/\w+'
+ __version__ = "0.02"
__description__ = """Cyberlocker.ch hoster plugin"""
- __author_name__ = ("stickell")
- __author_mail__ = ("l.stickell@yahoo.it")
-
- HOSTER_NAME = "cyberlocker.ch"
+ __author_name__ = "stickell"
+ __author_mail__ = "l.stickell@yahoo.it"
getInfo = create_getInfo(CyberlockerCh)
diff --git a/module/plugins/hoster/FastshareCz.py b/module/plugins/hoster/FastshareCz.py
index fba704123..93fbad6be 100644
--- a/module/plugins/hoster/FastshareCz.py
+++ b/module/plugins/hoster/FastshareCz.py
@@ -1,55 +1,63 @@
# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: zoidberg
-"""
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: zoidberg
+###############################################################################
# Test links (random.bin):
# http://www.fastshare.cz/2141189/random.bin
import re
+from urlparse import urljoin
+
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FastshareCz(SimpleHoster):
__name__ = "FastshareCz"
__type__ = "hoster"
- __pattern__ = r"http://(?:\w*\.)?fastshare.cz/\d+/.+"
- __version__ = "0.21"
- __description__ = """FastShare.cz"""
- __author_name__ = ("zoidberg", "stickell")
+ __pattern__ = r'http://(?:www\.)?fastshare\.cz/\d+/.+'
+ __version__ = "0.22"
+ __description__ = """FastShare.cz hoster plugin"""
+ __author_name__ = ("zoidberg", "stickell", "Walter Purcaro")
+ __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it", "vuolter@gmail.com")
+
+ FILE_INFO_PATTERN = r'<h1 class="dwp">(?P<N>[^<]+)</h1>\s*<div class="fileinfo">\s*Size\s*: (?P<S>\d+) (?P<U>\w+),'
+ FILE_OFFLINE_PATTERN = '>(The file has been deleted|Requested page not found)'
- FILE_INFO_PATTERN = r'<h1 class="dwp">(?P<N>[^<]+)</h1>\s*<div class="fileinfo">\s*(?:Velikost|Size)\s*: (?P<S>[^,]+),'
- FILE_OFFLINE_PATTERN = '(?:The file ?has been deleted|Requested page not found)'
- FILE_URL_REPLACEMENTS = [('#.*', '')]
- SH_COOKIES = [('fastshare.cz', 'lang', 'en')]
+ FILE_URL_REPLACEMENTS = [("#.*", "")]
+ SH_COOKIES = [(".fastshare.cz", "lang", "en")]
FREE_URL_PATTERN = r'action=(/free/.*?)>\s*<img src="([^"]*)"><br'
- PREMIUM_URL_PATTERN = r'(http://data\d+\.fastshare\.cz/download\.php\?id=\d+\&[^\s\"\'<>]+)'
- NOT_ENOUGH_CREDIC_PATTERN = "Nem.te dostate.n. kredit pro sta.en. tohoto souboru"
+ PREMIUM_URL_PATTERN = r'(http://data\d+\.fastshare\.cz/download\.php\?id=\d+&)'
+ CREDIT_PATTERN = " credit for "
def handleFree(self):
- if '100% of FREE slots are full' in self.html:
+ if "> 100% of FREE slots are full" in self.html:
self.retry(120, 60, "No free slots")
found = re.search(self.FREE_URL_PATTERN, self.html)
- if not found:
+ if found:
+ action, captcha_src = found.groups()
+ else:
self.parseError("Free URL")
- action, captcha_src = found.groups()
- captcha = self.decryptCaptcha("http://www.fastshare.cz" + captcha_src)
- self.download("http://www.fastshare.cz" + action, post={"code": captcha, "btn.x": 77, "btn.y": 18})
+
+ baseurl = "http://www.fastshare.cz"
+ captcha = self.decryptCaptcha(urljoin(baseurl, captcha_src))
+ self.download(urljoin(baseurl, action), post={"code": captcha, "btn.x": 77, "btn.y": 18})
check = self.checkDownload({
"paralell_dl":
@@ -64,24 +72,27 @@ class FastshareCz(SimpleHoster):
def handlePremium(self):
header = self.load(self.pyfile.url, just_header=True)
- if 'location' in header:
- url = header['location']
+ if "location" in header:
+ url = header["location"]
else:
self.html = self.load(self.pyfile.url)
- self.getFileInfo()
- if self.NOT_ENOUGH_CREDIC_PATTERN in self.html:
- self.logWarning('Not enough traffic left')
- self.resetAccount()
- found = re.search(self.PREMIUM_URL_PATTERN, self.html)
- if not found:
- self.parseError("Premium URL")
- url = found.group(1)
+ self.getFileInfo() #
- self.logDebug("PREMIUM URL: %s" % url)
+ if self.CREDIT_PATTERN in self.html:
+ self.logWarning("Not enough traffic left")
+ self.resetAccount()
+ else:
+ found = re.search(self.PREMIUM_URL_PATTERN, self.html)
+ if found:
+ url = found.group(1)
+ else:
+ self.parseError("Premium URL")
+
+ self.logDebug("PREMIUM URL: " + url)
self.download(url, disposition=True)
- check = self.checkDownload({"credit": re.compile(self.NOT_ENOUGH_CREDIC_PATTERN)})
+ check = self.checkDownload({"credit": re.compile(self.CREDIT_PATTERN)})
if check == "credit":
self.resetAccount()
diff --git a/module/plugins/hoster/FileomCom.py b/module/plugins/hoster/FileomCom.py
new file mode 100644
index 000000000..3cf9bb4c1
--- /dev/null
+++ b/module/plugins/hoster/FileomCom.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: Walter Purcaro
+###############################################################################
+
+# Test links (random.bin):
+# http://fileom.com/gycaytyzdw3g/random.bin.html
+
+from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo
+
+
+class FileomCom(XFileSharingPro):
+ __name__ = "FileomCom"
+ __type__ = "hoster"
+ __pattern__ = r'https?://(?:www\.)?fileom\.com/\w+'
+ __version__ = "0.01"
+ __description__ = """Fileom.com hoster plugin"""
+ __author_name__ = "Walter Purcaro"
+ __author_mail__ = "vuolter@gmail.com"
+
+ HOSTER_NAME = "fileom.com"
+
+ FILE_URL_REPLACEMENTS = [(r'/$', "")]
+ SH_COOKIES = [(".fileom.com", "lang", "english")]
+
+ FILE_NAME_PATTERN = r'Filename: <span>(?P<N>.+?)<'
+ FILE_SIZE_PATTERN = r'File Size: <span class="size">(?P<S>[\d\.]+) (?P<U>\w+)'
+
+ ERROR_PATTERN = r'class=["\']err["\'][^>]*>(.*?)(?:\'|</)'
+
+ DIRECT_LINK_PATTERN = r"var url2 = '(.+?)';"
+
+ def setup(self):
+ self.resumeDownload = self.premium
+ self.multiDL = True
+ self.chunkLimit = 1
+
+
+getInfo = create_getInfo(FileomCom)
diff --git a/module/plugins/hoster/FreeWayMe.py b/module/plugins/hoster/FreeWayMe.py
new file mode 100644
index 000000000..5439c10c1
--- /dev/null
+++ b/module/plugins/hoster/FreeWayMe.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+"""
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ @author: Nicolas Giese
+"""
+
+from module.plugins.Hoster import Hoster
+
+class FreeWayMe(Hoster):
+ __name__ = "FreeWayMe"
+ __version__ = "0.11"
+ __type__ = "hoster"
+ __pattern__ = r"https://free-way.me/.*"
+ __description__ = """FreeWayMe hoster plugin"""
+ __author_name__ = ("Nicolas Giese")
+ __author_mail__ = ("james@free-way.me")
+
+ def setup(self):
+ self.resumeDownload = False
+ self.chunkLimit = 1
+ self.multiDL = self.premium
+
+ def process(self, pyfile):
+ if not self.account:
+ self.logError(_("Please enter your %s account or deactivate this plugin") % "FreeWayMe")
+ self.fail("No FreeWay account provided")
+
+ self.logDebug("Old URL: %s" % pyfile.url)
+
+ (user, data) = self.account.selectAccount()
+
+ self.download(
+ "https://www.free-way.me/load.php",
+ get={"multiget": 7, "url": pyfile.url, "user": user, "pw": self.account.getpw(user), "json": ""},
+ disposition=True)
diff --git a/module/plugins/hoster/Keep2shareCC.py b/module/plugins/hoster/Keep2shareCC.py
index 323ee09ca..59308690c 100644
--- a/module/plugins/hoster/Keep2shareCC.py
+++ b/module/plugins/hoster/Keep2shareCC.py
@@ -16,7 +16,7 @@
############################################################################
# Test links (random.bin):
-# http://k2s.cc/file/527111edfb9ba/random.bin
+# http://k2s.cc/file/55fb73e1c00c5/random.bin
import re
from urlparse import urlparse, urljoin
@@ -29,7 +29,7 @@ class Keep2shareCC(SimpleHoster):
__name__ = "Keep2shareCC"
__type__ = "hoster"
__pattern__ = r"https?://(?:www\.)?(keep2share|k2s|keep2s)\.cc/file/(?P<ID>\w+)"
- __version__ = "0.08"
+ __version__ = "0.10"
__description__ = """Keep2share.cc hoster plugin"""
__author_name__ = ("stickell")
__author_mail__ = ("l.stickell@yahoo.it")
@@ -40,6 +40,7 @@ class Keep2shareCC(SimpleHoster):
DIRECT_LINK_PATTERN = r'To download this file with slow speed, use <a href="([^"]+)">this link</a>'
WAIT_PATTERN = r'Please wait ([\d:]+) to download this file'
+ ALREADY_DOWNLOADING_PATTERN = r'Free account does not allow to download more than one file at the same time'
RECAPTCHA_KEY = '6LcYcN0SAAAAABtMlxKj7X0hRxOY8_2U86kI1vbb'
@@ -60,6 +61,22 @@ class Keep2shareCC(SimpleHoster):
self.html = self.load(self.pyfile.url, post={'uniqueId': self.fid, 'free': 1})
+ m = re.search(self.WAIT_PATTERN, self.html)
+ if m:
+ self.logDebug('Hoster told us to wait for %s' % m.group(1))
+ # string to time convert courtesy of https://stackoverflow.com/questions/10663720
+ ftr = [3600, 60, 1]
+ wait_time = sum([a * b for a, b in zip(ftr, map(int, m.group(1).split(':')))])
+ self.wait(wait_time, reconnect=True)
+ self.retry()
+
+ m = re.search(self.ALREADY_DOWNLOADING_PATTERN, self.html)
+ if m:
+ # if someone is already downloading on our line, wait 30min and retry
+ self.logDebug('Already downloading, waiting for 30 minutes')
+ self.wait(1800, reconnect=True)
+ self.retry()
+
m = re.search(self.DIRECT_LINK_PATTERN, self.html)
if not m:
self.parseError("Unable to detect direct link")
diff --git a/module/plugins/hoster/LoadTo.py b/module/plugins/hoster/LoadTo.py
index 0f99c272a..d1c1eb0f8 100644
--- a/module/plugins/hoster/LoadTo.py
+++ b/module/plugins/hoster/LoadTo.py
@@ -1,61 +1,90 @@
# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: halfman
-"""
+############################################################################
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Affero General Public License as #
+# published by the Free Software Foundation, either version 3 of the #
+# License, or (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU Affero General Public License for more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+############################################################################
# Test links (random.bin):
-# http://www.load.to/dNsmgXRk4/random.bin
-# http://www.load.to/edbNTxcUb/random100.bin
+# http://www.load.to/JWydcofUY6/random.bin
+# http://www.load.to/oeSmrfkXE/random100.bin
import re
+
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+from module.plugins.internal.CaptchaService import ReCaptcha
class LoadTo(SimpleHoster):
__name__ = "LoadTo"
__type__ = "hoster"
__pattern__ = r"http://(?:www\.)?load\.to/\w+"
- __version__ = "0.12"
+ __version__ = "0.13"
__description__ = """Load.to hoster plugin"""
__author_name__ = ("halfman", "stickell")
__author_mail__ = ("Pulpan3@gmail.com", "l.stickell@yahoo.it")
- FILE_INFO_PATTERN = r'<a [^>]+>(?P<N>.+)</a></h3>\s*Size: (?P<S>\d+) Bytes'
+ FILE_INFO_PATTERN = r'<a [^>]+>(?P<N>.+)</a></h3>\s*Size: (?P<S>\d+) (?P<U>[kKmMgG]?i?[bB])'
URL_PATTERN = r'<form method="post" action="(.+?)"'
- FILE_OFFLINE_PATTERN = r'Can\'t find file. Please check URL.<br />'
+ FILE_OFFLINE_PATTERN = r'Can\'t find file. Please check URL.'
WAIT_PATTERN = r'type="submit" value="Download \((\d+)\)"'
+ RECAPTCHA_PATTERN = r'http://www.google.com/recaptcha/api/challenge'
+ RECAPTCHA_KEY = "6Lc34eISAAAAAKNbPVyxBgNriTjPRmF-FA1oxApG"
def setup(self):
- self.multiDL = False
+ self.multiDL = True
+ self.chunkLimit = 1
def process(self, pyfile):
-
self.html = self.load(pyfile.url, decode=True)
-
- found = re.search(self.URL_PATTERN, self.html)
- if not found:
- self.parseError('URL')
- download_url = found.group(1)
-
- timmy = re.search(self.WAIT_PATTERN, self.html)
- if timmy:
- self.setWait(timmy.group(1))
- self.wait()
-
- self.download(download_url, disposition=True)
+ self.getFileInfo()
+
+ # Check if File is online
+ if re.search(self.FILE_OFFLINE_PATTERN, self.html):
+ self.offline()
+
+ # Search for Download URL
+ m = re.search(self.URL_PATTERN, self.html)
+ if not m:
+ self.parseError('Unable to detect download URL')
+ download_url = m.group(1)
+
+ # Set Timer - may be obsolete
+ m = re.search(self.WAIT_PATTERN, self.html)
+ if m:
+ self.wait(m.group(1))
+
+ # Check if reCaptcha is present
+ m = re.search(self.RECAPTCHA_PATTERN, self.html)
+ if not m: # No captcha found
+ self.download(download_url)
+ else:
+ recaptcha = ReCaptcha(self)
+ for _ in xrange(5):
+ challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY)
+ if not response == '0':
+ break
+ else:
+ self.fail("No valid captcha solution received")
+
+ self.download(download_url,
+ post={'recaptcha_challenge_field': challenge, 'recaptcha_response_field': response})
+
+ # Verifiy reCaptcha by checking content of file for html 404-error
+ check = self.checkDownload({"404": re.compile("\A<h1>404 Not Found</h1>")})
+ if check == "404":
+ self.logWarning("The captcha you entered was incorrect. Please try again.")
+ self.invalidCaptcha()
+ self.retry()
getInfo = create_getInfo(LoadTo)
diff --git a/module/plugins/hoster/NosuploadCom.py b/module/plugins/hoster/NosuploadCom.py
new file mode 100644
index 000000000..5735390bb
--- /dev/null
+++ b/module/plugins/hoster/NosuploadCom.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo
+
+
+class NosuploadCom(XFileSharingPro):
+ __name__ = "NosuploadCom"
+ __type__ = "hoster"
+ __version__ = "0.1"
+ __pattern__ = r"http://(?:www\.)?nosupload\.com/\?d=\w{12}"
+ __description__ = """nosupload.com hoster plugin"""
+ __author_name__ = "igel"
+
+ HOSTER_NAME = "nosupload.com"
+
+ FILE_SIZE_PATTERN = r'<p><strong>Size:</strong> (?P<S>[0-9\.]+) (?P<U>[kKMG]?B)</p>'
+ DIRECT_LINK_PATTERN = r'<a class="select" href="(http://.+?)">Download</a>'
+ WAIT_PATTERN = r'Please wait.*?>(\d+)</span>'
+
+ def getDownloadLink(self):
+ # stage1: press the "Free Download" button
+ data = self.getPostParameters()
+ self.html = self.load(self.pyfile.url, post=data, ref=True, decode=True)
+
+ # stage2: wait some time and press the "Download File" button
+ data = self.getPostParameters()
+ wait_time = re.search(self.WAIT_PATTERN, self.html, re.MULTILINE | re.DOTALL).group(1)
+ self.logDebug("hoster told us to wait %s seconds" % wait_time)
+ self.wait(wait_time)
+ self.html = self.load(self.pyfile.url, post=data, ref=True, decode=True)
+
+ # stage3: get the download link
+ return re.search(self.DIRECT_LINK_PATTERN, self.html, re.S).group(1)
+
+
+getInfo = create_getInfo(NosuploadCom)
diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py
index 54bf1d1fa..4142eaece 100644
--- a/module/plugins/hoster/OneFichierCom.py
+++ b/module/plugins/hoster/OneFichierCom.py
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
+# Test links (random.bin):
+# http://5pnm24ltcw.1fichier.com/
+
import re
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
@@ -8,19 +11,22 @@ class OneFichierCom(SimpleHoster):
__name__ = "OneFichierCom"
__type__ = "hoster"
__pattern__ = r"(http://(\w+)\.((1fichier|d(es)?fichiers|pjointe)\.(com|fr|net|org)|(cjoint|mesfichiers|piecejointe|oi)\.(org|net)|tenvoi\.(com|org|net)|dl4free\.com|alterupload\.com|megadl.fr))"
- __version__ = "0.48"
+ __version__ = "0.50"
__description__ = """1fichier.com download hoster"""
__author_name__ = ("fragonib", "the-razer", "zoidberg", "imclem")
__author_mail__ = ("fragonib[AT]yahoo[DOT]es", "daniel_ AT gmx DOT net", "zoidberg@mujmail.cz", "imclem on github")
- FILE_NAME_PATTERN = r'">File name :</th>\s*<td>(?P<N>[^<]+)</td>'
- FILE_SIZE_PATTERN = r'<th>File size :</th>\s*<td>(?P<S>[^<]+)</td>'
+ FILE_NAME_PATTERN = r'">Filename :</th>\s*<td>(?P<N>[^<]+)</td>'
+ FILE_SIZE_PATTERN = r'<th>Size :</th>\s*<td>(?P<S>[^<]+)</td>'
FILE_OFFLINE_PATTERN = r'The (requested)? file (could not be found|has been deleted)'
FILE_URL_REPLACEMENTS = [(r'(http://[^/]*).*', r'\1/en/')]
- DOWNLOAD_LINK_PATTERN = r'<br/>&nbsp;<br/>&nbsp;<br/>&nbsp;\s+<a href="(?P<url>http://.*?)"'
+ DOWNLOAD_LINK_PATTERN = r"""location\s*.\s*'(?P<N>http://.*?)'"""
PASSWORD_PROTECTED_TOKEN = "protected by password"
- WAITING_PATTERN = "Warning ! Without premium status, you can download only one file at a time and you must wait up to (\d+) minutes between each downloads."
+ WAITING_PATTERN = "Warning ! Without premium status, you must wait up to (\d+) minutes between each downloads"
+ LAST_DOWNLOAD_DELAY = "Your last download finished (\d+) minutes ago"
+ NOT_PARALLEL = r"Warning ! Without premium status, you can download only one file at a time"
+ RETRY_TIME = 15*60 #Default retry time in seconds (if detected parallel download)
def process(self, pyfile):
found = re.search(self.__pattern__, pyfile.url)
@@ -28,19 +34,29 @@ class OneFichierCom(SimpleHoster):
url = "http://%s.%s/en/" % (found.group(2), found.group(3))
self.html = self.load(url, decode=True)
+ self.getFileInfo()
+
found = re.search(self.WAITING_PATTERN, self.html)
if found:
- self.waitAndRetry(int(found.group(1)) * 60)
-
- self.getFileInfo()
+ last_delay=0
+ # retrieve the delay from the last download to substract from required delay
+ found_delay = re.search(self.LAST_DOWNLOAD_DELAY, self.html)
+ if found_delay:
+ last_delay=int(found_delay.group(1))
+ self.waitAndRetry((int(found.group(1)) - last_delay) * 60)
+ else: #detect parallel download
+ found = re.search(self.NOT_PARALLEL, self.html)
+ if found:
+ self.waitAndRetry(self.RETRY_TIME)
url, inputs = self.parseHtmlForm('action="http://%s' % file_id)
- if not url or not inputs:
+ if not url:
self.parseError("Download link not found")
# Check for protection
if "pass" in inputs:
inputs['pass'] = self.getPassword()
+ inputs['submit'] = "Download"
self.download(url, post=inputs)
diff --git a/module/plugins/hoster/OverLoadMe.py b/module/plugins/hoster/OverLoadMe.py
new file mode 100644
index 000000000..658b3940f
--- /dev/null
+++ b/module/plugins/hoster/OverLoadMe.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+
+import re
+from urllib import unquote
+from random import randrange
+
+from module.plugins.Hoster import Hoster
+from module.common.json_layer import json_loads
+from module.utils import parseFileSize
+
+
+class OverLoadMe(Hoster):
+ __name__ = "OverLoadMe"
+ __version__ = "0.01"
+ __type__ = "hoster"
+ __pattern__ = r"https?://.*overload\.me.*"
+ __description__ = """Over-Load.me hoster plugin"""
+ __author_name__ = ("marley")
+ __author_mail__ = ("marley@over-load.me")
+
+ def getFilename(self, url):
+ try:
+ name = unquote(url.rsplit("/", 1)[1])
+ except IndexError:
+ name = "Unknown_Filename..."
+ if name.endswith("..."): # incomplete filename, append random stuff
+ name += "%s.tmp" % randrange(100, 999)
+ return name
+
+ def setup(self):
+ self.chunkLimit = 5
+ self.resumeDownload = True
+
+ def process(self, pyfile):
+ if re.match(self.__pattern__, pyfile.url):
+ new_url = pyfile.url
+ elif not self.account:
+ self.logError(_("Please enter your %s account or deactivate this plugin") % "Over-Load")
+ self.fail("No Over-Load account provided")
+ else:
+ self.logDebug("Old URL: %s" % pyfile.url)
+ data = self.account.getAccountData(self.user)
+
+ page = self.load("https://api.over-load.me/getdownload.php",
+ get={"auth": data["password"], "link": pyfile.url})
+ data = json_loads(page)
+
+ self.logDebug("Returned Data: %s" % data)
+
+ if data["err"] == 1:
+ self.logWarning(data["msg"])
+ self.tempOffline()
+ else:
+ if self.pyfile.name is not None and self.pyfile.name.endswith('.tmp') and data["filename"]:
+ self.pyfile.name = data["filename"]
+ self.pyfile.size = parseFileSize(data["filesize"])
+ new_url = data["downloadlink"]
+
+ if self.getConfig("https"):
+ new_url = new_url.replace("http://", "https://")
+ else:
+ new_url = new_url.replace("https://", "http://")
+
+ if new_url != pyfile.url:
+ self.logDebug("New URL: %s" % new_url)
+
+ if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown") or pyfile.name.endswith('..'):
+ # only use when name wasn't already set
+ pyfile.name = self.getFilename(new_url)
+
+ self.download(new_url, disposition=True)
+
+ check = self.checkDownload(
+ {"error": "<title>An error occured while processing your request</title>"})
+
+ if check == "error":
+ # usual this download can safely be retried
+ self.retry(reason="An error occured while generating link.", wait_time=60)
diff --git a/module/plugins/hoster/PutlockerCom.py b/module/plugins/hoster/PutlockerCom.py
index afe084028..002783bfd 100644
--- a/module/plugins/hoster/PutlockerCom.py
+++ b/module/plugins/hoster/PutlockerCom.py
@@ -1,96 +1,54 @@
# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: jeix
-"""
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: Walter Purcaro
+###############################################################################
import re
-from os import rename
-from module.plugins.internal.SimpleHoster import SimpleHoster
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class PutlockerCom(SimpleHoster):
__name__ = "PutlockerCom"
__type__ = "hoster"
- __pattern__ = r'http://(?:www\.)?putlocker\.com/(mobile/)?(file|embed)/(?P<ID>[a-zA-Z0-9]+)'
- __version__ = "0.32"
- __description__ = """Putlocker.Com"""
- __author_name__ = ("jeix", "stickell", "Walter Purcaro")
- __author_mail__ = ("", "l.stickell@yahoo.it", "vuolter@gmail.com")
+ __pattern__ = r'https?://(?:www\.)?(firedrive|putlocker)\.com/(mobile/)?(file|embed)/(?P<ID>\w+)'
+ __version__ = "0.33"
+ __description__ = """Firedrive.com hoster plugin"""
+ __author_name__ = "Walter Purcaro"
+ __author_mail__ = "vuolter@gmail.com"
- FILE_OFFLINE_PATTERN = r"This file doesn't exist, or has been removed."
- FILE_INFO_PATTERN = r'site-content">\s*<h1>(?P<N>.+)<strong>\( (?P<S>[^)]+) \)</strong></h1>'
+ FILE_NAME_PATTERN = r'<b>Name:</b> (?P<N>.+) <br>'
+ FILE_SIZE_PATTERN = r'<b>Size:</b> (?P<S>[\d.]+) (?P<U>[a-zA-Z]+) <br>'
+ FILE_OFFLINE_PATTERN = r"<div class=\"sad_face_image\">"
- FILE_URL_REPLACEMENTS = [(__pattern__, r'http://www.putlocker.com/file/\g<ID>')]
- HOSTER_NAME = "putlocker.com"
+ FILE_URL_REPLACEMENTS = [(__pattern__, r'http://www.firedrive.com/file/\g<ID>')]
def setup(self):
self.multiDL = self.resumeDownload = True
self.chunkLimit = -1
def handleFree(self):
- name = self.pyfile.name
link = self._getLink()
self.logDebug("Direct link: " + link)
self.download(link, disposition=True)
- self.processName(name)
def _getLink(self):
- hash_data = re.search(r'<input type="hidden" value="([a-z0-9]+)" name="hash">', self.html)
- if not hash_data:
- self.parseError('Unable to detect hash')
-
- post_data = {"hash": hash_data.group(1), "confirm": "Continue+as+Free+User"}
- self.html = self.load(self.pyfile.url, post=post_data)
- if (">You have exceeded the daily stream limit for your country\\. You can wait until tomorrow" in self.html or
- "(>This content server has been temporarily disabled for upgrades|Try again soon\\. You can still download it below\\.<)" in self.html):
- self.retry(wait_time=60 * 60 * 2, reason="Download limit exceeded or server disabled") # 2 hours wait
-
- patterns = (r'(/get_file\.php\?id=[A-Z0-9]+&key=[a-zA-Z0-9=]+&original=1)',
- r'(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+)',
- r'(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+&original=1)',
- r'<a href="/gopro\.php">Tired of ads and waiting\? Go Pro!</a>[\t\n\rn ]+</div>[\t\n\rn ]+<a href="(/.*?)"')
- for pattern in patterns:
- link = re.search(pattern, self.html)
- if link:
- break
- else:
- link = re.search(r"playlist: '(/get_file\.php\?stream=[a-zA-Z0-9=]+)'", self.html)
- if link:
- self.html = self.load("http://www.%s%s" % (self.HOSTER_NAME, link.group(1)))
- link = re.search(r'media:content url="(http://.*?)"', self.html)
- if not link:
- pattern = "\"(http://media\\-b\\d+\\.%s\\.%s/download/\\d+/.*?)\"" % self.HOSTER_NAME.rsplit(".")
- link = re.search(pattern, self.html)
- else:
- self.parseError('Unable to detect a download link')
+ self.html = self.load(self.pyfile.url, post={"confirm": re.search(r'name="confirm" value="(.*)"', self.html).group(1)})
+ return re.search(r'<a href="(https?://dl\.firedrive\.com/.*?)"', self.html).group(1)
- link = link.group(1).replace("&amp;", "&")
- if link.startswith("http://"):
- return link
- else:
- return "http://www.%s%s" % (self.HOSTER_NAME, link)
- def processName(self, name_old):
- name = self.pyfile.name
- if name <= name_old:
- return
- name_new = re.sub(r'\.[^.]+$', "", name_old) + name[len(name_old):]
- filename = self.lastDownload
- self.pyfile.name = name_new
- rename(filename, filename.rsplit(name)[0] + name_new)
- self.logInfo("%(name)s renamed to %(newname)s" % {"name": name, "newname": name_new})
+getInfo = create_getInfo(PutlockerCom)
diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py
index 611d2ba5d..7cb4cd229 100644
--- a/module/plugins/hoster/RapidgatorNet.py
+++ b/module/plugins/hoster/RapidgatorNet.py
@@ -1,52 +1,57 @@
# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: zoidberg
-"""
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: zoidberg
+###############################################################################
import re
from pycurl import HTTPHEADER
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.plugins.internal.CaptchaService import ReCaptcha, SolveMedia, AdsCaptcha
from module.common.json_layer import json_loads
from module.network.HTTPRequest import BadHeader
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+from module.plugins.internal.CaptchaService import ReCaptcha, SolveMedia, AdsCaptcha
class RapidgatorNet(SimpleHoster):
__name__ = "RapidgatorNet"
__type__ = "hoster"
- __pattern__ = r"http://(?:www\.)?(rapidgator.net)/file/(\w+)"
- __version__ = "0.19"
- __description__ = """rapidgator.net"""
- __author_name__ = ("zoidberg", "chrox", "stickell")
+ __pattern__ = r"http://(?:www\.)?(rapidgator\.net|rg\.to)/file/\w+"
+ __version__ = "0.21"
+ __description__ = """Rapidgator.net hoster plugin"""
+ __author_name__ = ("zoidberg", "chrox", "stickell", "Walter Purcaro")
+ __author_mail__ = ("zoidberg@mujmail.cz", "", "l.stickell@yahoo.it", "vuolter@gmail.com")
API_URL = 'http://rapidgator.net/api/file'
- FILE_NAME_PATTERN = r'Downloading:(?:\s*<[^>]*>)*\s*(?P<N>.*?)(?:\s*<[^>]*>)'
- FILE_SIZE_PATTERN = r'File size:\s*<strong>(?P<S>.*?)</strong>'
- FILE_OFFLINE_PATTERN = r'<title>File not found</title>'
+ FILE_NAME_PATTERN = r'<title>Download file (?P<N>.*)</title>'
+ FILE_SIZE_PATTERN = r'File size:\s*<strong>(?P<S>[\d\.]+) (?P<U>\w+)</strong>'
+ FILE_OFFLINE_PATTERN = r'>(File not found|Error 404)'
JSVARS_PATTERN = r"\s+var\s*(startTimerUrl|getDownloadUrl|captchaUrl|fid|secs)\s*=\s*'?(.*?)'?;"
- DOWNLOAD_LINK_PATTERN = r"return '(http[^']+)';\s*}\s*}\s*}?\);"
- RECAPTCHA_KEY_PATTERN = r'"http://api.recaptcha.net/challenge?k=(.*?)"'
- ADSCAPTCHA_SRC_PATTERN = r'(http://api.adscaptcha.com/Get.aspx[^"\']*)'
- SOLVEMEDIA_PATTERN = r'http:\/\/api\.solvemedia\.com\/papi\/challenge\.script\?k=(.*?)"'
+ PREMIUM_ONLY_ERROR_PATTERN = r'You can download files up to|This file can be downloaded by premium only<'
+ DOWNLOAD_LIMIT_ERROR_PATTERN = r'You have reached your (daily|hourly) downloads limit'
+ WAIT_PATTERN = r'(?:Delay between downloads must be not less than|Try again in)\s*(\d+)\s*(hour|min)'
+ DOWNLOAD_LINK_PATTERN = r"return '(http://\w+.rapidgator.net/.*)';"
+
+ RECAPTCHA_KEY_PATTERN = r'"http://api\.recaptcha\.net/challenge\?k=(.*?)"'
+ ADSCAPTCHA_SRC_PATTERN = r'(http://api\.adscaptcha\.com/Get\.aspx[^"\']*)'
+ SOLVEMEDIA_PATTERN = r'http://api\.solvemedia\.com/papi/challenge\.script\?k=(.*?)"'
def setup(self):
- self.resumeDownload = self.multiDL = False
+ self.resumeDownload = self.multiDL = self.premium
self.sid = None
self.chunkLimit = 1
self.req.setOption("timeout", 120)
@@ -60,7 +65,7 @@ class RapidgatorNet(SimpleHoster):
else:
self.handleFree()
- def getAPIResponse(self, cmd):
+ def api_response(self, cmd):
try:
json = self.load('%s/%s' % (self.API_URL, cmd),
get={'sid': self.sid,
@@ -85,23 +90,17 @@ class RapidgatorNet(SimpleHoster):
def handlePremium(self):
#self.logDebug("ACCOUNT_DATA", self.account.getAccountData(self.user))
- self.api_data = self.getAPIResponse('info')
+ self.api_data = self.api_response('info')
self.api_data['md5'] = self.api_data['hash']
self.pyfile.name = self.api_data['filename']
self.pyfile.size = self.api_data['size']
- url = self.getAPIResponse('download')['url']
- self.multiDL = True
+ url = self.api_response('download')['url']
self.download(url)
def handleFree(self):
self.html = self.load(self.pyfile.url, decode=True)
- self.getFileInfo()
- if ("You can download files up to 500 MB in free mode" in self.html or
- "This file can be downloaded by premium only" in self.html):
- self.fail("Premium account needed for download")
-
- self.checkWait()
+ self.checkFree()
jsvars = dict(re.findall(self.JSVARS_PATTERN, self.html))
self.logDebug(jsvars)
@@ -113,8 +112,7 @@ class RapidgatorNet(SimpleHoster):
jsvars.get('startTimerUrl', '/download/AjaxStartTimer'), jsvars["fid"])
jsvars.update(self.getJsonResponse(url))
- self.setWait(int(jsvars.get('secs', 30)) + 1, False)
- self.wait()
+ self.wait(int(jsvars.get('secs', 45)) + 1, False)
url = "http://rapidgator.net%s?sid=%s" % (
jsvars.get('getDownloadUrl', '/download/AjaxGetDownload'), jsvars["sid"])
@@ -125,6 +123,32 @@ class RapidgatorNet(SimpleHoster):
url = "http://rapidgator.net%s" % jsvars.get('captchaUrl', '/download/captcha')
self.html = self.load(url)
+
+ for _ in xrange(5):
+ found = re.search(self.DOWNLOAD_LINK_PATTERN, self.html)
+ if found:
+ link = found.group(1)
+ self.logDebug(link)
+ self.download(link, disposition=True)
+ break
+ else:
+ captcha, captcha_key = self.getCaptcha()
+ captcha_challenge, captcha_response = captcha.challenge(captcha_key)
+
+ self.html = self.load(url, post={
+ "DownloadCaptchaForm[captcha]": "",
+ "adcopy_challenge": captcha_challenge,
+ "adcopy_response": captcha_response
+ })
+
+ if "The verification code is incorrect" in self.html:
+ self.invalidCaptcha()
+ else:
+ self.correctCaptcha()
+ else:
+ self.parseError("Download link")
+
+ def getCaptcha(self):
found = re.search(self.ADSCAPTCHA_SRC_PATTERN, self.html)
if found:
captcha_key = found.group(1)
@@ -134,7 +158,6 @@ class RapidgatorNet(SimpleHoster):
if found:
captcha_key = found.group(1)
captcha = ReCaptcha(self)
-
else:
found = re.search(self.SOLVEMEDIA_PATTERN, self.html)
if found:
@@ -143,47 +166,29 @@ class RapidgatorNet(SimpleHoster):
else:
self.parseError("Captcha")
- for i in range(5):
- self.checkWait()
- captcha_challenge, captcha_response = captcha.challenge(captcha_key)
-
- self.html = self.load(url, post={
- "DownloadCaptchaForm[captcha]": "",
- "adcopy_challenge": captcha_challenge,
- "adcopy_response": captcha_response
- })
+ return captcha, captcha_key
- if 'The verification code is incorrect' in self.html:
- self.invalidCaptcha()
- else:
- self.correctCaptcha()
- break
+ def checkFree(self):
+ found = re.search(self.PREMIUM_ONLY_ERROR_PATTERN, self.html)
+ if found:
+ self.fail("Premium account needed for download")
else:
- self.fail("No valid captcha solution received")
-
- found = re.search(self.DOWNLOAD_LINK_PATTERN, self.html)
- if not found:
- self.parseError("download link")
- download_url = found.group(1)
- self.logDebug(download_url)
- self.download(download_url)
-
- def checkWait(self):
- found = re.search(r"(?:Delay between downloads must be not less than|Try again in)\s*(\d+)\s*(hour|min)",
- self.html)
+ found = re.search(self.WAIT_PATTERN, self.html)
+
if found:
wait_time = int(found.group(1)) * {"hour": 60, "min": 1}[found.group(2)]
else:
- found = re.search(r"You have reached your (daily|hourly) downloads limit", self.html)
- if found:
+ found = re.search(self.DOWNLOAD_LIMIT_ERROR_PATTERN, self.html)
+ if not found:
+ return
+ elif found.group(1) == "daily":
wait_time = 60
else:
- return
+ wait_time = 24 * 60
self.logDebug("Waiting %d minutes" % wait_time)
- self.setWait(wait_time * 60, True)
- self.wait()
- self.retry(max_tries=24)
+ self.wait(wait_time * 60, True)
+ self.retry()
def getJsonResponse(self, url):
response = self.load(url, decode=True)
diff --git a/module/plugins/hoster/ShareFilesCo.py b/module/plugins/hoster/ShareFilesCo.py
index 245e20ea6..35f21916c 100644
--- a/module/plugins/hoster/ShareFilesCo.py
+++ b/module/plugins/hoster/ShareFilesCo.py
@@ -1,28 +1,16 @@
# -*- coding: utf-8 -*-
-import re
-from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo
+from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
-class ShareFilesCo(XFileSharingPro):
+class ShareFilesCo(DeadHoster):
__name__ = "ShareFilesCo"
__type__ = "hoster"
- __pattern__ = r"http://(www\.)?sharefiles\.co/\w{12}"
- __version__ = "0.01"
+ __pattern__ = r'http://(?:www\.)?sharefiles\.co/\w{12}'
+ __version__ = "0.02"
__description__ = """Sharefiles.co hoster plugin"""
- __author_name__ = ("stickell")
- __author_mail__ = ("l.stickell@yahoo.it")
-
- HOSTER_NAME = "sharefiles.co"
-
- def startDownload(self, link):
- link = link.strip()
- if link.startswith('http://adf.ly'):
- link = re.sub('http://adf.ly/\d+/', '', link)
- if self.captcha:
- self.correctCaptcha()
- self.logDebug('DIRECT LINK: %s' % link)
- self.download(link)
+ __author_name__ = "stickell"
+ __author_mail__ = "l.stickell@yahoo.it"
getInfo = create_getInfo(ShareFilesCo)
diff --git a/module/plugins/hoster/SockshareCom.py b/module/plugins/hoster/SockshareCom.py
index b2635d8bc..fd0e5aa91 100644
--- a/module/plugins/hoster/SockshareCom.py
+++ b/module/plugins/hoster/SockshareCom.py
@@ -1,33 +1,97 @@
# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: Walter Purcaro
+###############################################################################
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
+import re
+from os import rename
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
- @author: Walter Purcaro
-"""
-from module.plugins.hoster.PutlockerCom import PutlockerCom
-
-
-class SockshareCom(PutlockerCom):
+class SockshareCom(SimpleHoster):
__name__ = "SockshareCom"
__type__ = "hoster"
- __pattern__ = r'http://(?:www\.)?sockshare\.com/(mobile/)?(file|embed)/(?P<ID>[A-Z0-9]+)'
- __version__ = "0.01"
- __description__ = """Sockshare.Com"""
- __author_name__ = ("Walter Purcaro")
- __author_mail__ = ("vuolter@gmail.com")
+ __pattern__ = r'http://(?:www\.)?sockshare\.com/(mobile/)?(file|embed)/(?P<ID>\w+)'
+ __version__ = "0.02"
+ __description__ = """Sockshare.com hoster plugin"""
+ __author_name__ = ("jeix", "stickell", "Walter Purcaro")
+ __author_mail__ = ("", "l.stickell@yahoo.it", "vuolter@gmail.com")
+
+ FILE_INFO_PATTERN = r'site-content">\s*<h1>(?P<N>.+)<strong>\( (?P<S>[^)]+) \)</strong></h1>'
+ FILE_OFFLINE_PATTERN = r'>This file doesn\'t exist, or has been removed.<'
FILE_URL_REPLACEMENTS = [(__pattern__, r'http://www.sockshare.com/file/\g<ID>')]
- HOSTER_NAME = "sockshare.com"
+
+ def setup(self):
+ self.multiDL = self.resumeDownload = True
+ self.chunkLimit = -1
+
+ def handleFree(self):
+ name = self.pyfile.name
+ link = self._getLink()
+ self.logDebug("Direct link: " + link)
+ self.download(link, disposition=True)
+ self.processName(name)
+
+ def _getLink(self):
+ hash_data = re.search(r'<input type="hidden" value="([a-z0-9]+)" name="hash">', self.html)
+ if not hash_data:
+ self.parseError("Unable to detect hash")
+
+ post_data = {"hash": hash_data.group(1), "confirm": "Continue+as+Free+User"}
+ self.html = self.load(self.pyfile.url, post=post_data)
+ if (">You have exceeded the daily stream limit for your country\\. You can wait until tomorrow" in self.html or
+ "(>This content server has been temporarily disabled for upgrades|Try again soon\\. You can still download it below\\.<)" in self.html):
+ self.retry(wait_time=60 * 60 * 2, reason="Download limit exceeded or server disabled") # 2 hours wait
+
+ patterns = (r'(/get_file\.php\?id=[A-Z0-9]+&key=[a-zA-Z0-9=]+&original=1)',
+ r'(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+)',
+ r'(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+&original=1)',
+ r'<a href="/gopro\.php">Tired of ads and waiting\? Go Pro!</a>[\t\n\rn ]+</div>[\t\n\rn ]+<a href="(/.*?)"')
+ for pattern in patterns:
+ link = re.search(pattern, self.html)
+ if link:
+ break
+ else:
+ link = re.search(r"playlist: '(/get_file\.php\?stream=[a-zA-Z0-9=]+)'", self.html)
+ if link:
+ self.html = self.load("http://www.sockshare.com" + link.group(1))
+ link = re.search(r'media:content url="(http://.*?)"', self.html)
+ if not link:
+ link = re.search(r'\"(http://media\\-b\\d+\\.sockshare\\.com/download/\\d+/.*?)\"', self.html)
+ else:
+ self.parseError('Unable to detect a download link')
+
+ link = link.group(1).replace("&amp;", "&")
+ if link.startswith("http://"):
+ return link
+ else:
+ return "http://www.sockshare.com" + link
+
+ def processName(self, name_old):
+ name = self.pyfile.name
+ if name <= name_old:
+ return
+ name_new = re.sub(r'\.[^.]+$', "", name_old) + name[len(name_old):]
+ filename = self.lastDownload
+ self.pyfile.name = name_new
+ rename(filename, filename.rsplit(name)[0] + name_new)
+ self.logInfo("%(name)s renamed to %(newname)s" % {"name": name, "newname": name_new})
+
+
+getInfo = create_getInfo(SockshareCom)
diff --git a/module/plugins/hoster/UptoboxCom.py b/module/plugins/hoster/UptoboxCom.py
index 420610ee4..b4b35ab20 100644
--- a/module/plugins/hoster/UptoboxCom.py
+++ b/module/plugins/hoster/UptoboxCom.py
@@ -1,19 +1,42 @@
# -*- coding: utf-8 -*-
+###############################################################################
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @author: Walter Purcaro
+###############################################################################
+
from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo
class UptoboxCom(XFileSharingPro):
__name__ = "UptoboxCom"
__type__ = "hoster"
- __pattern__ = r"http://(?:\w*\.)*?uptobox.com/\w{12}"
- __version__ = "0.07"
+ __pattern__ = r'https?://(?:www\.)?uptobox\.com/\w+'
+ __version__ = "0.08"
__description__ = """Uptobox.com hoster plugin"""
- __author_name__ = ("zoidberg")
- __author_mail__ = ("zoidberg@mujmail.cz")
+ __author_name__ = "Walter Purcaro"
+ __author_mail__ = "vuolter@gmail.com"
- FILE_INFO_PATTERN = r'<div class="para_title">(?P<N>.+) \((?P<S>[^)]+)\)</div>'
- FILE_OFFLINE_PATTERN = r'<center>File Not Found</center>'
HOSTER_NAME = "uptobox.com"
+ FILE_INFO_PATTERN = r'"para_title">(?P<N>.+) \((?P<S>[\d\.]+) (?P<U>\w+)\)'
+ FILE_OFFLINE_PATTERN = r'>(File not found|Access Denied|404 Not Found)'
+ TEMP_OFFLINE_PATTERN = r'>This server is in maintenance mode'
+
+ WAIT_PATTERN = r'>(\d+)</span> seconds<'
+
+ DIRECT_LINK_PATTERN = r'"(https?://\w+\.uptobox\.com/d/.*?)"'
+
getInfo = create_getInfo(UptoboxCom)
diff --git a/module/plugins/hoster/XFileSharingPro.py b/module/plugins/hoster/XFileSharingPro.py
index 5b167c3c9..c4c05f604 100644
--- a/module/plugins/hoster/XFileSharingPro.py
+++ b/module/plugins/hoster/XFileSharingPro.py
@@ -1,27 +1,27 @@
# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: zoidberg
-"""
+###############################################################################
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License,
+# or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# @author: zoidberg
+###############################################################################
import re
from random import random
from urllib import unquote
from urlparse import urlparse
from pycurl import FOLLOWLOCATION, LOW_SPEED_TIME
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, PluginParseError
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, PluginParseError, replace_patterns
from module.plugins.internal.CaptchaService import ReCaptcha, SolveMedia
from module.utils import html_unescape
from module.network.RequestFactory import getURL
@@ -36,7 +36,7 @@ class XFileSharingPro(SimpleHoster):
__name__ = "XFileSharingPro"
__type__ = "hoster"
__pattern__ = r"^unmatchable$"
- __version__ = "0.25"
+ __version__ = "0.27"
__description__ = """XFileSharingPro common hoster base"""
__author_name__ = ("zoidberg", "stickell")
__author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it")
@@ -44,10 +44,10 @@ class XFileSharingPro(SimpleHoster):
FILE_NAME_PATTERN = r'<input type="hidden" name="fname" value="(?P<N>[^"]+)"'
FILE_SIZE_PATTERN = r'You have requested <font color="red">[^<]+</font> \((?P<S>[^<]+)\)</font>'
FILE_INFO_PATTERN = r'<tr><td align=right><b>Filename:</b></td><td nowrap>(?P<N>[^<]+)</td></tr>\s*.*?<small>\((?P<S>[^<]+)\)</small>'
- FILE_OFFLINE_PATTERN = r'<(b|h[1-6])>File Not Found</(b|h[1-6])>|This file has been removed'
+ FILE_OFFLINE_PATTERN = r'>\w+ (Not Found|file (was|has been) removed)'
WAIT_PATTERN = r'<span id="countdown_str">.*?>(\d+)</span>'
- LONG_WAIT_PATTERN = r'(?P<H>\d+(?=\s*hour))?.*?(?P<M>\d+(?=\s*minute))?.*?(?P<S>\d+(?=\s*second))?'
+ #LONG_WAIT_PATTERN = r'(?P<H>\d+(?=\s*hour))?.*?(?P<M>\d+(?=\s*minute))?.*?(?P<S>\d+(?=\s*second))?'
OVR_DOWNLOAD_LINK_PATTERN = r'<h2>Download Link</h2>\s*<textarea[^>]*>([^<]+)'
OVR_KILL_LINK_PATTERN = r'<h2>Delete Link</h2>\s*<textarea[^>]*>([^<]+)'
CAPTCHA_URL_PATTERN = r'(http://[^"\']+?/captchas?/[^"\']+)'
@@ -68,7 +68,9 @@ class XFileSharingPro(SimpleHoster):
def process(self, pyfile):
self.prepare()
- if not re.match(self.__pattern__, self.pyfile.url):
+ pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS)
+
+ if not re.match(self.__pattern__, pyfile.url):
if self.premium:
self.handleOverriden()
else:
@@ -128,7 +130,7 @@ class XFileSharingPro(SimpleHoster):
self.startDownload(url)
def getDownloadLink(self):
- for i in range(5):
+ for i in xrange(5):
self.logDebug("Getting download link: #%d" % i)
data = self.getPostParameters()
@@ -223,8 +225,8 @@ class XFileSharingPro(SimpleHoster):
self.setWait(3600, True)
self.wait()
self.retry(25)
- elif 'countdown' in self.errmsg or 'Expired session' in self.errmsg:
- self.retry(3)
+ elif 'countdown' in self.errmsg or 'Expired' in self.errmsg:
+ self.retry()
elif 'maintenance' in self.errmsg:
self.tempOffline()
elif 'download files up to' in self.errmsg:
@@ -238,7 +240,7 @@ class XFileSharingPro(SimpleHoster):
return self.errmsg
def getPostParameters(self):
- for _ in range(3):
+ for _ in xrange(3):
if not self.errmsg:
self.checkErrors()
diff --git a/module/plugins/hoster/ZDF.py b/module/plugins/hoster/ZDF.py
index 9940fd078..e45717186 100644
--- a/module/plugins/hoster/ZDF.py
+++ b/module/plugins/hoster/ZDF.py
@@ -10,7 +10,7 @@ class ZDF(Hoster):
# Based on zdfm by Roland Beermann
# http://github.com/enkore/zdfm/
__name__ = "ZDF Mediathek"
- __version__ = "0.7"
+ __version__ = "0.8"
__pattern__ = r"http://www\.zdf\.de/ZDFmediathek/[^0-9]*([0-9]+)[^0-9]*"
__config__ = []
@@ -23,11 +23,12 @@ class ZDF(Hoster):
@staticmethod
def video_valid(video):
- return video.findtext("url").startswith("http") and video.findtext("url").endswith(".mp4")
+ return video.findtext("url").startswith("http") and video.findtext("url").endswith(".mp4") and \
+ video.findtext("facets/facet").startswith("progressive")
@staticmethod
def get_id(url):
- return int(re.search(r"[^0-9]*([0-9]+)[^0-9]*", url).group(1))
+ return int(re.search(r"[^0-9]*([0-9]{4,})[^0-9]*", url).group(1))
def process(self, pyfile):
xml = fromstring(self.load(XML_API % self.get_id(pyfile.url)))
diff --git a/module/plugins/hoster/ZippyshareCom.py b/module/plugins/hoster/ZippyshareCom.py
index e4f2befa0..5983627d5 100644
--- a/module/plugins/hoster/ZippyshareCom.py
+++ b/module/plugins/hoster/ZippyshareCom.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Test links (random.bin):
-# http://www29.zippyshare.com/v/55578602/file.html
+# http://www8.zippyshare.com/v/3120421/file.html
import re
import subprocess
@@ -18,7 +17,7 @@ class ZippyshareCom(SimpleHoster):
__name__ = "ZippyshareCom"
__type__ = "hoster"
__pattern__ = r"(?P<HOST>http://www\d{0,2}\.zippyshare.com)/v(?:/|iew.jsp.*key=)(?P<KEY>\d+)"
- __version__ = "0.42"
+ __version__ = "0.46"
__description__ = """Zippyshare.com Download Hoster"""
__author_name__ = ("spoob", "zoidberg", "stickell")
__author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it")
@@ -31,7 +30,7 @@ class ZippyshareCom(SimpleHoster):
SH_COOKIES = [('zippyshare.com', 'ziplocale', 'en')]
- DOWNLOAD_URL_PATTERN = r"<script type=\"text/javascript\">([^<]*?)(document\.getElementById\('dlbutton'\).href = [^;]+;)"
+ DOWNLOAD_URL_PATTERN = r"<script type=\"text/javascript\">([^<]*?)(document\.getElementById\('dlbutton'\).href\s*=\s*[^;]+;)"
SEED_PATTERN = r'swfobject.embedSWF\("([^"]+)".*?seed: (\d+)'
CAPTCHA_KEY_PATTERN = r'Recaptcha.create\("([^"]+)"'
CAPTCHA_SHORTENCODE_PATTERN = r"shortencode: '([^']+)'"
@@ -66,8 +65,6 @@ class ZippyshareCom(SimpleHoster):
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
- url = None
-
found = re.search(self.DOWNLOAD_URL_PATTERN, self.html, re.S)
#Method #1: JS eval
if found and re.search(r'span id="omg" class="(\d*)"', self.html):
@@ -84,7 +81,8 @@ class ZippyshareCom(SimpleHoster):
omg = re.search(regex + r" = ([^;]+);", js).group(1)
js = re.sub(regex + r" = ([^;]+);", '', js)
js = re.sub(regex, omg, js)
- js = re.sub(r"document.getElementById\(\\*'dlbutton\\*'\).href = ", '', js)
+ js = re.sub(r"document.getElementById\(\\*'dlbutton\\*'\).href\s*= ", '', js)
+ js = re.sub(r"(?i)(function som(e|d)Function\(\) {)|(var som(e|d)function = function\(\) {)", '', js)
url = self.js.eval(js)
elif found and re.search(r"document.getElementById\(\\*'dlbutton\\*'\).href = \"", self.html):
js = "\n".join(found.groups())
@@ -210,7 +208,7 @@ class ZippyshareCom(SimpleHoster):
'response': code,
'shortencode': shortencode}))
self.logDebug("reCaptcha response : %s" % response)
- if response == True:
+ if response:
self.correctCaptcha()
break
else: