From 8801af3abae628053a66af59c5df2a0bb9584ddd Mon Sep 17 00:00:00 2001 From: Stefano Date: Fri, 29 Mar 2013 21:59:48 +0100 Subject: New hoster: FilerNet --- module/plugins/hoster/FilerNet.py | 103 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 module/plugins/hoster/FilerNet.py (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py new file mode 100644 index 000000000..9693723f9 --- /dev/null +++ b/module/plugins/hoster/FilerNet.py @@ -0,0 +1,103 @@ +# -*- 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 . # +############################################################################ + +# Test links (random.bin): +# http://filer.net/get/ivgf5ztw53et3ogd +# http://filer.net/get/hgo14gzcng3scbvv + +import pycurl +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.ReCaptcha import ReCaptcha + + +class FilerNet(SimpleHoster): + __name__ = "FilerNet" + __type__ = "hoster" + __pattern__ = r"https?://(www\.)?filer\.net/get/(\w+)" + __version__ = "0.01" + __description__ = """Filer.net Download Hoster""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_INFO_PATTERN = r'

Free Download (?P\S+) (?P[\w.]+) (?P\w+)

' + FILE_OFFLINE_PATTERN = r'Nicht gefunden' + RECAPTCHA_KEY = '6LcFctISAAAAAAgaeHgyqhNecGJJRnxV1m_vAz3V' + + def process(self, pyfile): + self.req.setOption("timeout", 120) + self.html = self.load(pyfile.url, decode=not self.SH_BROKEN_ENCODING, cookies=self.SH_COOKIES) + + # Wait between downloads + m = re.search(r'musst du (\d+) Sekunden warten', self.html) + if m: + waittime = int(m.group(1)) + self.retry(3, waittime, 'Wait between free downloads') + + self.getFileInfo() + if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): + self.handlePremium() + else: + self.handleFree() + + def handleFree(self): + self.html = self.load(self.pyfile.url, decode=True) + + inputs = self.parseHtmlForm(input_names='token')[1] + if 'token' not in inputs: + self.parseError('Unable to detect token') + token = inputs['token'] + self.logDebug('Token: ' + token) + + self.html = self.load(self.pyfile.url, post={'token': token}, decode=True) + + inputs = self.parseHtmlForm(input_names='hash')[1] + if 'hash' not in inputs: + self.parseError('Unable to detect hash') + hash_data = inputs['hash'] + self.logDebug('Hash: ' + hash_data) + + downloadURL = '' + 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, + 'hash': hash_data} + + # Workaround for 0.4.9 just_header issue. In 0.5 clean the code using just_header + self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0) + self.load(self.pyfile.url, post=post_data) + self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 1) + + if 'location' in self.req.http.header: + location = re.search(r'location: (\S+)', self.req.http.header).group(1) + downloadURL = 'http://filer.net' + location + self.correctCaptcha() + break + else: + self.logInfo('Wrong captcha') + self.invalidCaptcha() + + if not downloadURL: + self.fail("No Download url retrieved/all captcha attempts failed") + + self.download(downloadURL, disposition=True) + + +getInfo = create_getInfo(FilerNet) -- cgit v1.2.3 From 3634f7f678ed58becda172192536f756a61b2ec1 Mon Sep 17 00:00:00 2001 From: Stefano Date: Sat, 30 Mar 2013 21:20:35 +0100 Subject: Two plugins updated to avoid errors in 0.5 --- module/plugins/hoster/OneFichierCom.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py index 46323d829..922eb3a1f 100644 --- a/module/plugins/hoster/OneFichierCom.py +++ b/module/plugins/hoster/OneFichierCom.py @@ -10,8 +10,7 @@ class OneFichierCom(SimpleHoster): __version__ = "0.45" __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") + __author_mail__ = ("fragonib[AT]yahoo[DOT]es", "daniel_ AT gmx DOT net", "zoidberg@mujmail.cz","imclem on github") FILE_NAME_PATTERN = r'">File name :\s*(?P[^<]+)' FILE_SIZE_PATTERN = r'File size :\s*(?P[^<]+)' -- cgit v1.2.3 From 173c5f3ccfb06b4a24b38e59ad73127fc363eea4 Mon Sep 17 00:00:00 2001 From: Stefano Date: Sat, 30 Mar 2013 21:35:19 +0100 Subject: OneFichierCom: version number increased --- module/plugins/hoster/OneFichierCom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py index 922eb3a1f..7b87bbe71 100644 --- a/module/plugins/hoster/OneFichierCom.py +++ b/module/plugins/hoster/OneFichierCom.py @@ -7,7 +7,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.45" + __version__ = "0.46" __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") -- cgit v1.2.3 From 3b52a1537e599efca78da3ca89306a5b0f5081de Mon Sep 17 00:00:00 2001 From: Stefano Date: Mon, 1 Apr 2013 15:16:02 +0200 Subject: RarefileNet: added pattern to support premium downloads --- module/plugins/hoster/RarefileNet.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/RarefileNet.py b/module/plugins/hoster/RarefileNet.py index 7c5543cc8..a0f5930b5 100644 --- a/module/plugins/hoster/RarefileNet.py +++ b/module/plugins/hoster/RarefileNet.py @@ -1,30 +1,34 @@ # -*- coding: utf-8 -*- + import re + from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo from module.utils import html_unescape + class RarefileNet(XFileSharingPro): __name__ = "RarefileNet" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)*rarefile.net/\w{12}" - __version__ = "0.02" + __version__ = "0.03" __description__ = """Rarefile.net hoster plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") - + FILE_NAME_PATTERN = r'(?P.*?)' FILE_SIZE_PATTERN = r'Size : (?P.+?) ' + DIRECT_LINK_PATTERN = r'(?P=link)' HOSTER_NAME = "rarefile.net" - + def setup(self): - self.resumeDownload = self.multiDL = self.premium - + self.resumeDownload = self.multiDL = self.premium + def handleCaptcha(self, inputs): captcha_div = re.search(r'Enter code.*?(.*?)', self.html, re.S).group(1) - self.logDebug(captcha_div) + self.logDebug(captcha_div) numerals = re.findall('(\d)', html_unescape(captcha_div)) inputs['code'] = "".join([a[1] for a in sorted(numerals, key = lambda num: int(num[0]))]) - self.logDebug("CAPTCHA", inputs['code'], numerals) + self.logDebug("CAPTCHA", inputs['code'], numerals) return 3 -getInfo = create_getInfo(RarefileNet) \ No newline at end of file +getInfo = create_getInfo(RarefileNet) -- cgit v1.2.3 From 4279f57d08844ed7a67d91aa3863baa0ed1164fe Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 2 Apr 2013 01:19:16 +0200 Subject: New hoster: Data.hu --- module/plugins/hoster/DataHu.py | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 module/plugins/hoster/DataHu.py (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/DataHu.py b/module/plugins/hoster/DataHu.py new file mode 100644 index 000000000..7abd93d1f --- /dev/null +++ b/module/plugins/hoster/DataHu.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 . # +############################################################################ + +# Test links (random.bin): +# http://data.hu/get/6381232/random.bin + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class DataHu(SimpleHoster): + __name__ = "DataHu" + __type__ = "hoster" + __pattern__ = r"http://(www\.)?data.hu/get/\w+" + __version__ = "0.01" + __description__ = """Data.hu Download Hoster""" + __author_name__ = ("crash", "stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_INFO_PATTERN = ur'(?P<N>.*) \((?P<S>[^)]+)\) let\xf6lt\xe9se' + FILE_OFFLINE_PATTERN = ur'Az adott f\xe1jl nem l\xe9tezik' + DIRECT_LINK_PATTERN = r'
' + + def handleFree(self): + self.resumeDownload = True + self.html = self.load(self.pyfile.url, decode=True) + + m = re.search(self.DIRECT_LINK_PATTERN, self.html) + if m: + url = m.group(1) + self.logDebug('Direct link: ' + url) + else: + self.parseError('Unable to get direct link') + + self.download(url, disposition=True) + + +getInfo = create_getInfo(DataHu) -- cgit v1.2.3 From bb159d8a3c6d1c8324bb2b12baef5abea97d0f63 Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 4 Apr 2013 00:15:40 +0300 Subject: YoutubeCom: increased version --- module/plugins/hoster/YoutubeCom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py index 8b8764367..2fb1e5264 100644 --- a/module/plugins/hoster/YoutubeCom.py +++ b/module/plugins/hoster/YoutubeCom.py @@ -34,7 +34,7 @@ class YoutubeCom(Hoster): __name__ = "YoutubeCom" __type__ = "hoster" __pattern__ = r"(http|https)://(www\.)?(de\.)?\youtube\.com/watch\?v=.*" - __version__ = "0.29" + __version__ = "0.30" __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), -- cgit v1.2.3 From e0ae0ca05b9ca8ce4a451c182594bdc481c22264 Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 4 Apr 2013 14:07:14 +0200 Subject: PutlockerCom: using SimpleHoster to clean the code and make it work better --- module/plugins/hoster/PutlockerCom.py | 112 ++++++++++------------------------ 1 file changed, 32 insertions(+), 80 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/PutlockerCom.py b/module/plugins/hoster/PutlockerCom.py index ca5336231..e98e4d332 100644 --- a/module/plugins/hoster/PutlockerCom.py +++ b/module/plugins/hoster/PutlockerCom.py @@ -1,4 +1,5 @@ # -*- 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 @@ -16,103 +17,56 @@ @author: jeix """ +# http://www.putlocker.com/file/83C174C844583CF7 + import re -from module.plugins.Hoster import Hoster -from module.network.RequestFactory import getURL - -def getInfo(urls): - result = [] - - for url in urls: - - html = getURL(url) - if re.search(PutlockerCom.PATTERN_OFFLINE, html): - result.append((url, 0, 1, url)) - else: - name = re.search(PutlockerCom.PATTERN_FILENAME_1, html) - if name is None: - name = re.search(PutlockerCom.PATTERN_FILENAME_2, html) - if name is None: - result.append((url, 0, 1, url)) - continue - - name = name.group(1) - - # size = re.search(PutlockerCom.PATTERN_FILESIZE, html) - # if size is None: - # result.append((url, 0, 1, url)) - # continue - - # size = size.group(1) - - result.append((name, 0, 2, url)) - yield result - -class PutlockerCom(Hoster): + +from module.plugins.internal.SimpleHoster import SimpleHoster + + +class PutlockerCom(SimpleHoster): __name__ = "PutlockerCom" __type__ = "hoster" __pattern__ = r'http://(www\.)?putlocker\.com/(file|embed)/[A-Z0-9]+' - __version__ = "0.21" + __version__ = "0.22" __description__ = """Putlocker.Com""" - __author_name__ = ("jeix") - - PATTERN_OFFLINE = r"This file doesn't exist, or has been removed." - PATTERN_FILENAME_1 = "site-content.*?

(.*?)\s*

(?P.+)\( (?P[^)]+) \)

' + + def handleFree(self): + self.html = self.load(self.pyfile.url, decode=True) + self.link = self._getLink() if not self.link.startswith('http://'): self.link = "http://www.putlocker.com" + self.link - self.download( self.link ) - - def _checkOnline(self): - if re.search(self.PATTERN_OFFLINE, self.html): - return False - else: - return True - - def _getName(self): - name = re.search(self.PATTERN_FILENAME_1, self.html) - if name is None: - name = re.search(self.PATTERN_FILENAME_2, self.html) - # if name is None: - # self.fail("%s: Plugin broken." % self.__name__) - - return name.group(1) - + self.download(self.link, disposition=True) + def _getLink(self): self.hash = re.search("", self.html) # if self.hash is None: - # self.fail("%s: Plugin broken." % self.__name__) - + # self.fail("%s: Plugin broken." % self.__name__) + self.param = "hash=" + self.hash.group(1) + "&confirm=Continue+as+Free+User" self.html2 = self.load(self.pyfile.url, post=self.param) if ">You have exceeded the daily stream limit for your country\\. You can wait until tomorrow" in self.html2 or "(>This content server has been temporarily disabled for upgrades|Try again soon\\. You can still download it below\\.<)" in self.html2: self.waittime = 2 * 60 * 60 self.retry(wait_time=self.waittime, reason="Waiting %s seconds" % self.waittime) - - self.link = re.search("
Tired of ads and waiting\\? Go Pro\\![\t\n\rn ]+

[\t\n\rn ]+Tired of ads and waiting\\? Go Pro\\![\t\n\rn ]+[\t\n\rn ]+ Date: Thu, 4 Apr 2013 18:40:35 +0200 Subject: UploadedTo: update regex to fix bug #62 + cosmetics --- module/plugins/hoster/UploadedTo.py | 53 ++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py index a2134ecb5..5d8c9a5ac 100644 --- a/module/plugins/hoster/UploadedTo.py +++ b/module/plugins/hoster/UploadedTo.py @@ -11,34 +11,37 @@ from module.plugins.ReCaptcha import ReCaptcha key = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=".decode('base64') + def getID(url): """ returns id from file url""" - m = re.match(r"http://[\w\.-]*?(uploaded\.(to|net)(/file/|/?\?id=|.*?&id=)|ul\.to/)(?P\w+)", url) + m = re.match(r"http://[\w\.-]*?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=)(?P\w+)", url) return m.group('ID') + def getAPIData(urls): - post = {"apikey" : key} + post = {"apikey": key} - idMap = {} + idMap = {} - for i, url in enumerate(urls): - id = getID(url) - post["id_%s" % i] = id - idMap[id] = url + for i, url in enumerate(urls): + id = getID(url) + post["id_%s" % i] = id + idMap[id] = url - api = unicode(getURL("http://uploaded.net/api/filemultiple", post=post, decode=False), 'iso-8859-1') + api = unicode(getURL("http://uploaded.net/api/filemultiple", post=post, decode=False), 'iso-8859-1') - result = {} + result = {} - if api: - for line in api.splitlines(): - data = line.split(",", 4) - if data[1] in idMap: - result[data[1]] = (data[0], data[2], data[4], data[3], idMap[data[1]]) + if api: + for line in api.splitlines(): + data = line.split(",", 4) + if data[1] in idMap: + result[data[1]] = (data[0], data[2], data[4], data[3], idMap[data[1]]) - return result + return result -def parseFileInfo(self, url = '', html = ''): + +def parseFileInfo(self, url='', html=''): if not html and hasattr(self, "html"): html = self.html name, size, status, found, fileid = url, 0, 3, None, None @@ -54,6 +57,7 @@ def parseFileInfo(self, url = '', html = ''): return name, size, status, fileid + def getInfo(urls): for chunk in chunks(urls, 80): result = [] @@ -74,7 +78,7 @@ class UploadedTo(Hoster): __name__ = "UploadedTo" __type__ = "hoster" __pattern__ = r"http://[\w\.-]*?(uploaded\.(to|net)(/file/|/?\?id=|.*?&id=)|ul\.to/)\w+" - __version__ = "0.64" + __version__ = "0.65" __description__ = """Uploaded.net Download Hoster""" __author_name__ = ("spoob", "mkaay", "zoidberg", "netpok", "stickell") __author_mail__ = ("spoob@pyload.org", "mkaay@mkaay.de", "zoidberg@mujmail.cz", "netpok@gmail.com", "l.stickell@yahoo.it") @@ -88,7 +92,7 @@ class UploadedTo(Hoster): self.multiDL = False self.resumeDownload = False self.url = False - self.chunkLimit = 1 # critical problems with more chunks + self.chunkLimit = 1 # critical problems with more chunks if self.account: self.premium = self.account.getAccountInfo(self.user)["premium"] if self.premium: @@ -108,7 +112,7 @@ class UploadedTo(Hoster): if not api: self.logWarning("No response for API call") - self.html = unicode(self.load(pyfile.url, decode = False), 'iso-8859-1') + self.html = unicode(self.load(pyfile.url, decode=False), 'iso-8859-1') name, size, status, self.fileID = parseFileInfo(self) self.logDebug(name, size, status, self.fileID) if status == 1: @@ -140,8 +144,9 @@ class UploadedTo(Hoster): def handlePremium(self): info = self.account.getAccountInfo(self.user, True) - self.log.debug("%(name)s: Use Premium Account (%(left)sGB left)" % {"name" :self.__name__, "left" : info["trafficleft"]/1024/1024}) - if int(self.data[1])/1024 > info["trafficleft"]: + self.log.debug("%(name)s: Use Premium Account (%(left)sGB left)" % {"name": self.__name__, + "left": info["trafficleft"] / 1024 / 1024}) + if int(self.data[1]) / 1024 > info["trafficleft"]: self.log.info(_("%s: Not enough traffic left" % self.__name__)) self.account.empty(self.user) self.resetAccount() @@ -185,7 +190,7 @@ class UploadedTo(Hoster): #self.req.lastURL = str(self.url) re_captcha = ReCaptcha(self) challenge, result = re_captcha.challenge(challengeId.group(1)) - options = {"recaptcha_challenge_field" : challenge, "recaptcha_response_field": result} + options = {"recaptcha_challenge_field": challenge, "recaptcha_response_field": result} self.wait() result = self.load(url, post=options) @@ -193,13 +198,13 @@ class UploadedTo(Hoster): if "limit-size" in result: self.fail("File too big for free download") - elif "limit-slot" in result: # Temporary restriction so just wait a bit + elif "limit-slot" in result: # Temporary restriction so just wait a bit self.setWait(30 * 60, True) self.wait() self.retry() elif "limit-parallel" in result: self.fail("Cannot download in parallel") - elif self.DL_LIMIT_PATTERN in result: # limit-dl + elif self.DL_LIMIT_PATTERN in result: # limit-dl self.setWait(60 * 60, True) self.wait() self.retry() -- cgit v1.2.3 From 260f0e1f9dea492d88ebcb3f55b7575431a92573 Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 4 Apr 2013 18:51:51 +0200 Subject: DebridItaliaCom: + ability to detect offline files. + license note --- module/plugins/hoster/DebridItaliaCom.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/DebridItaliaCom.py b/module/plugins/hoster/DebridItaliaCom.py index a8f7dd57e..121a141b3 100644 --- a/module/plugins/hoster/DebridItaliaCom.py +++ b/module/plugins/hoster/DebridItaliaCom.py @@ -1,5 +1,20 @@ # -*- 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 . # +############################################################################ + import re from module.plugins.Hoster import Hoster @@ -7,7 +22,7 @@ from module.plugins.Hoster import Hoster class DebridItaliaCom(Hoster): __name__ = "DebridItaliaCom" - __version__ = "0.02" + __version__ = "0.03" __type__ = "hoster" __pattern__ = r"https?://.*debriditalia\.com" __description__ = """Debriditalia.com hoster plugin""" @@ -31,7 +46,10 @@ class DebridItaliaCom(Hoster): page = self.load(url) self.logDebug("XML data: %s" % page) - new_url = re.search(r'(?P[^<]+)', page).group('direct') + if 'File not available' in page: + self.offline() + else: + new_url = re.search(r'(?P[^<]+)', page).group('direct') self.logDebug("New URL: %s" % new_url) -- cgit v1.2.3 From 0f984f7e3fea8d7fb111543a23e0f7f617c1a63c Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 4 Apr 2013 20:55:09 +0200 Subject: PutlockerCom: code optimized and cleaned up --- module/plugins/hoster/PutlockerCom.py | 77 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 39 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/PutlockerCom.py b/module/plugins/hoster/PutlockerCom.py index e98e4d332..043adcb06 100644 --- a/module/plugins/hoster/PutlockerCom.py +++ b/module/plugins/hoster/PutlockerCom.py @@ -28,7 +28,7 @@ class PutlockerCom(SimpleHoster): __name__ = "PutlockerCom" __type__ = "hoster" __pattern__ = r'http://(www\.)?putlocker\.com/(file|embed)/[A-Z0-9]+' - __version__ = "0.22" + __version__ = "0.23" __description__ = """Putlocker.Com""" __author_name__ = ("jeix", "stickell") __author_mail__ = ("l.stickell@yahoo.it") @@ -39,43 +39,42 @@ class PutlockerCom(SimpleHoster): def handleFree(self): self.html = self.load(self.pyfile.url, decode=True) - self.link = self._getLink() - if not self.link.startswith('http://'): - self.link = "http://www.putlocker.com" + self.link - self.download(self.link, disposition=True) + link = self._getLink() + if not link.startswith('http://'): + link = "http://www.putlocker.com" + link + self.download(link, disposition=True) def _getLink(self): - self.hash = re.search("", self.html) - # if self.hash is None: - # self.fail("%s: Plugin broken." % self.__name__) - - self.param = "hash=" + self.hash.group(1) + "&confirm=Continue+as+Free+User" - self.html2 = self.load(self.pyfile.url, post=self.param) - if ">You have exceeded the daily stream limit for your country\\. You can wait until tomorrow" in self.html2 or "(>This content server has been temporarily disabled for upgrades|Try again soon\\. You can still download it below\\.<)" in self.html2: - self.waittime = 2 * 60 * 60 - self.retry(wait_time=self.waittime, reason="Waiting %s seconds" % self.waittime) - - self.link = re.search( - "Tired of ads and waiting\\? Go Pro\\![\t\n\rn ]+[\t\n\rn ]+', 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=2 * 60 * 60, reason="Download limit exceeded or server disabled") + + link = re.search(r'(/get_file\.php\?id=[A-Z0-9]+&key=[A-Za-z0-9=]+&original=1)', self.html) + if not link: + link = re.search(r"(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+)", self.html) + + if not link: + link = re.search(r"(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+&original=1)", self.html) + + if not link: + link = re.search( + r'Tired of ads and waiting\? Go Pro![\t\n\rn ]+[\t\n\rn ]+ Date: Fri, 5 Apr 2013 17:37:13 +0200 Subject: PutlockerCom: using loop to avoid repeated statement --- module/plugins/hoster/PutlockerCom.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/PutlockerCom.py b/module/plugins/hoster/PutlockerCom.py index 043adcb06..9eff0dc2b 100644 --- a/module/plugins/hoster/PutlockerCom.py +++ b/module/plugins/hoster/PutlockerCom.py @@ -28,7 +28,7 @@ class PutlockerCom(SimpleHoster): __name__ = "PutlockerCom" __type__ = "hoster" __pattern__ = r'http://(www\.)?putlocker\.com/(file|embed)/[A-Z0-9]+' - __version__ = "0.23" + __version__ = "0.24" __description__ = """Putlocker.Com""" __author_name__ = ("jeix", "stickell") __author_mail__ = ("l.stickell@yahoo.it") @@ -55,19 +55,15 @@ class PutlockerCom(SimpleHoster): "(>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=2 * 60 * 60, reason="Download limit exceeded or server disabled") - link = re.search(r'(/get_file\.php\?id=[A-Z0-9]+&key=[A-Za-z0-9=]+&original=1)', self.html) - if not link: - link = re.search(r"(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+)", self.html) - - if not link: - link = re.search(r"(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+&original=1)", self.html) - - if not link: - link = re.search( - r'Tired of ads and waiting\? Go Pro![\t\n\rn ]+[\t\n\rn ]+Tired of ads and waiting\? Go Pro![\t\n\rn ]+[\t\n\rn ]+ Date: Fri, 5 Apr 2013 21:41:55 +0200 Subject: EgoFilesCom: fixed bug in premium downloads. Sometimes for premium users pyfile.url redirect directly to the file, so the load call in the process function of SimpleHoster causes a pyCurl error. + content-disposition --- module/plugins/hoster/EgoFilesCom.py | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/EgoFilesCom.py b/module/plugins/hoster/EgoFilesCom.py index b27abb416..ad278e60f 100644 --- a/module/plugins/hoster/EgoFilesCom.py +++ b/module/plugins/hoster/EgoFilesCom.py @@ -1,15 +1,34 @@ # -*- 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 . # +############################################################################ + +# Test link (random.bin): +# http://egofiles.com/mOZfMI1WLZ6HBkGG/random.bin + +import re + from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo from module.plugins.ReCaptcha import ReCaptcha -import re class EgoFilesCom(SimpleHoster): __name__ = "EgoFilesCom" __type__ = "hoster" __pattern__ = r"https?://(www\.)?egofiles.com/(\w+)" - __version__ = "0.10" + __version__ = "0.11" __description__ = """Egofiles.com Download Hoster""" __author_name__ = ("stickell") __author_mail__ = ("l.stickell@yahoo.it") @@ -25,8 +44,15 @@ class EgoFilesCom(SimpleHoster): # Set English language self.load("https://egofiles.com/ajax/lang.php?lang=en", just_header=True) + def process(self, pyfile): + if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): + self.handlePremium() + else: + self.handleFree() + def handleFree(self): self.html = self.load(self.pyfile.url, decode=True) + self.getFileInfo() # Wait time between free downloads if 'For next free download you have to wait' in self.html: @@ -56,7 +82,7 @@ class EgoFilesCom(SimpleHoster): if not downloadURL: self.fail("No Download url retrieved/all captcha attempts failed") - self.download(downloadURL) + self.download(downloadURL, disposition=True) def handlePremium(self): header = self.load(self.pyfile.url, just_header=True) @@ -65,11 +91,13 @@ class EgoFilesCom(SimpleHoster): self.download(header['location']) else: self.html = self.load(self.pyfile.url, decode=True) + self.getFileInfo() m = re.search(r'Download >', self.html) if not m: self.parseError('Unable to detect direct download url') else: self.logDebug('DIRECT URL from html: ' + m.group('link')) - self.download(m.group('link')) + self.download(m.group('link'), disposition=True) + getInfo = create_getInfo(EgoFilesCom) -- cgit v1.2.3 From ecfbaded5e03529d1b189b6b5fc8b2f8516c4b31 Mon Sep 17 00:00:00 2001 From: enkore Date: Sat, 6 Apr 2013 20:21:43 +0200 Subject: Add hoster plugin for ARD mediathek --- module/plugins/hoster/ARD.py | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 module/plugins/hoster/ARD.py (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/ARD.py b/module/plugins/hoster/ARD.py new file mode 100644 index 000000000..60a40e69d --- /dev/null +++ b/module/plugins/hoster/ARD.py @@ -0,0 +1,80 @@ + +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.1" + __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"

([^<]*)

", 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.core.config["permission"]["folder"], 8)) + + if self.core.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.log.warning(_("Setting User and Group failed: %s") % str(e)) + + output_file = save_join(location, save_path(pyfile.name)) + + RTMP.download_rtmp_stream(url, playpath=playpath, output_file=output_file) -- cgit v1.2.3 From d8f2b5d9046f4cca3a8d0cd5c5dd297526ea870e Mon Sep 17 00:00:00 2001 From: enkore Date: Sat, 6 Apr 2013 20:43:48 +0200 Subject: ARD: Correct file extension --- module/plugins/hoster/ARD.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/ARD.py b/module/plugins/hoster/ARD.py index 60a40e69d..5ab65cd4b 100644 --- a/module/plugins/hoster/ARD.py +++ b/module/plugins/hoster/ARD.py @@ -75,6 +75,6 @@ class ARD(Hoster): except Exception, e: self.log.warning(_("Setting User and Group failed: %s") % str(e)) - output_file = save_join(location, save_path(pyfile.name)) + 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) -- cgit v1.2.3 From b89bc76f6cc8fa64b16eee42a0e00fdc2ddf13cc Mon Sep 17 00:00:00 2001 From: Stefano Date: Sat, 6 Apr 2013 21:33:52 +0200 Subject: DebridItaliaCom: fail instead of offline to allow revert to traditional download --- module/plugins/hoster/DebridItaliaCom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/DebridItaliaCom.py b/module/plugins/hoster/DebridItaliaCom.py index 121a141b3..470c4ae5d 100644 --- a/module/plugins/hoster/DebridItaliaCom.py +++ b/module/plugins/hoster/DebridItaliaCom.py @@ -47,7 +47,7 @@ class DebridItaliaCom(Hoster): self.logDebug("XML data: %s" % page) if 'File not available' in page: - self.offline() + self.fail('File not available') else: new_url = re.search(r'(?P[^<]+)', page).group('direct') -- cgit v1.2.3 From 73792d869620ea1a2aca4a0dbda67fb9b87b29c7 Mon Sep 17 00:00:00 2001 From: enkore Date: Sun, 7 Apr 2013 00:36:13 +0200 Subject: Add XVideosCom hoster --- module/plugins/hoster/XVideosCom.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 module/plugins/hoster/XVideosCom.py (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/XVideosCom.py b/module/plugins/hoster/XVideosCom.py new file mode 100644 index 000000000..b7f3f7b58 --- /dev/null +++ b/module/plugins/hoster/XVideosCom.py @@ -0,0 +1,19 @@ + +import re +import urllib + +from module.plugins.Hoster import Hoster + +class XVideosCom(Hoster): + __name__ = "XVideos.com" + __version__ = "0.1" + __pattern__ = r"http://www\.xvideos\.com/video([0-9]+)/.*" + __config__ = [] + + def process(self, pyfile): + site = self.load(pyfile.url) + pyfile.name = "%s (%s).flv" %( + re.search(r"

([^<]+) Date: Sun, 7 Apr 2013 14:08:18 +0200 Subject: UploadedTo: fixed #68 --- module/plugins/hoster/UploadedTo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py index 5d8c9a5ac..874b04d64 100644 --- a/module/plugins/hoster/UploadedTo.py +++ b/module/plugins/hoster/UploadedTo.py @@ -14,7 +14,7 @@ key = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=".decode('base64') def getID(url): """ returns id from file url""" - m = re.match(r"http://[\w\.-]*?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=)(?P\w+)", url) + m = re.match(r"http://[\w\.-]*?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P\w+)", url) return m.group('ID') @@ -78,7 +78,7 @@ class UploadedTo(Hoster): __name__ = "UploadedTo" __type__ = "hoster" __pattern__ = r"http://[\w\.-]*?(uploaded\.(to|net)(/file/|/?\?id=|.*?&id=)|ul\.to/)\w+" - __version__ = "0.65" + __version__ = "0.66" __description__ = """Uploaded.net Download Hoster""" __author_name__ = ("spoob", "mkaay", "zoidberg", "netpok", "stickell") __author_mail__ = ("spoob@pyload.org", "mkaay@mkaay.de", "zoidberg@mujmail.cz", "netpok@gmail.com", "l.stickell@yahoo.it") -- cgit v1.2.3 From e0b97f04b6bf8dac024cf1c15f640cab1a687098 Mon Sep 17 00:00:00 2001 From: Stefano Date: Sun, 7 Apr 2013 20:47:16 +0200 Subject: FilefactoryCom: fixes #70 --- module/plugins/hoster/FilefactoryCom.py | 88 ++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 39 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index 66d26c999..b3eb4c865 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -8,6 +8,9 @@ from module.common.json_layer import json_loads import re +# Test links (random.bin): +# http://www.filefactory.com/file/ymxkmdud2o3/n/random.bin + def checkFile(plugin, urls): url_dict = {} @@ -34,7 +37,7 @@ class FilefactoryCom(Hoster): __name__ = "FilefactoryCom" __type__ = "hoster" __pattern__ = r"http://(?:www\.)?filefactory\.com/file/(?P[a-zA-Z0-9]+).*" # URLs given out are often longer but this is the requirement - __version__ = "0.36" + __version__ = "0.37" __description__ = """Filefactory.Com File Download Hoster""" __author_name__ = ("paulking", "zoidberg") @@ -48,7 +51,8 @@ class FilefactoryCom(Hoster): FILE_CHECK_PATTERN = r'check:\s*\'(?P.*?)\'' CAPTCHA_KEY_PATTERN = r'Recaptcha.create\(\s*"(.*?)",' WAIT_PATTERN = r'id="startWait" value="(?P\d+)"' - FILE_URL_PATTERN = r']*?id="downloadLinkTarget"[^>]*>\s*]*?id="downloadLinkTarget"[^>]*>\s*'}) -- cgit v1.2.3 From f516aaecff9d4efa8a60af521b4e1c1965a1a249 Mon Sep 17 00:00:00 2001 From: Stefano Date: Sun, 7 Apr 2013 22:31:51 +0200 Subject: FilefactoryCom: plugin rewritten (see also bug #70) --- module/plugins/hoster/FilefactoryCom.py | 218 +++++++++++++------------------- 1 file changed, 90 insertions(+), 128 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index b3eb4c865..e92c1505d 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -1,159 +1,121 @@ # -*- coding: utf-8 -*- -from module.network.RequestFactory import getURL -from module.plugins.Hoster import Hoster -from module.plugins.ReCaptcha import ReCaptcha -from module.utils import parseFileSize -from module.plugins.Plugin import chunks -from module.common.json_layer import json_loads -import re +############################################################################ +# 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 . # +############################################################################ # Test links (random.bin): # http://www.filefactory.com/file/ymxkmdud2o3/n/random.bin -def checkFile(plugin, urls): - url_dict = {} - +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster +from module.network.RequestFactory import getURL +from module.utils import parseFileSize + + +def getInfo(urls): + file_info = list() + list_ids = dict() + + # Create a dict id:url. Will be used to retrieve original url for url in urls: - url_dict[re.search(plugin.__pattern__, url).group('id')] = (url, 0, 0, url) - url_ids = url_dict.keys() - urls = map(lambda url_id: 'http://www.filefactory.com/file/' + url_id, url_ids) - - html = getURL("http://www.filefactory.com/tool/links.php", post = {"func": "links", "links": "\n".join(urls)}, decode=True) - - for m in re.finditer(plugin.LC_INFO_PATTERN, html): - if m.group('id') in url_ids: - url_dict[m.group('id')] = (m.group('name'), parseFileSize(m.group('size')), 2, url_dict[m.group('id')][3]) - - for m in re.finditer(plugin.LC_OFFLINE_PATTERN, html): - if m.group('id') in url_ids: - url_dict[m.group('id')] = (url_dict[m.group('id')][0], 0, 1, url_dict[m.group('id')][3]) - - file_info = url_dict.values() - + m = re.search(FilefactoryCom.__pattern__, url) + list_ids[m.group('id')] = url + + # WARN: There could be a limit of urls for request + post_data = {'func': 'links', 'links': '\n'.join(urls)} + rep = getURL('http://www.filefactory.com/tool/links.php', post=post_data, decode=True) + + # Online links + for m in re.finditer( + r'innerText">\s*

(?P.+) \((?P[\w.]+) (?P\w+)\)

\s*

http://www.filefactory.com/file/(?P\w+).*

\s*

(http://www.filefactory.com/file/(?P\w+)/)

\s*

\1

\s*

Error: file not found

', + rep): + file_info.append((list_ids[m.group('ID')], 0, 1, list_ids[m.group('ID')])) + return file_info - -class FilefactoryCom(Hoster): + + +class FilefactoryCom(SimpleHoster): __name__ = "FilefactoryCom" __type__ = "hoster" - __pattern__ = r"http://(?:www\.)?filefactory\.com/file/(?P[a-zA-Z0-9]+).*" # URLs given out are often longer but this is the requirement - __version__ = "0.37" + __pattern__ = r"https?://(?:www\.)?filefactory\.com/file/(?P[a-zA-Z0-9]+)" + __version__ = "0.38" __description__ = """Filefactory.Com File Download Hoster""" - __author_name__ = ("paulking", "zoidberg") - - LC_INFO_PATTERN = r'

(?P[^<]+) \((?P[0-9.]+ \w+)\)

\s*

http://www.filefactory.com/file/(?P\w+)/' - LC_OFFLINE_PATTERN = r'

http://www.filefactory.com/file/(?P\w+)/

\s*

' - + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_INFO_PATTERN = r'(?P\S+)\s*\s*

\s*

(?P[\w.]+) (?P\w+) file uploaded' FILE_OFFLINE_PATTERN = r'File Not Found' - FILE_NAME_PATTERN = r'<span class="last">(?P<name>.*?)</span>' - FILE_INFO_PATTERN = r'<span>(?P<size>\d(\d|\.)*) (?P<units>..) file uploaded' - - FILE_CHECK_PATTERN = r'check:\s*\'(?P<check>.*?)\'' - CAPTCHA_KEY_PATTERN = r'Recaptcha.create\(\s*"(.*?)",' - WAIT_PATTERN = r'id="startWait" value="(?P<wait>\d+)"' - FILE_URL_PATTERN = r'<p[^>]*?id="downloadLinkTarget"[^>]*>\s*<a href="(?P<url>.*?)"' - - - def setup(self): - self.multiDL = self.resumeDownloads = self.premium def process(self, pyfile): - # Check file - pyfile.name, pyfile.size, status, self.url = checkFile(self, [pyfile.url])[0] - if status != 2: self.offline() - self.logDebug("File Name: %s Size: %d" % (pyfile.name, pyfile.size)) - - # Handle downloading - url = self.checkDirectDownload(pyfile.url) - if url: - self.download(url) - else: - self.html = self.load(pyfile.url, decode = True) - - if self.premium: - self.handlePremium() - else: - self.handleFree() - - def checkDirectDownload(self, url): - for i in range(5): - header = self.load(url, just_header = True) - if 'location' in header: - url = header['location'].strip() - if not url.startswith("http://"): - url = "http://www.filefactory.com" + url - self.logDebug('URL: ' + url) - elif 'content-disposition' in header: - return url - - return False - + if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): + self.handlePremium() + else: + self.handleFree() + def handleFree(self): + self.html = self.load(self.pyfile.url, decode=True) if "Currently only Premium Members can download files larger than" in self.html: self.fail("File too large for free download") elif "All free download slots on this server are currently in use" in self.html: self.retry(50, 900, "All free slots are busy") - - url = re.search(r"document\.location\.host \+\s*'(.+)';", self.html).group(1) - if not url.startswith('"http://"'): - url = 'http://www.filefactory.com' + url + + url = re.search(r"document\.location\.host \+\s*'(.+)';", self.html) + if not url: + self.parseError('Unable to detect free link') + url = 'http://www.filefactory.com' + url.group(1) self.html = self.load(url, decode=True) - direct = re.search(r'data-href-direct="(.*)" class="button', self.html).group(1) - waittime = re.search(r'id="startWait" value="(\d+)"', self.html).group(1) - self.setWait(waittime) + waittime = re.search(r'id="startWait" value="(\d+)"', self.html) + if not waittime: + self.parseError('Unable to detect wait time') + self.setWait(int(waittime.group(1))) self.wait() - # # Resolve captcha - # found = re.search(self.CAPTCHA_KEY_PATTERN, self.html) - # recaptcha_key = found.group(1) if found else "6LeN8roSAAAAAPdC1zy399Qei4b1BwmSBSsBN8zm" - # recaptcha = ReCaptcha(self) - # - # # Try up to 5 times - # for i in range(5): - # challenge, code = recaptcha.challenge(recaptcha_key) - # response = json_loads(self.load("http://www.filefactory.com/file/checkCaptcha.php", - # post={"check" : self.check, "recaptcha_challenge_field" : challenge, "recaptcha_response_field" : code})) - # if response['status'] == 'ok': - # self.correctCaptcha() - # break - # else: - # self.invalidCaptcha() - # else: - # self.fail("No valid captcha after 5 attempts") - # - # # This will take us to a wait screen - # waiturl = "http://www.filefactory.com" + response['path'] - # self.logDebug("Fetching wait with url [%s]" % waiturl) - # waithtml = self.load(waiturl, decode=True) - # found = re.search(r'<a href="(http://www.filefactory.com/dlf/.*?)"', waithtml) - # waithtml = self.load(found.group(1), decode=True) - # - # # Find the wait value and wait - # wait = int(re.search(self.WAIT_PATTERN, waithtml).group('wait')) - # self.logDebug("Waiting %d seconds." % wait) - # self.setWait(wait, True) - # self.wait() - # - # # Now get the real download url and retrieve the file - # url = re.search(self.FILE_URL_PATTERN,waithtml).group('url') - # # this may either download our file or forward us to an error page - # self.logDebug("Download URL: %s" % url) - self.download(direct) - + direct = re.search(r'data-href-direct="(.*)" class="button', self.html) + if not direct: + self.parseError('Unable to detect free direct link') + direct = direct.group(1) + self.logDebug('DIRECT LINK: ' + direct) + self.download(direct, disposition=True) + check = self.checkDownload({"multiple": "You are currently downloading too many files at once.", "error": '<div id="errorMessage">'}) if check == "multiple": - self.setWait(15*60) self.logDebug("Parallel downloads detected; waiting 15 minutes") - self.wait() - self.retry() + self.retry(wait_time=15 * 60, reason='Parallel downloads') elif check == "error": self.fail("Unknown error") - + def handlePremium(self): - self.fail('Please enable direct downloads') - -def getInfo(urls): - for chunk in chunks(urls, 100): yield checkFile(FilefactoryCom, chunk) + header = self.load(self.pyfile.url, just_header=True) + if 'location' in header: + url = header['location'].strip() + if not url.startswith("http://"): + url = "http://www.filefactory.com" + url + elif 'content-disposition' in header: + url = self.pyfile.url + else: + self.parseError('Unable to detect premium direct link') + + self.logDebug('DIRECT PREMIUM LINK: ' + url) + self.download(url, disposition=True) -- cgit v1.2.3 From 7d4dbda910413ab5db4e689a3b73d83676cd1b23 Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Mon, 8 Apr 2013 00:25:03 +0300 Subject: FilefactoryCom: removed unused constants + code comments --- module/plugins/hoster/FilefactoryCom.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index e92c1505d..aebf0f38d 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -57,14 +57,11 @@ class FilefactoryCom(SimpleHoster): __name__ = "FilefactoryCom" __type__ = "hoster" __pattern__ = r"https?://(?:www\.)?filefactory\.com/file/(?P<id>[a-zA-Z0-9]+)" - __version__ = "0.38" + __version__ = "0.39" __description__ = """Filefactory.Com File Download Hoster""" __author_name__ = ("stickell") __author_mail__ = ("l.stickell@yahoo.it") - FILE_INFO_PATTERN = r'(?P<N>\S+)\s*</span>\s*</h1>\s*<h2>(?P<S>[\w.]+) (?P<U>\w+) file uploaded' - FILE_OFFLINE_PATTERN = r'<title>File Not Found' - def process(self, pyfile): if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): self.handlePremium() @@ -78,18 +75,21 @@ class FilefactoryCom(SimpleHoster): elif "All free download slots on this server are currently in use" in self.html: self.retry(50, 900, "All free slots are busy") + # Load the page that contains the direct link url = re.search(r"document\.location\.host \+\s*'(.+)';", self.html) if not url: self.parseError('Unable to detect free link') url = 'http://www.filefactory.com' + url.group(1) self.html = self.load(url, decode=True) + # Free downloads wait time waittime = re.search(r'id="startWait" value="(\d+)"', self.html) if not waittime: self.parseError('Unable to detect wait time') self.setWait(int(waittime.group(1))) self.wait() + # Parse the direct link and download it direct = re.search(r'data-href-direct="(.*)" class="button', self.html) if not direct: self.parseError('Unable to detect free direct link') -- cgit v1.2.3 From adc259b69f1b283c92cfcb759fffc05d777a309a Mon Sep 17 00:00:00 2001 From: philou75 <pjupin@gmail.com> Date: Mon, 8 Apr 2013 23:00:02 +0300 Subject: Update OneFichierCom.py Waiting pattern correction following hoster modification --- module/plugins/hoster/OneFichierCom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py index 7b87bbe71..5d7e14f1e 100644 --- a/module/plugins/hoster/OneFichierCom.py +++ b/module/plugins/hoster/OneFichierCom.py @@ -19,7 +19,7 @@ class OneFichierCom(SimpleHoster): DOWNLOAD_LINK_PATTERN = r'<br/> <br/> <br/> \s+<a href="(?P<url>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 at least (\d+) minutes between each downloads." + 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." def process(self, pyfile): found = re.search(self.__pattern__, pyfile.url) file_id = found.group(2) -- cgit v1.2.3 From 7a2980d939b64e20c2c3ec5891dae2afcce550d0 Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Tue, 9 Apr 2013 20:46:39 +0200 Subject: UploadedTo: getID uses the __pattern__ regex to avoid duplication. + test links + https support + content-disposition --- module/plugins/hoster/UploadedTo.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py index 874b04d64..c7ce5846e 100644 --- a/module/plugins/hoster/UploadedTo.py +++ b/module/plugins/hoster/UploadedTo.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- +# Test links (random.bin): +# http://ul.to/044yug9o +# http://ul.to/gzfhd0xs + import re from module.utils import html_unescape, parseFileSize @@ -14,7 +18,7 @@ key = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=".decode('base64') def getID(url): """ returns id from file url""" - m = re.match(r"http://[\w\.-]*?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)", url) + m = re.match(UploadedTo.__pattern__, url) return m.group('ID') @@ -77,8 +81,8 @@ def getInfo(urls): class UploadedTo(Hoster): __name__ = "UploadedTo" __type__ = "hoster" - __pattern__ = r"http://[\w\.-]*?(uploaded\.(to|net)(/file/|/?\?id=|.*?&id=)|ul\.to/)\w+" - __version__ = "0.66" + __pattern__ = r"https?://[\w\.-]*?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)" + __version__ = "0.67" __description__ = """Uploaded.net Download Hoster""" __author_name__ = ("spoob", "mkaay", "zoidberg", "netpok", "stickell") __author_mail__ = ("spoob@pyload.org", "mkaay@mkaay.de", "zoidberg@mujmail.cz", "netpok@gmail.com", "l.stickell@yahoo.it") @@ -221,7 +225,7 @@ class UploadedTo(Hoster): if not downloadURL: self.fail("No Download url retrieved/all captcha attempts failed") - self.download(downloadURL) + self.download(downloadURL, disposition=True) check = self.checkDownload({"limit-dl": self.DL_LIMIT_PATTERN}) if check == "limit-dl": self.setWait(60 * 60, True) -- cgit v1.2.3 From 95f56ae40b7c6a56b959b512aa82c8674377c31c Mon Sep 17 00:00:00 2001 From: Gonzalo SR <gonzalo@gonzalosr.com> Date: Thu, 11 Apr 2013 15:16:13 +0300 Subject: Fixed incorrect use of rstrip() rstrip() ate the last "r" in .rar files. "The chars argument is not a suffix; rather, all combinations of its values are stripped" (see http://docs.python.org/2/library/stdtypes.html#str.rstrip) Using rsplit() instead. --- module/plugins/hoster/MegaNz.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/MegaNz.py b/module/plugins/hoster/MegaNz.py index a28ddca9d..3b64c3ef5 100644 --- a/module/plugins/hoster/MegaNz.py +++ b/module/plugins/hoster/MegaNz.py @@ -19,7 +19,7 @@ class MegaNz(Hoster): __name__ = "MegaNz" __type__ = "hoster" __pattern__ = r"https?://([a-z0-9]+\.)?mega\.co\.nz/#!([a-zA-Z0-9!_\-]+)" - __version__ = "0.11" + __version__ = "0.12" __description__ = """mega.co.nz hoster plugin""" __author_name__ = ("RaNaN", ) __author_mail__ = ("ranan@pyload.org", ) @@ -34,7 +34,7 @@ class MegaNz(Hoster): def getCipherKey(self, key): """ Construct the cipher key from the given data """ a = array("I", key) - key_array = array("I", [a[0] ^ a[4], a[1] ^a[5], a[2] ^ a[6], a[3] ^a[7]]) + key_array = array("I", [a[0] ^ a[4], a[1] ^ a[5], a[2] ^ a[6], a[3] ^ a[7]]) return key_array def callApi(self, **kwargs): @@ -55,7 +55,7 @@ class MegaNz(Hoster): self.fail(_("Decryption failed")) # Data is padded, 0-bytes must be stripped - return json.loads(attr.replace("MEGA", "").rstrip("\0").strip()) + return json.loads(attr.replace("MEGA", "").rsplit("\0")[0].strip()) def decryptFile(self, key): """ Decrypts the file at lastDownload` """ @@ -69,7 +69,7 @@ class MegaNz(Hoster): self.pyfile.setStatus("decrypting") f = open(self.lastDownload, "rb") - df = open(self.lastDownload.rstrip(self.FILE_SUFFIX), "wb") + df = open(self.lastDownload.rsplit(self.FILE_SUFFIX)[0], "wb") # TODO: calculate CBC-MAC for checksum -- cgit v1.2.3 From 2f9dc56db6fc84e9915b7b8bc7892b880fe03059 Mon Sep 17 00:00:00 2001 From: Gonzalo SR <gonzalo@gonzalosr.com> Date: Thu, 11 Apr 2013 19:07:46 +0300 Subject: revert correct rsrtrip() --- module/plugins/hoster/MegaNz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/MegaNz.py b/module/plugins/hoster/MegaNz.py index 3b64c3ef5..e5be4eeb7 100644 --- a/module/plugins/hoster/MegaNz.py +++ b/module/plugins/hoster/MegaNz.py @@ -55,7 +55,7 @@ class MegaNz(Hoster): self.fail(_("Decryption failed")) # Data is padded, 0-bytes must be stripped - return json.loads(attr.replace("MEGA", "").rsplit("\0")[0].strip()) + return json.loads(attr.replace("MEGA", "").rstrip("\0").strip()) def decryptFile(self, key): """ Decrypts the file at lastDownload` """ -- cgit v1.2.3 From 3b86e3ee0b31bb4b32caa2ac3c2a543b00d290aa Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Fri, 12 Apr 2013 15:20:09 +0200 Subject: EgoFilesCom: fixed FILE_INFO_PATTERN --- module/plugins/hoster/EgoFilesCom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/EgoFilesCom.py b/module/plugins/hoster/EgoFilesCom.py index ad278e60f..4e78a5b9a 100644 --- a/module/plugins/hoster/EgoFilesCom.py +++ b/module/plugins/hoster/EgoFilesCom.py @@ -28,12 +28,12 @@ class EgoFilesCom(SimpleHoster): __name__ = "EgoFilesCom" __type__ = "hoster" __pattern__ = r"https?://(www\.)?egofiles.com/(\w+)" - __version__ = "0.11" + __version__ = "0.12" __description__ = """Egofiles.com Download Hoster""" __author_name__ = ("stickell") __author_mail__ = ("l.stickell@yahoo.it") - FILE_INFO_PATTERN = r'<div class="down-file">\s+(?P<N>\S+)\s+<div class="file-properties">\s+(File size|Rozmiar): (?P<S>[\w.]+) (?P<U>\w+) \|' + FILE_INFO_PATTERN = r'<div class="down-file">\s+(?P<N>.+)\s+<div class="file-properties">\s+(File size|Rozmiar): (?P<S>[\w.]+) (?P<U>\w+) \|' FILE_OFFLINE_PATTERN = r'(File size|Rozmiar): 0 KB' WAIT_TIME_PATTERN = r'For next free download you have to wait <strong>((?P<m>\d*)m)? ?((?P<s>\d+)s)?</strong>' DIRECT_LINK_PATTERN = r'<a href="(?P<link>[^"]+)">Download ></a>' -- cgit v1.2.3 From c235e869a50d8783b01f5a46d5b93e171cbbb71e Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Fri, 12 Apr 2013 15:30:17 +0200 Subject: New debrid: MultiDebridCom http://forum.pyload.org/viewtopic.php?f=13&t=2426 --- module/plugins/hoster/MultiDebridCom.py | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 module/plugins/hoster/MultiDebridCom.py (limited to 'module/plugins/hoster') diff --git a/module/plugins/hoster/MultiDebridCom.py b/module/plugins/hoster/MultiDebridCom.py new file mode 100644 index 000000000..ca98e8a0e --- /dev/null +++ b/module/plugins/hoster/MultiDebridCom.py @@ -0,0 +1,57 @@ +# -*- 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.Hoster import Hoster +from module.common.json_layer import json_loads + + +class MultiDebridCom(Hoster): + __name__ = "MultiDebridCom" + __version__ = "0.01" + __type__ = "hoster" + __pattern__ = r"http://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/dl/" + __description__ = """Multi-debrid.com hoster plugin""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + def init(self): + self.chunkLimit = -1 + self.resumeDownload = True + + def process(self, pyfile): + if not self.account: + self.logError("Please enter your Multi-debrid.com account or deactivate this plugin") + self.fail("No Multi-debrid.com account provided") + + self.logDebug("Original URL: %s" % pyfile.url) + if re.match(self.__pattern__, pyfile.url): + new_url = pyfile.url + else: + page = self.req.load('http://multi-debrid.com/api.php', + get={'user': self.user, 'pass': self.account.getAccountData(self.user)['password'], + 'link': pyfile.url}) + self.logDebug("JSON data: " + page) + page = json_loads(page) + if page['status'] != 'ok': + self.fail('Unable to unrestrict link') + new_url = page['link'] + + self.logDebug("Unrestricted URL: " + new_url) + + self.download(new_url, disposition=True) -- cgit v1.2.3