diff options
Diffstat (limited to 'pyload/plugins')
53 files changed, 703 insertions, 380 deletions
diff --git a/pyload/plugins/Crypter.py b/pyload/plugins/Crypter.py index 2a65a9da2..af3d5aba7 100644 --- a/pyload/plugins/Crypter.py +++ b/pyload/plugins/Crypter.py @@ -3,10 +3,9 @@ from pyload.Api import LinkStatus, DownloadStatus as DS from pyload.utils import to_list, has_method, uniqify from pyload.utils.fs import exists, remove, fs_encode -from pyload.utils.packagetools import parseNames - from Base import Base, Retry + class Package: """ Container that indicates that a new package should be created """ @@ -186,15 +185,6 @@ class Crypter(Base): """ raise NotImplementedError - def generatePackages(self, urls): - """Generates :class:`Package` instances and names from urls. Useful for many different links and no\ - given package name. - - :param urls: list of urls - :return: list of `Package` - """ - return [Package(name, purls) for name, purls in parseNames([(url, url) for url in urls]).iteritems()] - def _decrypt(self, urls): """Internal method to select decrypting method @@ -205,16 +195,9 @@ class Crypter(Base): # separate local and remote files content, urls = self.getLocalContent(urls) + result = [] - if has_method(cls, "decryptURLs"): - self.setup() - result = to_list(self.decryptURLs(urls)) - elif has_method(cls, "decryptURL"): - result = [] - for url in urls: - self.setup() - result.extend(to_list(self.decryptURL(url))) - elif has_method(cls, "decrypt"): + if urls and has_method(cls, "decrypt"): self.logDebug("Deprecated .decrypt() method in Crypter plugin") result = [] for url in urls: @@ -222,20 +205,28 @@ class Crypter(Base): self.setup() self.decrypt(self.pyfile) result.extend(self.convertPackages()) - else: - if not has_method(cls, "decryptFile") or urls: - self.logDebug("No suited decrypting method was overwritten in plugin") - result = [] - - if has_method(cls, "decryptFile"): - for f, c in content: + elif urls: + method = True + try: self.setup() - result.extend(to_list(self.decryptFile(c))) - try: - if f.startswith("tmp_"): remove(f) - except IOError: - self.logWarning(_("Could not remove file '%s'") % f) - self.core.print_exc() + result = to_list(self.decryptURLs(urls)) + except NotImplementedError: + method = False + + # this will raise error if not implemented + if not method: + for url in urls: + self.setup() + result.extend(to_list(self.decryptURL(url))) + + for f, c in content: + self.setup() + result.extend(to_list(self.decryptFile(c))) + try: + if f.startswith("tmp_"): remove(f) + except IOError: + self.logWarning(_("Could not remove file '%s'") % f) + self.core.print_exc() return result diff --git a/pyload/plugins/accounts/DdlstorageCom.py b/pyload/plugins/accounts/DdlstorageCom.py index 6c610aa84..7404348a4 100644 --- a/pyload/plugins/accounts/DdlstorageCom.py +++ b/pyload/plugins/accounts/DdlstorageCom.py @@ -1,13 +1,51 @@ # -*- coding: utf-8 -*- +from hashlib import md5 +from time import mktime, strptime + from module.plugins.internal.XFSPAccount import XFSPAccount +from module.common.json_layer import json_loads +from module.utils import parseFileSize + +# DDLStorage API Documentation: +# http://www.ddlstorage.com/cgi-bin/api_req.cgi?req_type=doc class DdlstorageCom(XFSPAccount): __name__ = "DdlstorageCom" - __version__ = "0.01" + __version__ = "1.00" __type__ = "account" __description__ = """DDLStorage.com account plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") MAIN_PAGE = "http://ddlstorage.com/" + + def loadAccountInfo(self, user, req): + password = self.accounts[user]['password'] + api_data = req.load('http://www.ddlstorage.com/cgi-bin/api_req.cgi', + post={'req_type': 'user_info', + 'client_id': 53472, + 'user_login': user, + 'user_password': md5(password).hexdigest(), + 'sign': md5('user_info%d%s%s%s' % (53472, user, md5(password).hexdigest(), + '25JcpU2dPOKg8E2OEoRqMSRu068r0Cv3')).hexdigest()}) + api_data = api_data.replace('<pre>', '').replace('</pre>', '') + self.logDebug('Account Info API data: ' + api_data) + api_data = json_loads(api_data) + + if api_data['status'] != 'OK': # 'status' must be always OK for a working account + return {"premium": False, "valid": False} + + if api_data['account_type'] == 'REGISTERED': + premium = False + validuntil = None + else: + premium = True + validuntil = int(mktime(strptime(api_data['premium_expire'], "%Y-%m-%d %H:%M:%S"))) + + if api_data['usr_bandwidth_available'] == 'UNLIMITED': + trafficleft = -1 + else: + trafficleft = parseFileSize(api_data['usr_bandwidth_available']) / 1024 + + return {"premium": premium, "validuntil": validuntil, "trafficleft": trafficleft} diff --git a/pyload/plugins/accounts/FilebeerInfo.py b/pyload/plugins/accounts/FilebeerInfo.py deleted file mode 100644 index 3c3a9edfd..000000000 --- a/pyload/plugins/accounts/FilebeerInfo.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- 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 -""" - -import re -from time import mktime, strptime -from module.plugins.Account import Account - - -class FilebeerInfo(Account): - __name__ = "FilebeerInfo" - __version__ = "0.02" - __type__ = "account" - __description__ = """filebeer.info account plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") - - VALID_UNTIL_PATTERN = r'Reverts To Free Account:\s</td>\s*<td>\s*(.*?)\s*</td>' - - def loadAccountInfo(self, user, req): - html = req.load("http://filebeer.info/upgrade.php", decode=True) - premium = not 'Free User </td>' in html - - validuntil = None - if premium: - try: - validuntil = mktime(strptime(re.search(self.VALID_UNTIL_PATTERN, html).group(1), "%d/%m/%Y %H:%M:%S")) - except Exception, e: - self.logError("Unable to parse account info", e) - - return {"validuntil": validuntil, "trafficleft": -1, "premium": premium} - - def login(self, user, data, req): - html = req.load('http://filebeer.info/login.php', post={ - "submit": 'Login', - "loginPassword": data['password'], - "loginUsername": user, - "submitme": '1' - }, decode=True) - - if "<ul class='pageErrors'>" in html or ">Your username and password are invalid<" in html: - self.wrongPassword() diff --git a/pyload/plugins/accounts/FilecloudIo.py b/pyload/plugins/accounts/FilecloudIo.py index 5de722ea7..93ae02006 100644 --- a/pyload/plugins/accounts/FilecloudIo.py +++ b/pyload/plugins/accounts/FilecloudIo.py @@ -18,18 +18,41 @@ """ from module.plugins.Account import Account +from module.common.json_layer import json_loads class FilecloudIo(Account): __name__ = "FilecloudIo" - __version__ = "0.01" + __version__ = "0.02" __type__ = "account" __description__ = """FilecloudIo account plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") + __author_name__ = ("zoidberg", "stickell") + __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") def loadAccountInfo(self, user, req): - return {"validuntil": -1, "trafficleft": -1, "premium": False} + # It looks like the first API request always fails, so we retry 5 times, it should work on the second try + for _ in range(5): + rep = req.load("https://secure.filecloud.io/api-fetch_apikey.api", + post={"username": user, "password": self.accounts[user]['password']}) + rep = json_loads(rep) + if rep['status'] == 'ok': + break + elif rep['status'] == 'error' and rep['message'] == 'no such user or wrong password': + self.logError("Wrong username or password") + return {"valid": False, "premium": False} + else: + return {"premium": False} + + akey = rep['akey'] + self.accounts[user]['akey'] = akey # Saved for hoster plugin + rep = req.load("http://api.filecloud.io/api-fetch_account_details.api", + post={"akey": akey}) + rep = json_loads(rep) + + if rep['is_premium'] == 1: + return {"validuntil": int(rep["premium_until"]), "trafficleft": -1} + else: + return {"premium": False} def login(self, user, data, req): req.cj.setCookie("secure.filecloud.io", "lang", "en") diff --git a/pyload/plugins/accounts/SpeedLoadOrg.py b/pyload/plugins/accounts/SpeedLoadOrg.py deleted file mode 100644 index bb9fb05fb..000000000 --- a/pyload/plugins/accounts/SpeedLoadOrg.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -from module.plugins.internal.XFSPAccount import XFSPAccount - - -class SpeedLoadOrg(XFSPAccount): - __name__ = "SpeedLoadOrg" - __version__ = "0.01" - __type__ = "account" - __description__ = """SpeedLoadOrg account plugin""" - __author_name__ = ("stickell") - __author_mail__ = ("l.stickell@yahoo.it") - - MAIN_PAGE = "http://speedload.org/" diff --git a/pyload/plugins/addons/Captcha9kw.py b/pyload/plugins/addons/Captcha9kw.py index e13f93dec..d6fef549f 100755 --- a/pyload/plugins/addons/Captcha9kw.py +++ b/pyload/plugins/addons/Captcha9kw.py @@ -19,11 +19,9 @@ from __future__ import with_statement from thread import start_new_thread from base64 import b64encode -import cStringIO -import pycurl import time -from module.network.RequestFactory import getURL, getRequest +from module.network.RequestFactory import getURL from module.network.HTTPRequest import BadHeader from module.plugins.Hook import Hook @@ -31,7 +29,7 @@ from module.plugins.Hook import Hook class Captcha9kw(Hook): __name__ = "Captcha9kw" - __version__ = "0.07" + __version__ = "0.08" __description__ = """send captchas to 9kw.eu""" __config__ = [("activated", "bool", "Activated", False), ("force", "bool", "Force CT even if client is connected", True), @@ -39,6 +37,8 @@ class Captcha9kw(Hook): ("confirm", "bool", "Confirm Captcha (Cost +6)", "False"), ("captchaperhour", "int", "Captcha per hour (max. 9999)", "9999"), ("prio", "int", "Prio 1-10 (Cost +1-10)", "0"), + ("selfsolve", "bool", + "If enabled and you have a 9kw client active only you will get your captcha to solve it", "False"), ("timeout", "int", "Timeout (max. 300)", "220"), ("passkey", "password", "API key", ""), ] __author_name__ = ("RaNaN") @@ -80,6 +80,7 @@ class Captcha9kw(Hook): "confirm": self.getConfig("confirm"), "captchaperhour": self.getConfig("captchaperhour"), "maxtimeout": self.getConfig("timeout"), + "selfsolve": self.getConfig("selfsolve"), "pyload": "1", "source": "pyload", "base64": "1", diff --git a/pyload/plugins/addons/Checksum.py b/pyload/plugins/addons/Checksum.py index 08fd623b8..081e8ac3b 100644 --- a/pyload/plugins/addons/Checksum.py +++ b/pyload/plugins/addons/Checksum.py @@ -54,7 +54,7 @@ def computeChecksum(local_file, algorithm): class Checksum(Hook): __name__ = "Checksum" - __version__ = "0.08" + __version__ = "0.10" __description__ = "Verify downloaded file size and checksum (enable in general preferences)" __config__ = [("activated", "bool", "Activated", True), ("action", "fail;retry;nothing", "What to do if check fails?", "retry"), diff --git a/pyload/plugins/crypter/FilebeerInfoFolder.py b/pyload/plugins/crypter/FilebeerInfoFolder.py index 86ce5b697..b6bf4fd07 100644 --- a/pyload/plugins/crypter/FilebeerInfoFolder.py +++ b/pyload/plugins/crypter/FilebeerInfoFolder.py @@ -1,36 +1,14 @@ # -*- coding: utf-8 -*- -import re -from module.plugins.Crypter import Crypter +from module.plugins.internal.DeadCrypter import DeadCrypter -class FilebeerInfoFolder(Crypter): +class FilebeerInfoFolder(DeadCrypter): __name__ = "FilebeerInfoFolder" __type__ = "crypter" __pattern__ = r"http://(?:www\.)?filebeer\.info/(\d+~f).*" - __version__ = "0.01" + __version__ = "0.02" __description__ = """Filebeer.info Folder Plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") - LINK_PATTERN = r'<td title="[^"]*"><a href="([^"]+)" target="_blank">' - PAGE_COUNT_PATTERN = r'<p class="introText">\s*Total Pages (\d+)' - - def decrypt(self, pyfile): - pyfile.url = re.sub(self.__pattern__, r'http://filebeer.info/\1?page=1', pyfile.url) - html = self.load(pyfile.url) - - page_count = int(re.search(self.PAGE_COUNT_PATTERN, html).group(1)) - new_links = [] - - for i in range(1, page_count + 1): - self.logInfo("Fetching links from page %i" % i) - new_links.extend(re.findall(self.LINK_PATTERN, html)) - - if i < page_count: - html = self.load("%s?page=%d" % (pyfile.url, i + 1)) - - if new_links: - self.core.files.addLinks(new_links, self.pyfile.package().id) - else: - self.fail('Could not extract any links') diff --git a/pyload/plugins/crypter/FiletramCom.py b/pyload/plugins/crypter/FiletramCom.py new file mode 100644 index 000000000..886b8be30 --- /dev/null +++ b/pyload/plugins/crypter/FiletramCom.py @@ -0,0 +1,31 @@ +# -*- 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/>. # +############################################################################ + +from module.plugins.internal.SimpleCrypter import SimpleCrypter + + +class FiletramCom(SimpleCrypter): + __name__ = "FiletramCom" + __type__ = "crypter" + __pattern__ = r"http://(?:www\.)?filetram.com/[^/]+/.+" + __version__ = "0.01" + __description__ = """Filetram.com Plugin""" + __author_name__ = ("igel", "stickell") + __author_mail__ = ("igelkun@myopera.com", "l.stickell@yahoo.it") + + LINK_PATTERN = r"\s+(http://.+)" + TITLE_PATTERN = r"<title>(?P<title>[^<]+) - Free Download[^<]*</title>" diff --git a/pyload/plugins/crypter/LofCc.py b/pyload/plugins/crypter/LofCc.py index ec9cdaac6..5fee776c7 100644 --- a/pyload/plugins/crypter/LofCc.py +++ b/pyload/plugins/crypter/LofCc.py @@ -5,14 +5,14 @@ import re from os.path import join from module.plugins.Crypter import Crypter -from module.plugins.ReCaptcha import ReCaptcha +from module.plugins.internal.CaptchaService import ReCaptcha class LofCc(Crypter): __name__ = "LofCc" __type__ = "container" __pattern__ = r"http://lof.cc/(.*)" - __version__ = "0.1" + __version__ = "0.2" __description__ = """lof.cc Plugin""" __author_name__ = ("mkaay") __author_mail__ = ("mkaay@mkaay.de") diff --git a/pyload/plugins/crypter/NCryptIn.py b/pyload/plugins/crypter/NCryptIn.py index 6e0c35e92..170a5291d 100644 --- a/pyload/plugins/crypter/NCryptIn.py +++ b/pyload/plugins/crypter/NCryptIn.py @@ -6,17 +6,17 @@ import re from Crypto.Cipher import AES from module.plugins.Crypter import Crypter -from module.plugins.ReCaptcha import ReCaptcha +from module.plugins.internal.CaptchaService import ReCaptcha class NCryptIn(Crypter): __name__ = "NCryptIn" __type__ = "crypter" - __pattern__ = r"http://(?:www\.)?ncrypt.in/folder-([^/\?]+)" - __version__ = "1.23" + __pattern__ = r"http://(?:www\.)?ncrypt.in/(?P<type>folder|link|frame)-([^/\?]+)" + __version__ = "1.25" __description__ = """NCrypt.in Crypter Plugin""" - __author_name__ = ("fragonib") - __author_mail__ = ("fragonib[AT]yahoo[DOT]es") + __author_name__ = ("fragonib", "stickell") + __author_mail__ = ("fragonib[AT]yahoo[DOT]es", "l.stickell@yahoo.it") # Constants _JK_KEY_ = "jk" @@ -33,31 +33,46 @@ class NCryptIn(Crypter): # Init self.package = pyfile.package() - # Request package - self.html = self.load(self.pyfile.url) - self.cleanedHtml = self.removeCrap(self.html) - if not self.isOnline(): - self.offline() - - # Check for protection - if self.isProtected(): - self.html = self.unlockProtection() + self.type = re.search(self.__pattern__, pyfile.url).group('type') + if self.type in ('link', 'frame'): + self.handleSingle() + else: + # Request package + self.html = self.load(self.pyfile.url) self.cleanedHtml = self.removeCrap(self.html) - self.handleErrors() - - # Get package name and folder - (package_name, folder_name) = self.getPackageInfo() - - # Extract package links - package_links = [] - package_links.extend(self.handleWebLinks()) - package_links.extend(self.handleContainers()) - package_links.extend(self.handleCNL2()) - package_links = self.removeContainers(package_links) - package_links = set(package_links) - - # Pack - self.packages = [(package_name, package_links, folder_name)] + if not self.isOnline(): + self.offline() + + # Check for protection + if self.isProtected(): + self.html = self.unlockProtection() + self.cleanedHtml = self.removeCrap(self.html) + self.handleErrors() + + # Get package name and folder + (package_name, folder_name) = self.getPackageInfo() + + # Extract package links + package_links = [] + package_links.extend(self.handleWebLinks()) + package_links.extend(self.handleContainers()) + package_links.extend(self.handleCNL2()) + package_links = self.removeContainers(package_links) + package_links = set(package_links) + + # Pack + self.packages = [(package_name, package_links, folder_name)] + + def handleSingle(self): + if self.type == 'link': + self.pyfile.url = self.pyfile.url.replace('link', 'frame') + header = self.load(self.pyfile.url, just_header=True) + if 'location' not in header: + self.fail("Unable to decrypt link") + loc = header['location'] + self.logDebug("Link decrypted: " + loc) + self.package_links = [loc] + self.packages = [(self.package.name, self.package_links, self.package.folder)] def removeCrap(self, content): patterns = (r'(type="hidden".*?(name=".*?")?.*?value=".*?")', diff --git a/pyload/plugins/crypter/SpeedLoadOrgFolder.py b/pyload/plugins/crypter/SpeedLoadOrgFolder.py index 8223eb7b9..7472e28fe 100644 --- a/pyload/plugins/crypter/SpeedLoadOrgFolder.py +++ b/pyload/plugins/crypter/SpeedLoadOrgFolder.py @@ -15,17 +15,14 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################ -from module.plugins.internal.SimpleCrypter import SimpleCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter -class SpeedLoadOrgFolder(SimpleCrypter): +class SpeedLoadOrgFolder(DeadCrypter): __name__ = "SpeedLoadOrgFolder" __type__ = "crypter" __pattern__ = r"http://(www\.)?speedload\.org/(\d+~f$|folder/\d+/)" - __version__ = "0.2" + __version__ = "0.3" __description__ = """Speedload Crypter Plugin""" __author_name__ = ("stickell") __author_mail__ = ("l.stickell@yahoo.it") - - LINK_PATTERN = r'<div class="link"><a href="(http://speedload.org/\w+)"' - TITLE_PATTERN = r'<title>Files of: (?P<title>[^<]+) folder</title>' diff --git a/pyload/plugins/crypter/TurbobitNetFolder.py b/pyload/plugins/crypter/TurbobitNetFolder.py new file mode 100644 index 000000000..e172f8037 --- /dev/null +++ b/pyload/plugins/crypter/TurbobitNetFolder.py @@ -0,0 +1,60 @@ +# -*- 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/>. # +############################################################################ + +import math +import re + +from module.plugins.internal.SimpleCrypter import SimpleCrypter +from module.common.json_layer import json_loads + + +def format_links(fid): + return 'http://turbobit.net/%s.html' % fid + + +class TurbobitNetFolder(SimpleCrypter): + __name__ = "TurbobitNetFolder" + __type__ = "crypter" + __pattern__ = r"http://(?:w{3}.)?turbobit\.net/download/folder/(?P<id>\w+)" + __version__ = "0.01" + __description__ = """Turbobit.net Folder Plugin""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + TITLE_PATTERN = r"<img src='/js/lib/grid/icon/folder.png'>(?P<title>.+)</div>" + + def getLinks(self): + folder_id = re.search(self.__pattern__, self.pyfile.url).group('id') + grid = self.load('http://turbobit.net/downloadfolder/gridFile', + get={'id_folder': folder_id, 'rows': 200}, decode=True) + grid = json_loads(grid) + + links_count = grid["records"] + pages = int(math.ceil(links_count / 200.0)) + + ids = list() + for i in grid['rows']: + ids.append(i['id']) + + for p in range(2, pages + 1): + grid = self.load('http://turbobit.net/downloadfolder/gridFile', + get={'id_folder': folder_id, 'rows': 200, 'page': p}, decode=True) + grid = json_loads(grid) + for i in grid['rows']: + ids.append(i['id']) + + return map(format_links, ids) diff --git a/pyload/plugins/crypter/XupPl.py b/pyload/plugins/crypter/XupPl.py new file mode 100644 index 000000000..09832f037 --- /dev/null +++ b/pyload/plugins/crypter/XupPl.py @@ -0,0 +1,18 @@ +from module.plugins.Crypter import Crypter + + +class XupPl(Crypter): + __name__ = "XupPl" + __type__ = "crypter" + __pattern__ = r"https?://.*\.xup\.pl/.*" + __version__ = "0.1" + __description__ = """Xup.pl Crypter Plugin""" + __author_name__ = ("z00nx") + __author_mail__ = ("z00nx0@gmail.com") + + def decrypt(self, pyfile): + header = self.load(self.pyfile.url, just_header=True) + if 'location' in header: + self.core.files.addLinks([header['location']], self.pyfile.package().id) + else: + self.fail('Unable to find link') diff --git a/pyload/plugins/hoster/CzshareCom.py b/pyload/plugins/hoster/CzshareCom.py index 8f6f76d84..fdfce6226 100644 --- a/pyload/plugins/hoster/CzshareCom.py +++ b/pyload/plugins/hoster/CzshareCom.py @@ -48,7 +48,7 @@ class CzshareCom(SimpleHoster): USER_CREDIT_PATTERN = r'<div class="credit">\s*kredit: <strong>([0-9., ]+)([kKMG]i?B)</strong>\s*</div><!-- .credit -->' def setup(self): - self.multiDL = self.resumeDownload = True if self.premium else False + self.multiDL = self.resumeDownload = self.premium self.chunkLimit = 1 def checkTrafficLeft(self): diff --git a/pyload/plugins/hoster/DailymotionCom.py b/pyload/plugins/hoster/DailymotionCom.py index ab8ff7910..7d33540f8 100644 --- a/pyload/plugins/hoster/DailymotionCom.py +++ b/pyload/plugins/hoster/DailymotionCom.py @@ -36,7 +36,8 @@ class DailymotionCom(Hoster): for quality in ('hd720URL', 'hqURL', 'sdURL', 'ldURL', ''): dlLink = self.getQuality(quality, allLinksInfo) - if dlLink is not None: break + if dlLink is not None: + break else: self.fail(r'Unable to find video URL') diff --git a/pyload/plugins/hoster/DdlstorageCom.py b/pyload/plugins/hoster/DdlstorageCom.py index 5eaebf1d1..82072aadb 100644 --- a/pyload/plugins/hoster/DdlstorageCom.py +++ b/pyload/plugins/hoster/DdlstorageCom.py @@ -1,13 +1,45 @@ # -*- coding: utf-8 -*- +import re +from hashlib import md5 -from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo +from module.plugins.hoster.XFileSharingPro import XFileSharingPro +from module.network.RequestFactory import getURL +from module.plugins.Plugin import chunks +from module.common.json_layer import json_loads + + +def getInfo(urls): + # DDLStorage API Documentation: + # http://www.ddlstorage.com/cgi-bin/api_req.cgi?req_type=doc + ids = dict() + for url in urls: + m = re.search(DdlstorageCom.__pattern__, url) + ids[m.group('ID')] = url + + for chunk in chunks(ids.keys(), 5): + api = getURL('http://www.ddlstorage.com/cgi-bin/api_req.cgi', + post={'req_type': 'file_info_free', + 'client_id': 53472, + 'file_code': ','.join(chunk), + 'sign': md5('file_info_free%d%s%s' % (53472, ','.join(chunk), + '25JcpU2dPOKg8E2OEoRqMSRu068r0Cv3')).hexdigest()}) + api = api.replace('<pre>', '').replace('</pre>', '') + api = json_loads(api) + + result = list() + for el in api: + if el['status'] == 'online': + result.append((el['file_name'], int(el['file_size']), 2, ids[el['file_code']])) + else: + result.append((ids[el['file_code']], 0, 1, ids[el['file_code']])) + yield result class DdlstorageCom(XFileSharingPro): __name__ = "DdlstorageCom" __type__ = "hoster" - __pattern__ = r"http://(?:\w*\.)*?ddlstorage.com/\w{12}" - __version__ = "0.07" + __pattern__ = r"http://(?:\w*\.)*?ddlstorage.com/(?P<ID>\w{12})" + __version__ = "1.00" __description__ = """DDLStorage.com hoster plugin""" __author_name__ = ("zoidberg", "stickell") __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") @@ -15,5 +47,38 @@ class DdlstorageCom(XFileSharingPro): FILE_INFO_PATTERN = r'<p class="sub_title"[^>]*>(?P<N>.+) \((?P<S>[^)]+)\)</p>' HOSTER_NAME = "ddlstorage.com" + def prepare(self): + self.getAPIData() + super(DdlstorageCom, self).prepare() + + def getAPIData(self): + file_id = re.search(self.__pattern__, self.pyfile.url).group('ID') + data = {'client_id': 53472, + 'file_code': file_id} + if self.user: + passwd = self.account.getAccountData(self.user)["password"] + data['req_type'] = 'file_info_reg' + data['user_login'] = self.user + data['user_password'] = md5(passwd).hexdigest() + data['sign'] = md5('file_info_reg%d%s%s%s%s' % (data['client_id'], data['user_login'], + data['user_password'], data['file_code'], + '25JcpU2dPOKg8E2OEoRqMSRu068r0Cv3')).hexdigest() + else: + data['req_type'] = 'file_info_free' + data['sign'] = md5('file_info_free%d%s%s' % (data['client_id'], data['file_code'], + '25JcpU2dPOKg8E2OEoRqMSRu068r0Cv3')).hexdigest() + + self.api_data = self.load('http://www.ddlstorage.com/cgi-bin/api_req.cgi', post=data) + self.api_data = self.api_data.replace('<pre>', '').replace('</pre>', '') + self.logDebug('API Data: ' + self.api_data) + self.api_data = json_loads(self.api_data)[0] + + if self.api_data['status'] == 'offline': + self.offline() -getInfo = create_getInfo(DdlstorageCom)
\ No newline at end of file + if 'file_name' in self.api_data: + self.pyfile.name = self.api_data['file_name'] + if 'file_size' in self.api_data: + self.pyfile.size = self.api_data['size'] = self.api_data['file_size'] + if 'file_md5_base64' in self.api_data: + self.api_data['md5_ddlstorage'] = self.api_data['file_md5_base64'] diff --git a/pyload/plugins/hoster/DlFreeFr.py b/pyload/plugins/hoster/DlFreeFr.py index 1f0e38acd..35b9ca6b8 100644 --- a/pyload/plugins/hoster/DlFreeFr.py +++ b/pyload/plugins/hoster/DlFreeFr.py @@ -119,8 +119,8 @@ class DlFreeFr(SimpleHoster): #FILE_URL_PATTERN = r'href="(?P<url>http://.*?)">Télécharger ce fichier' def setup(self): + self.multiDL = self.resumeDownload = True self.limitDL = 5 - self.resumeDownload = True self.chunkLimit = 1 def init(self): diff --git a/pyload/plugins/hoster/FilecloudIo.py b/pyload/plugins/hoster/FilecloudIo.py index 92735d579..c7684a05d 100644 --- a/pyload/plugins/hoster/FilecloudIo.py +++ b/pyload/plugins/hoster/FilecloudIo.py @@ -26,9 +26,9 @@ class FilecloudIo(SimpleHoster): __name__ = "FilecloudIo" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)*(?:filecloud\.io|ifile\.it|mihd\.net)/(?P<ID>\w+).*" - __version__ = "0.01" + __version__ = "0.02" __description__ = """Filecloud.io (formerly Ifile.it) plugin - free account only""" - __author_name__ = ("zoidberg") + __author_name__ = ("zoidberg", "stickell") FILE_SIZE_PATTERN = r'{var __ab1 = (?P<S>\d+);}' FILE_NAME_PATTERN = r'id="aliasSpan">(?P<N>.*?) <' @@ -109,5 +109,18 @@ class FilecloudIo(SimpleHoster): else: self.fail("Unexpected server response") + def handlePremium(self): + akey = self.account.getAccountData(self.user)['akey'] + ukey = self.file_info['ID'] + self.logDebug("Akey: %s | Ukey: %s" % (akey, ukey)) + rep = self.load("http://api.filecloud.io/api-fetch_download_url.api", + post={"akey": akey, "ukey": ukey}) + self.logDebug("FetchDownloadUrl: " + rep) + rep = json_loads(rep) + if rep['status'] == 'ok': + self.download(rep['download_url'], disposition=True) + else: + self.fail(rep['message']) + getInfo = create_getInfo(FilecloudIo) diff --git a/pyload/plugins/hoster/FileserveCom.py b/pyload/plugins/hoster/FileserveCom.py index e8e78f9b0..a9ff24d19 100644 --- a/pyload/plugins/hoster/FileserveCom.py +++ b/pyload/plugins/hoster/FileserveCom.py @@ -65,7 +65,7 @@ class FileserveCom(Hoster): # shares code with FilejungleCom and UploadstationCom def setup(self): - self.resumeDownload = self.multiDL = True if self.premium else False + self.resumeDownload = self.multiDL = self.premium self.file_id = re.search(self.__pattern__, self.pyfile.url).group('id') self.url = "%s%s" % (self.URLS[0], self.file_id) diff --git a/pyload/plugins/hoster/FileshareInUa.py b/pyload/plugins/hoster/FileshareInUa.py index d3724f728..11adc4e9c 100644 --- a/pyload/plugins/hoster/FileshareInUa.py +++ b/pyload/plugins/hoster/FileshareInUa.py @@ -19,8 +19,7 @@ class FileshareInUa(Hoster): PATTERN_OFFLINE = "This file doesn't exist, or has been removed." def setup(self): - self.resumeDownload = True - self.multiDL = True + self.resumeDownload = self.multiDL = True def process(self, pyfile): self.pyfile = pyfile diff --git a/pyload/plugins/hoster/FreevideoCz.py b/pyload/plugins/hoster/FreevideoCz.py index c5da074ed..3d8921c38 100644 --- a/pyload/plugins/hoster/FreevideoCz.py +++ b/pyload/plugins/hoster/FreevideoCz.py @@ -47,8 +47,7 @@ class FreevideoCz(Hoster): FILE_OFFLINE_PATTERN = r'<h2 class="red-corner-full">Str.nka nebyla nalezena</h2>' def setup(self): - self.multiDL = True - self.resumeDownload = True + self.multiDL = self.resumeDownload = True def process(self, pyfile): @@ -58,7 +57,8 @@ class FreevideoCz(Hoster): self.offline() found = re.search(self.URL_PATTERN, self.html) - if found is None: self.fail("Parse error (URL)") + if found is None: + self.fail("Parse error (URL)") download_url = found.group(1) pyfile.name = re.search(self.__pattern__, pyfile.url).group(1) + ".mp4" diff --git a/pyload/plugins/hoster/GamefrontCom.py b/pyload/plugins/hoster/GamefrontCom.py index a0ee03f26..c82cfdf50 100644 --- a/pyload/plugins/hoster/GamefrontCom.py +++ b/pyload/plugins/hoster/GamefrontCom.py @@ -8,7 +8,7 @@ class GamefrontCom(Hoster): __name__ = "GamefrontCom" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)*?gamefront.com/files/[A-Za-z0-9]+" - __version__ = "0.03" + __version__ = "0.04" __description__ = """gamefront.com hoster plugin""" __author_name__ = ("fwannmacher") __author_mail__ = ("felipe@warhammerproject.com") @@ -19,8 +19,8 @@ class GamefrontCom(Hoster): PATTERN_OFFLINE = "This file doesn't exist, or has been removed." def setup(self): - self.resumeDownload = True - self.multiDL = True + self.resumeDownload = self.multiDL = True + self.chunkLimit = -1 def process(self, pyfile): self.pyfile = pyfile diff --git a/pyload/plugins/hoster/GooIm.py b/pyload/plugins/hoster/GooIm.py new file mode 100644 index 000000000..f96e6e6cc --- /dev/null +++ b/pyload/plugins/hoster/GooIm.py @@ -0,0 +1,55 @@ +# -*- 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/>. # +############################################################################ + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class GooIm(SimpleHoster): + __name__ = "GooIm" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?goo\.im/.+" + __version__ = "0.02" + __description__ = """Goo.im hoster plugin""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_NAME_PATTERN = r'<h3>Filename: (?P<N>.+)</h3>' + FILE_OFFLINE_PATTERN = r'The file you requested was not found' + + def setup(self): + self.chunkLimit = -1 + self.multiDL = self.resumeDownload = True + + def handleFree(self): + self.html = self.load(self.pyfile.url) + m = re.search(r'MD5sum: (?P<MD5>[0-9a-z]{32})</h3>', self.html) + if m: + self.check_data = {"md5": m.group('MD5')} + self.setWait(10) + self.wait() + + header = self.load(self.pyfile.url, just_header=True) + if header['location']: + self.logDebug("Direct link: " + header['location']) + self.download(header['location']) + else: + self.parseError("Unable to detect direct download link") + + +getInfo = create_getInfo(GooIm) diff --git a/pyload/plugins/hoster/HotfileCom.py b/pyload/plugins/hoster/HotfileCom.py index 992899ef5..a7a46e03b 100644 --- a/pyload/plugins/hoster/HotfileCom.py +++ b/pyload/plugins/hoster/HotfileCom.py @@ -49,8 +49,7 @@ class HotfileCom(Hoster): self.url = None if self.premium: - self.multiDL = True - self.resumeDownload = True + self.multiDL = self.resumeDownload = True self.chunkLimit = -1 else: self.multiDL = False diff --git a/pyload/plugins/hoster/IfolderRu.py b/pyload/plugins/hoster/IfolderRu.py index dc1ef8fe2..14e568f8f 100644 --- a/pyload/plugins/hoster/IfolderRu.py +++ b/pyload/plugins/hoster/IfolderRu.py @@ -24,7 +24,7 @@ class IfolderRu(SimpleHoster): __name__ = "IfolderRu" __type__ = "hoster" __pattern__ = r"http://(?:[^.]*\.)?(?:ifolder\.ru|rusfolder\.(?:com|net|ru))/(?:files/)?(?P<ID>\d+).*" - __version__ = "0.37" + __version__ = "0.38" __description__ = """rusfolder.com / ifolder.ru""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") @@ -49,7 +49,7 @@ class IfolderRu(SimpleHoster): self.html = self.load("http://rusfolder.com/%s" % file_id, cookies=True, decode=True) self.getFileInfo() - url = re.search('<a href="(http://ints\..*?=)"', self.html).group(1) + url = re.search(r"location\.href = '(http://ints\..*?=)'", self.html).group(1) self.html = self.load(url, cookies=True, decode=True) url, session_id = re.search(self.SESSION_ID_PATTERN, self.html).groups() diff --git a/pyload/plugins/hoster/JumbofilesCom.py b/pyload/plugins/hoster/JumbofilesCom.py index 93885a6a3..1b8a2d73b 100644 --- a/pyload/plugins/hoster/JumbofilesCom.py +++ b/pyload/plugins/hoster/JumbofilesCom.py @@ -17,8 +17,7 @@ class JumbofilesCom(SimpleHoster): DIRECT_LINK_PATTERN = '<meta http-equiv="refresh" content="10;url=(.+)">' def setup(self): - self.resumeDownload = True - self.multiDL = True + self.resumeDownload = self.multiDL = True def handleFree(self): ukey = re.search(self.__pattern__, self.pyfile.url).group(1) diff --git a/pyload/plugins/hoster/Keep2shareCC.py b/pyload/plugins/hoster/Keep2shareCC.py new file mode 100644 index 000000000..5e4f5f540 --- /dev/null +++ b/pyload/plugins/hoster/Keep2shareCC.py @@ -0,0 +1,89 @@ +# -*- 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/>. # +############################################################################ + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.internal.CaptchaService import ReCaptcha + + +class Keep2shareCC(SimpleHoster): + __name__ = "Keep2shareCC" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?keep2share\.cc/file/\w+" + __version__ = "0.03" + __description__ = """Keep2share.cc hoster plugin""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_NAME_PATTERN = r'File: <span>(?P<N>.+)</span>' + FILE_SIZE_PATTERN = r'Size: (?P<S>[^<]+)</div>' + FILE_OFFLINE_PATTERN = r'File not found or deleted|Sorry, this file is blocked or deleted' + + 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' + + RECAPTCHA_KEY = '6LcYcN0SAAAAABtMlxKj7X0hRxOY8_2U86kI1vbb' + + def handleFree(self): + fid = re.search(r'<input type="hidden" name="slow_id" value="([^"]+)">', self.html).group(1) + self.html = self.load(self.pyfile.url, post={'yt0': '', 'slow_id': fid}) + + m = re.search(self.WAIT_PATTERN, self.html) + if m: + wait_string = m.group(1) + wait_time = int(wait_string[0:2]) * 3600 + int(wait_string[3:5]) * 60 + int(wait_string[6:8]) + self.setWait(wait_time, True) + self.wait() + self.process(self.pyfile) + + recaptcha = ReCaptcha(self) + for i in xrange(5): + challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY) + post_data = {'recaptcha_challenge_field': challenge, + 'recaptcha_response_field': response, + 'CaptchaForm%5Bcode%5D': '', + 'free': 1, + 'freeDownloadRequest': 1, + 'uniqueId': fid, + 'yt0': ''} + + self.html = self.load(self.pyfile.url, post=post_data) + + if 'recaptcha' not in self.html: + self.correctCaptcha() + self.setWait(30) + self.wait() + break + else: + self.logInfo('Wrong captcha') + self.invalidCaptcha() + else: + self.fail("All captcha attempts failed") + + self.html = self.load(self.pyfile.url, post={'uniqueId': fid, 'free': 1}) + + dl = 'http://keep2share.cc' + m = re.search(self.DIRECT_LINK_PATTERN, self.html) + if not m: + self.parseError("Unable to detect direct link") + dl += m.group(1) + self.logDebug('Direct Link: ' + dl) + self.download(dl, disposition=True) + + +getInfo = create_getInfo(Keep2shareCC) diff --git a/pyload/plugins/hoster/MediafireCom.py b/pyload/plugins/hoster/MediafireCom.py index 1e856c41d..494d0049e 100644 --- a/pyload/plugins/hoster/MediafireCom.py +++ b/pyload/plugins/hoster/MediafireCom.py @@ -36,7 +36,8 @@ def checkHTMLHeader(url): url = line.split(':', 1)[1].strip() if 'error.php?errno=320' in url: return url, 1 - if not url.startswith('http://'): url = 'http://www.mediafire.com' + url + if not url.startswith('http://'): + url = 'http://www.mediafire.com' + url break elif 'content-disposition' in line: return url, 2 @@ -114,7 +115,8 @@ class MediafireCom(SimpleHoster): self.fail("No or incorrect password") found = re.search(r'kNO = "(http://.*?)";', self.html) - if not found: self.parseError("Download URL") + if not found: + self.parseError("Download URL") download_url = found.group(1) self.logDebug("DOWNLOAD LINK:", download_url) diff --git a/pyload/plugins/hoster/MegaNz.py b/pyload/plugins/hoster/MegaNz.py index db97f6859..bf4223213 100644 --- a/pyload/plugins/hoster/MegaNz.py +++ b/pyload/plugins/hoster/MegaNz.py @@ -20,7 +20,7 @@ class MegaNz(Hoster): __name__ = "MegaNz" __type__ = "hoster" __pattern__ = r"https?://([a-z0-9]+\.)?mega\.co\.nz/#!([a-zA-Z0-9!_\-]+)" - __version__ = "0.13" + __version__ = "0.14" __description__ = """mega.co.nz hoster plugin""" __author_name__ = ("RaNaN", ) __author_mail__ = ("ranan@pyload.org", ) @@ -69,8 +69,11 @@ class MegaNz(Hoster): cipher = AES.new(self.getCipherKey(key), AES.MODE_CTR, counter=ctr) self.pyfile.setStatus("decrypting") - f = open(self.lastDownload, "rb") - df = open(self.lastDownload.rsplit(self.FILE_SUFFIX)[0], "wb") + + file_crypted = self.lastDownload + file_decrypted = file_crypted.rsplit(self.FILE_SUFFIX)[0] + f = open(file_crypted, "rb") + df = open(file_decrypted, "wb") # TODO: calculate CBC-MAC for checksum @@ -84,7 +87,9 @@ class MegaNz(Hoster): f.close() df.close() - remove(self.lastDownload) + remove(file_crypted) + + self.lastDownload = file_decrypted def process(self, pyfile): diff --git a/pyload/plugins/hoster/MegasharesCom.py b/pyload/plugins/hoster/MegasharesCom.py index 7d089f717..4e43d4a00 100644 --- a/pyload/plugins/hoster/MegasharesCom.py +++ b/pyload/plugins/hoster/MegasharesCom.py @@ -43,7 +43,7 @@ class MegasharesCom(SimpleHoster): def setup(self): self.resumeDownload = True - self.multiDL = True if self.premium else False + self.multiDL = self.premium def handlePremium(self): self.handleDownload(True) diff --git a/pyload/plugins/hoster/NetloadIn.py b/pyload/plugins/hoster/NetloadIn.py index 0e658761a..773f2e427 100644 --- a/pyload/plugins/hoster/NetloadIn.py +++ b/pyload/plugins/hoster/NetloadIn.py @@ -62,9 +62,8 @@ class NetloadIn(Hoster): def setup(self): self.multiDL = False if self.premium: - self.multiDL = True + self.multiDL = self.resumeDownload = True self.chunkLimit = -1 - self.resumeDownload = True def process(self, pyfile): self.url = pyfile.url diff --git a/pyload/plugins/hoster/NowDownloadEu.py b/pyload/plugins/hoster/NowDownloadEu.py index 4e4c32373..f1cace73b 100644 --- a/pyload/plugins/hoster/NowDownloadEu.py +++ b/pyload/plugins/hoster/NowDownloadEu.py @@ -39,9 +39,8 @@ class NowDownloadEu(SimpleHoster): def setup(self): self.wantReconnect = False - self.multiDL = True + self.multiDL = self.resumeDownload = True self.chunkLimit = -1 - self.resumeDownload = True def handleFree(self): tokenlink = re.search(self.FILE_TOKEN_PATTERN, self.html) diff --git a/pyload/plugins/hoster/OneFichierCom.py b/pyload/plugins/hoster/OneFichierCom.py index 9e2f53fd2..54bf1d1fa 100644 --- a/pyload/plugins/hoster/OneFichierCom.py +++ b/pyload/plugins/hoster/OneFichierCom.py @@ -8,7 +8,7 @@ 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.47" + __version__ = "0.48" __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") @@ -57,5 +57,8 @@ class OneFichierCom(SimpleHoster): self.wait() self.retry() + def setup(self): + self.multiDL = self.premium + self.resumeDownload = True getInfo = create_getInfo(OneFichierCom) diff --git a/pyload/plugins/hoster/Premium4Me.py b/pyload/plugins/hoster/Premium4Me.py index d5dd30e2a..d98fea4c4 100644 --- a/pyload/plugins/hoster/Premium4Me.py +++ b/pyload/plugins/hoster/Premium4Me.py @@ -61,7 +61,8 @@ class Premium4Me(Hoster): trb = self.getTraffic() self.logInfo("Filesize: %d, Traffic used %d, traffic left %d" % (pyfile.size, tra - trb, trb)) - if err: self.fail(err) + if err: + self.fail(err) def getTraffic(self): try: diff --git a/pyload/plugins/hoster/PutlockerCom.py b/pyload/plugins/hoster/PutlockerCom.py index 0f62ea96d..02205f9cc 100644 --- a/pyload/plugins/hoster/PutlockerCom.py +++ b/pyload/plugins/hoster/PutlockerCom.py @@ -37,9 +37,8 @@ class PutlockerCom(SimpleHoster): FILE_INFO_PATTERN = r'site-content">\s*<h1>(?P<N>.+)<strong>\( (?P<S>[^)]+) \)</strong></h1>' def handleFree(self): - self.multiDL = True + self.multiDL = self.resumeDownload = True self.chunkLimit = -1 - self.resumeDownload = True self.pyfile.url = re.sub(r'http://putlocker\.com', r'http://www.putlocker.com', self.pyfile.url) self.html = self.load(self.pyfile.url, decode=True) diff --git a/pyload/plugins/hoster/RapidgatorNet.py b/pyload/plugins/hoster/RapidgatorNet.py index 543d73966..64ed6a4b3 100644 --- a/pyload/plugins/hoster/RapidgatorNet.py +++ b/pyload/plugins/hoster/RapidgatorNet.py @@ -46,8 +46,7 @@ class RapidgatorNet(SimpleHoster): SOLVEMEDIA_PATTERN = r'http:\/\/api\.solvemedia\.com\/papi\/challenge\.script\?k=(.*?)"' def setup(self): - self.resumeDownload = False - self.multiDL = False + self.resumeDownload = self.multiDL = False self.sid = None self.chunkLimit = 1 self.req.setOption("timeout", 120) diff --git a/pyload/plugins/hoster/RgHostNet.py b/pyload/plugins/hoster/RgHostNet.py new file mode 100644 index 000000000..a46b51733 --- /dev/null +++ b/pyload/plugins/hoster/RgHostNet.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class RgHostNet(SimpleHoster): + __name__ = "RgHostNet" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?rghost\.net/\d+(?:r=\d+)?" + __version__ = "0.01" + __description__ = """RgHost.net Download Hoster""" + __author_name__ = ("z00nx") + __author_mail__ = ("z00nx0@gmail.com") + + FILE_INFO_PATTERN = r'<h1>\s+(<a[^>]+>)?(?P<N>[^<]+)(</a>)?\s+<small[^>]+>\s+\((?P<S>[^)]+)\)\s+</small>\s+</h1>' + FILE_OFFLINE_PATTERN = r'File is deleted|this page is not found' + DOWNLOAD_LINK_PATTERN = '''<a\s+href="([^"]+)"\s+class="btn\s+large\s+download"[^>]+>Download</a>''' + + def handleFree(self): + found = re.search(self.DOWNLOAD_LINK_PATTERN, self.html) + if not found: + self.parseError("Unable to detect the direct link") + download_link = found.group(1) + self.download(download_link, disposition=True) + +getInfo = create_getInfo(RgHostNet) diff --git a/pyload/plugins/hoster/Share76Com.py b/pyload/plugins/hoster/Share76Com.py index aaa8cd950..b48780652 100644 --- a/pyload/plugins/hoster/Share76Com.py +++ b/pyload/plugins/hoster/Share76Com.py @@ -13,9 +13,5 @@ class Share76Com(XFileSharingPro): FILE_INFO_PATTERN = r'<h2>\s*File:\s*<font[^>]*>(?P<N>[^>]+)</font>\s*\[<font[^>]*>(?P<S>[0-9.]+) (?P<U>[kKMG])i?B</font>\]</h2>' HOSTER_NAME = "share76.com" - def setup(self): - self.resumeDownload = self.multiDL = self.premium - self.chunkLimit = 1 - getInfo = create_getInfo(Share76Com) diff --git a/pyload/plugins/hoster/ShareRapidCom.py b/pyload/plugins/hoster/ShareRapidCom.py index 42bdaa4e3..82f98d73c 100644 --- a/pyload/plugins/hoster/ShareRapidCom.py +++ b/pyload/plugins/hoster/ShareRapidCom.py @@ -2,54 +2,32 @@ # -*- coding: utf-8 -*- import re + from pycurl import HTTPHEADER -from module.network.RequestFactory import getRequest, getURL from module.network.HTTPRequest import BadHeader -from module.plugins.internal.SimpleHoster import SimpleHoster, parseFileInfo -from module.common.json_layer import json_loads - - -def checkFile(url): - response = getURL("http://share-rapid.com/checkfiles.php", post={"files": url}, decode=True) - info = json_loads(response) - - if "error" in info: - if info['error'] == False: - info['name'] = info['filename'] - info['status'] = 2 - elif info['msg'] == "Not found": - info['status'] = 1 # offline - elif info['msg'] == "Service Unavailable": - info['status'] = 6 # temp.offline - - return info +from module.network.RequestFactory import getRequest +from module.plugins.internal.SimpleHoster import SimpleHoster, parseFileInfo, replace_patterns def getInfo(urls): + h = getRequest() + h.c.setopt(HTTPHEADER, + ["Accept: text/html", + "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0"]) for url in urls: - info = checkFile(url) - if "filename" in info: - yield info['name'], info['size'], info['status'], url - else: - file_info = (url, 0, 3, url) - h = getRequest() - try: - h.c.setopt(HTTPHEADER, ["Accept: text/html"]) - html = h.load(url, cookies=True, decode=True) - file_info = parseFileInfo(ShareRapidCom, url, html) - finally: - h.close() - yield file_info + html = h.load(url, decode=True) + file_info = parseFileInfo(ShareRapidCom, replace_patterns(url, ShareRapidCom.FILE_URL_REPLACEMENTS), html) + yield file_info class ShareRapidCom(SimpleHoster): __name__ = "ShareRapidCom" __type__ = "hoster" - __pattern__ = r"http://(?:www\.)?((share(-?rapid\.(biz|com|cz|info|eu|net|org|pl|sk)|-(central|credit|free|net)\.cz|-ms\.net)|(s-?rapid|rapids)\.(cz|sk))|(e-stahuj|mediatack|premium-rapidshare|rapidshare-premium|qiuck)\.cz|kadzet\.com|stahuj-zdarma\.eu|strelci\.net|universal-share\.com)/stahuj/(\w+)" - __version__ = "0.52" + __pattern__ = r"http://(?:www\.)?((share(-?rapid\.(biz|com|cz|info|eu|net|org|pl|sk)|-(central|credit|free|net)\.cz|-ms\.net)|(s-?rapid|rapids)\.(cz|sk))|(e-stahuj|mediatack|premium-rapidshare|rapidshare-premium|qiuck)\.cz|kadzet\.com|stahuj-zdarma\.eu|strelci\.net|universal-share\.com)/stahuj/(?P<id>\w+)" + __version__ = "0.53" __description__ = """Share-rapid.com plugin - premium only""" - __author_name__ = ("MikyWoW", "zoidberg") - __author_mail__ = ("MikyWoW@seznam.cz", "zoidberg@mujmail.cz") + __author_name__ = ("MikyWoW", "zoidberg", "stickell") + __author_mail__ = ("MikyWoW@seznam.cz", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") FILE_NAME_PATTERN = r'<h1[^>]*><span[^>]*>(?:<a[^>]*>)?(?P<N>[^<]+)' FILE_SIZE_PATTERN = r'<td class="i">Velikost:</td>\s*<td class="h"><strong>\s*(?P<S>[0-9.]+) (?P<U>[kKMG])i?B</strong></td>' @@ -59,7 +37,7 @@ class ShareRapidCom(SimpleHoster): ERR_LOGIN_PATTERN = ur'<div class="error_div"><strong>Stahování je přístupné pouze přihlášeným uživatelům' ERR_CREDIT_PATTERN = ur'<div class="error_div"><strong>Stahování zdarma je možné jen přes náš' - FILE_URL_REPLACEMENTS = [(__pattern__, r'http://share-rapid.com/stahuj/\1')] + FILE_URL_REPLACEMENTS = [(__pattern__, r'http://share-rapid.com/stahuj/\g<id>')] def setup(self): self.chunkLimit = 1 @@ -69,35 +47,20 @@ class ShareRapidCom(SimpleHoster): if not self.account: self.fail("User not logged in") - self.info = checkFile(pyfile.url) - self.logDebug(self.info) - - pyfile.status = self.info['status'] - - if pyfile.status == 2: - pyfile.name = self.info['name'] - pyfile.size = self.info['size'] - elif pyfile.status == 1: - self.offline() - elif pyfile.status == 6: - self.tempOffline() - else: - self.fail("Unexpected file status") - - url = "http://share-rapid.com/stahuj/%s" % self.info['filepath'] try: - self.html = self.load(url, decode=True) + self.html = self.load(pyfile.url, decode=True) except BadHeader, e: self.account.relogin(self.user) self.retry(3, 0, str(e)) + self.getFileInfo() + found = re.search(self.DOWNLOAD_URL_PATTERN, self.html) - if found is not None: + if found: link = found.group(1) self.logDebug("Premium link: %s" % link) - self.check_data = {"size": pyfile.size} - self.download(link) + self.download(link, disposition=True) else: if re.search(self.ERR_LOGIN_PATTERN, self.html): self.relogin(self.user) diff --git a/pyload/plugins/hoster/SpeedLoadOrg.py b/pyload/plugins/hoster/SpeedLoadOrg.py index 17354864f..5687fae85 100644 --- a/pyload/plugins/hoster/SpeedLoadOrg.py +++ b/pyload/plugins/hoster/SpeedLoadOrg.py @@ -1,23 +1,15 @@ # -*- coding: utf-8 -*- -from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo +from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo -class SpeedLoadOrg(XFileSharingPro): +class SpeedLoadOrg(DeadHoster): __name__ = "SpeedLoadOrg" __type__ = "hoster" __pattern__ = r"http://(www\.)?speedload\.org/(?P<ID>\w+)" - __version__ = "1.01" + __version__ = "1.02" __description__ = """Speedload.org hoster plugin""" __author_name__ = ("stickell") __author_mail__ = ("l.stickell@yahoo.it") - FILE_NAME_PATTERN = r'Filename:</b></td><td nowrap>(?P<N>[^<]+)</td></tr>' - FILE_SIZE_PATTERN = r'Size:</b></td><td>[\w. ]+<small>\((?P<S>\d+) bytes\)</small>' - - HOSTER_NAME = "speedload.org" - - def handlePremium(self): - self.download(self.pyfile.url, post=self.getPostParameters()) - getInfo = create_getInfo(SpeedLoadOrg) diff --git a/pyload/plugins/hoster/TurbobitNet.py b/pyload/plugins/hoster/TurbobitNet.py index 5fe42bba7..d574d1fa7 100644 --- a/pyload/plugins/hoster/TurbobitNet.py +++ b/pyload/plugins/hoster/TurbobitNet.py @@ -35,8 +35,8 @@ from module.plugins.internal.CaptchaService import ReCaptcha class TurbobitNet(SimpleHoster): __name__ = "TurbobitNet" __type__ = "hoster" - __pattern__ = r"http://(?:\w*\.)?(turbobit.net|unextfiles.com)/(?:download/free/)?(?P<ID>\w+).*" - __version__ = "0.09" + __pattern__ = r"http://(?:\w*\.)?(turbobit.net|unextfiles.com)/(?!download/folder/)(?:download/free/)?(?P<ID>\w+).*" + __version__ = "0.10" __description__ = """Turbobit.net plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") diff --git a/pyload/plugins/hoster/UploadedTo.py b/pyload/plugins/hoster/UploadedTo.py index 6ac3320c0..aee7f32b1 100644 --- a/pyload/plugins/hoster/UploadedTo.py +++ b/pyload/plugins/hoster/UploadedTo.py @@ -101,15 +101,13 @@ class UploadedTo(Hoster): def setup(self): self.html = None - self.multiDL = False - self.resumeDownload = False + self.multiDL = self.resumeDownload = False self.url = False self.chunkLimit = 1 # critical problems with more chunks if self.account: self.premium = self.account.getAccountInfo(self.user)["premium"] if self.premium: - self.multiDL = True - self.resumeDownload = True + self.multiDL = self.resumeDownload = True self.fileID = getID(self.pyfile.url) self.pyfile.url = "http://uploaded.net/file/%s" % self.fileID diff --git a/pyload/plugins/hoster/UptoboxCom.py b/pyload/plugins/hoster/UptoboxCom.py index e0d4ce7f4..fe05bf916 100644 --- a/pyload/plugins/hoster/UptoboxCom.py +++ b/pyload/plugins/hoster/UptoboxCom.py @@ -15,9 +15,5 @@ class UptoboxCom(XFileSharingPro): FILE_OFFLINE_PATTERN = r'<center>File Not Found</center>' HOSTER_NAME = "uptobox.com" - def setup(self): - self.resumeDownload = self.multiDL = self.premium - self.chunkLimit = 1 - getInfo = create_getInfo(UptoboxCom) diff --git a/pyload/plugins/hoster/X7To.py b/pyload/plugins/hoster/X7To.py index 24d1643f3..1b8850d9d 100644 --- a/pyload/plugins/hoster/X7To.py +++ b/pyload/plugins/hoster/X7To.py @@ -21,8 +21,7 @@ class X7To(Hoster): def init(self): if self.premium: - self.multiDL = False - self.resumeDownload = False + self.multiDL = self.resumeDownload = False self.chunkLimit = 1 else: self.multiDL = False diff --git a/pyload/plugins/hoster/XFileSharingPro.py b/pyload/plugins/hoster/XFileSharingPro.py index e37afc243..d6fb31307 100644 --- a/pyload/plugins/hoster/XFileSharingPro.py +++ b/pyload/plugins/hoster/XFileSharingPro.py @@ -24,6 +24,7 @@ from pycurl import FOLLOWLOCATION, LOW_SPEED_TIME from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, PluginParseError from module.plugins.internal.CaptchaService import ReCaptcha, SolveMedia from module.utils import html_unescape +from module.network.RequestFactory import getURL class XFileSharingPro(SimpleHoster): @@ -35,7 +36,7 @@ class XFileSharingPro(SimpleHoster): __name__ = "XFileSharingPro" __type__ = "hoster" __pattern__ = r"^unmatchable$" - __version__ = "0.21" + __version__ = "0.23" __description__ = """XFileSharingPro common hoster base""" __author_name__ = ("zoidberg", "stickell") __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") @@ -73,18 +74,20 @@ class XFileSharingPro(SimpleHoster): else: self.fail("Only premium users can download from other hosters with %s" % self.HOSTER_NAME) else: + try: + # Due to a 0.4.9 core bug self.load would use cookies even if + # cookies=False. Workaround using getURL to avoid cookies. + # Can be reverted in 0.5 as the cookies bug has been fixed. + self.html = getURL(pyfile.url, decode=True) + self.file_info = self.getFileInfo() + except PluginParseError: + self.file_info = None + self.location = self.getDirectDownloadLink() - # self.load will fail because pyfile.url is a direct link to the download if self.location - # is set so it will be executed only if pyfile.url is not a direct link (location not set). - if not self.location: - try: - self.html = self.load(pyfile.url, cookies=False, decode=True) - self.file_info = self.getFileInfo() - except PluginParseError: - self.file_info = None - pyfile.name = html_unescape(unquote(urlparse( - self.location if self.location else pyfile.url).path.split("/")[-1])) + if not self.file_info: + pyfile.name = html_unescape(unquote(urlparse( + self.location if self.location else pyfile.url).path.split("/")[-1])) if self.location: self.startDownload(self.location) diff --git a/pyload/plugins/hoster/YoutubeCom.py b/pyload/plugins/hoster/YoutubeCom.py index 1db5fc0a4..316eebd4b 100644 --- a/pyload/plugins/hoster/YoutubeCom.py +++ b/pyload/plugins/hoster/YoutubeCom.py @@ -4,7 +4,6 @@ import re import subprocess import os -import os.path from urllib import unquote from module.utils import html_unescape @@ -37,7 +36,7 @@ class YoutubeCom(Hoster): __name__ = "YoutubeCom" __type__ = "hoster" __pattern__ = r"https?://(?:[^/]*?)youtube\.com/watch.*?[?&]v=.*" - __version__ = "0.34" + __version__ = "0.35" __config__ = [("quality", "sd;hd;fullhd;240p;360p;480p;720p;1080p;3072p", "Quality Setting", "hd"), ("fmt", "int", "FMT/ITAG Number (5-102, 0 for auto)", 0), (".mp4", "bool", "Allow .mp4", True), @@ -49,6 +48,9 @@ class YoutubeCom(Hoster): __author_name__ = ("spoob", "zoidberg") __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz") + # Invalid characters that must be removed from the file name + invalidChars = ':?><"|\\' + # name, width, height, quality ranking, 3D formats = {5: (".flv", 400, 240, 1, False), 6: (".flv", 640, 400, 4, False), @@ -137,6 +139,11 @@ class YoutubeCom(Hoster): file_suffix = self.formats[fmt][0] if fmt in self.formats else ".flv" file_name_pattern = '<meta name="title" content="(.+?)">' name = re.search(file_name_pattern, html).group(1).replace("/", "") + + # Cleaning invalid characters from the file name + for c in self.invalidChars: + name = name.replace(c, '_') + pyfile.name = html_unescape(name) time = re.search(r"t=((\d+)m)?(\d+)s", pyfile.url) diff --git a/pyload/plugins/hoster/ZippyshareCom.py b/pyload/plugins/hoster/ZippyshareCom.py index 3c7b68bb6..a3b1cf783 100644 --- a/pyload/plugins/hoster/ZippyshareCom.py +++ b/pyload/plugins/hoster/ZippyshareCom.py @@ -15,7 +15,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.39" + __version__ = "0.41" __description__ = """Zippyshare.com Download Hoster""" __author_name__ = ("spoob", "zoidberg", "stickell") __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") @@ -26,7 +26,7 @@ class ZippyshareCom(SimpleHoster): FILE_INFO_PATTERN = r'document\.getElementById\(\'dlbutton\'\)\.href = "[^;]*/(?P<N>[^"]+)";' FILE_OFFLINE_PATTERN = r'>File does not exist on this server</div>' - DOWNLOAD_URL_PATTERN = r"<script type=\"text/javascript\">([^<]*?)document\.getElementById\('dlbutton'\).href = ([^;]+);" + DOWNLOAD_URL_PATTERN = r"<script type=\"text/javascript\">([^<]*?)(document\.getElementById\('dlbutton'\).href = [^;]+;)" SEED_PATTERN = r'swfobject.embedSWF\("([^"]+)".*?seed: (\d+)' CAPTCHA_KEY_PATTERN = r'Recaptcha.create\("([^"]+)"' CAPTCHA_SHORTENCODE_PATTERN = r"shortencode: '([^']+)'" @@ -63,52 +63,29 @@ class ZippyshareCom(SimpleHoster): def get_file_url(self): """ returns the absolute downloadable filepath """ - url = multiply = modulo = None + url = None found = re.search(self.DOWNLOAD_URL_PATTERN, self.html, re.S) - if found: - #Method #1: JS eval + #Method #1: JS eval + if found and re.search(r'span id="omg" class="(\d*)"', self.html): + js = "\n".join(found.groups()) + d = re.search(r'span id="omg" class="(\d*)"', self.html).group(1) + regex = r"document.getElementById\('omg'\).getAttribute\('class'\)" + js = re.sub(regex, d, js) + regex = r"document.getElementById\(\\*'dlbutton\\*'\).href = " + js = re.sub(regex, '', js) + url = self.js.eval(js) + elif found and re.search(r"document.getElementById\(\\*'dlbutton\\*'\).omg", self.html): js = "\n".join(found.groups()) regex = r"document.getElementById\(\\*'dlbutton\\*'\).omg" 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) url = self.js.eval(js) else: #Method #2: SWF eval - seed_search = re.search(self.SEED_PATTERN, self.html) - if seed_search: - swf_url, file_seed = seed_search.groups() - - swf_sts = self.getStorage("swf_sts") - swf_stamp = int(self.getStorage("swf_stamp") or 0) - swf_version = self.getStorage("version") - self.logDebug("SWF", swf_sts, swf_stamp, swf_version) - - if not swf_sts: - self.logDebug('Using default values') - multiply, modulo = self.LAST_KNOWN_VALUES - elif swf_sts == "1": - self.logDebug('Using stored values') - multiply = self.getStorage("multiply") - modulo = self.getStorage("modulo") - elif swf_sts == "2": - if swf_version < self.__version__: - self.logDebug('Reverting to default values') - self.setStorage("swf_sts", "") - self.setStorage("version", self.__version__) - multiply, modulo = self.LAST_KNOWN_VALUES - elif (swf_stamp + 3600000) < timestamp(): - swfdump = self.get_swfdump_path() - if swfdump: - multiply, modulo = self.get_swf_values(self.file_info['HOST'] + swf_url, swfdump) - else: - self.logWarning("Swfdump not found. Install swftools to bypass captcha.") - - if multiply and modulo: - self.logDebug("TIME = (%s * %s) %s" % (file_seed, multiply, modulo)) - url = "/download?key=%s&time=%d" % (self.file_info['KEY'], - (int(file_seed) * int(multiply)) % int(modulo)) + url = self.swf_eval() if not url: #Method #3: Captcha @@ -116,6 +93,45 @@ class ZippyshareCom(SimpleHoster): return self.file_info['HOST'] + url + def swf_eval(self): + multiply = modulo = None + seed_search = re.search(self.SEED_PATTERN, self.html) + if seed_search: + swf_url, file_seed = seed_search.groups() + + swf_sts = self.getStorage("swf_sts") + swf_stamp = int(self.getStorage("swf_stamp") or 0) + swf_version = self.getStorage("version") + self.logDebug("SWF", swf_sts, swf_stamp, swf_version) + + if not swf_sts: + self.logDebug('Using default values') + multiply, modulo = self.LAST_KNOWN_VALUES + elif swf_sts == "1": + self.logDebug('Using stored values') + multiply = self.getStorage("multiply") + modulo = self.getStorage("modulo") + elif swf_sts == "2": + if swf_version < self.__version__: + self.logDebug('Reverting to default values') + self.setStorage("swf_sts", "") + self.setStorage("version", self.__version__) + multiply, modulo = self.LAST_KNOWN_VALUES + elif (swf_stamp + 3600000) < timestamp(): + swfdump = self.get_swfdump_path() + if swfdump: + multiply, modulo = self.get_swf_values(self.file_info['HOST'] + swf_url, swfdump) + else: + self.logWarning("Swfdump not found. Install swftools to bypass captcha.") + + if multiply and modulo: + self.logDebug("TIME = (%s * %s) %s" % (file_seed, multiply, modulo)) + url = "/download?key=%s&time=%d" % (self.file_info['KEY'], + (int(file_seed) * int(multiply)) % int(modulo)) + return url + + return None + def get_swf_values(self, swf_url, swfdump): self.logDebug('Parsing values from %s' % swf_url) multiply = modulo = None diff --git a/pyload/plugins/internal/DeadCrypter.py b/pyload/plugins/internal/DeadCrypter.py new file mode 100644 index 000000000..805f781af --- /dev/null +++ b/pyload/plugins/internal/DeadCrypter.py @@ -0,0 +1,14 @@ +from module.plugins.Crypter import Crypter as _Crypter + + +class DeadCrypter(_Crypter): + __name__ = "DeadCrypter" + __type__ = "crypter" + __pattern__ = r"" + __version__ = "0.01" + __description__ = """Crypter is no longer available""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + def setup(self): + self.fail("Crypter is no longer available") diff --git a/pyload/plugins/internal/SimpleCrypter.py b/pyload/plugins/internal/SimpleCrypter.py index f0fe0b764..e26bf6644 100644 --- a/pyload/plugins/internal/SimpleCrypter.py +++ b/pyload/plugins/internal/SimpleCrypter.py @@ -19,9 +19,8 @@ import re -from module.plugins.Crypter import Crypter -from module.utils import html_unescape - +from pyload.plugins.Crypter import Crypter, Package +from pyload.utils import html_unescape class SimpleCrypter(Crypter): __name__ = "SimpleCrypter" @@ -52,11 +51,10 @@ class SimpleCrypter(Crypter): must return the html of the page number 'page_n' """ - def decrypt(self, pyfile): - self.html = self.load(pyfile.url, decode=True) - - package_name, folder_name = self.getPackageNameAndFolder() + def decryptURL(self, url): + self.html = self.load(url, decode=True) + package_name = self.getPackageName() self.package_links = self.getLinks() if hasattr(self, 'PAGES_PATTERN') and hasattr(self, 'loadPage'): @@ -65,10 +63,11 @@ class SimpleCrypter(Crypter): self.logDebug('Package has %d links' % len(self.package_links)) if self.package_links: - self.packages = [(package_name, self.package_links, folder_name)] + return Package(package_name, self.package_links) else: self.fail('Could not extract any links') + def getLinks(self): """ Returns the links extracted from self.html @@ -76,18 +75,15 @@ class SimpleCrypter(Crypter): """ return re.findall(self.LINK_PATTERN, self.html) - def getPackageNameAndFolder(self): + def getPackageName(self): if hasattr(self, 'TITLE_PATTERN'): m = re.search(self.TITLE_PATTERN, self.html) if m: - name = folder = html_unescape(m.group('title').strip()) - self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) - return name, folder - - name = self.pyfile.package().name - folder = self.pyfile.package().folder - self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder)) - return name, folder + name = html_unescape(m.group('title').strip()) + self.logDebug("Found name [%s] in package info" % (name)) + return name + + return None def handleMultiPages(self): pages = re.search(self.PAGES_PATTERN, self.html) diff --git a/pyload/plugins/internal/SimpleHoster.py b/pyload/plugins/internal/SimpleHoster.py index 7b1d7323a..745cbfd8f 100644 --- a/pyload/plugins/internal/SimpleHoster.py +++ b/pyload/plugins/internal/SimpleHoster.py @@ -146,7 +146,7 @@ class PluginParseError(Exception): class SimpleHoster(Hoster): __name__ = "SimpleHoster" - __version__ = "0.28" + __version__ = "0.29" __pattern__ = None __type__ = "hoster" __description__ = """Base hoster plugin""" @@ -173,13 +173,16 @@ class SimpleHoster(Hoster): self.file_info = {} def setup(self): - self.resumeDownload = self.multiDL = True if self.premium else False - if isinstance(self.SH_COOKIES, list): set_cookies(self.req.cj, self.SH_COOKIES) + self.resumeDownload = self.multiDL = self.premium + if isinstance(self.SH_COOKIES, list): + set_cookies(self.req.cj, self.SH_COOKIES) def process(self, pyfile): pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS) self.req.setOption("timeout", 120) - self.html = self.load(pyfile.url, decode = not self.SH_BROKEN_ENCODING, cookies = self.SH_COOKIES) + # Due to a 0.4.9 core bug self.load would keep previous cookies even if overridden by cookies parameter. + # Workaround using getURL. Can be reverted in 0.5 as the cookies bug has been fixed. + self.html = getURL(pyfile.url, decode=not self.SH_BROKEN_ENCODING, cookies=self.SH_COOKIES) self.getFileInfo() if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): self.handlePremium() diff --git a/pyload/plugins/network/CurlChunk.py b/pyload/plugins/network/CurlChunk.py index 871cf7f39..75be9ce6c 100644 --- a/pyload/plugins/network/CurlChunk.py +++ b/pyload/plugins/network/CurlChunk.py @@ -25,7 +25,7 @@ import codecs import pycurl from pyload.utils import remove_chars -from pyload.utils.fs import fs_encode +from pyload.utils.fs import fs_encode, fs_decode from CurlRequest import CurlRequest @@ -35,7 +35,7 @@ class WrongFormat(Exception): class ChunkInfo(): def __init__(self, name): - self.name = unicode(name) + self.name = fs_decode(name) self.size = 0 self.resume = False self.chunks = [] @@ -153,6 +153,8 @@ class CurlChunk(CurlRequest): self.sleep = 0.000 self.lastSize = 0 + # next to last size + self.nLastSize = 0 def __repr__(self): return "<CurlChunk id=%d, size=%d, arrived=%d>" % (self.id, self.size, self.arrived) @@ -228,6 +230,8 @@ class CurlChunk(CurlRequest): self.BOMChecked = True size = len(buf) + self.nLastSize = self.lastSize + self.lastSize = size self.arrived += size @@ -235,7 +239,9 @@ class CurlChunk(CurlRequest): if self.p.bucket: sleep(self.p.bucket.consumed(size)) - else: + + # if the buffer sizes are stable no sleep will be made + elif size != self.lastSize or size != self.nLastSize: # Avoid small buffers, increasing sleep time slowly if buffer size gets smaller # otherwise reduce sleep time percentile (values are based on tests) # So in general cpu time is saved without reducing bandwidth too much @@ -245,8 +251,6 @@ class CurlChunk(CurlRequest): else: self.sleep *= 0.7 - self.lastSize = size - sleep(self.sleep) if self.range and self.arrived > self.size: diff --git a/pyload/plugins/network/CurlRequest.py b/pyload/plugins/network/CurlRequest.py index 8d1f22450..717590ac5 100644 --- a/pyload/plugins/network/CurlRequest.py +++ b/pyload/plugins/network/CurlRequest.py @@ -187,7 +187,6 @@ class CurlRequest(Request): if "auth" in self.options: self.c.setopt(pycurl.USERPWD, str(self.options["auth"])) - def load(self, url, get={}, post={}, referer=True, cookies=True, just_header=False, multipart=False, decode=False): """ load and returns a given page """ |