From 5a1cd89497598daffdd643114db7a033cf46a807 Mon Sep 17 00:00:00 2001 From: zoidberg10 Date: Wed, 7 Mar 2012 22:27:53 +0100 Subject: AllDebrid plugin by Andy, Voigt; closed #555; generic XFileSharingPro plugin --- module/network/HTTPRequest.py | 1 + module/plugins/accounts/AlldebridCom.py | 27 ++++ module/plugins/accounts/BayfilesCom.py | 17 ++- module/plugins/hooks/AlldebridCom.py | 26 ++++ module/plugins/hoster/AlldebridCom.py | 65 +++++++++ module/plugins/hoster/BitshareCom.py | 2 + module/plugins/hoster/CramitIn.py | 20 +++ module/plugins/hoster/EasybytezCom.py | 106 +++------------ module/plugins/hoster/FiledinoCom.py | 18 +++ module/plugins/hoster/FreakshareCom.py | 27 ++-- module/plugins/hoster/RarefileNet.py | 26 ++++ module/plugins/hoster/XFileSharingPro.py | 224 +++++++++++++++++++++++++++++++ module/plugins/internal/SimpleHoster.py | 54 +++++--- 13 files changed, 482 insertions(+), 131 deletions(-) create mode 100644 module/plugins/accounts/AlldebridCom.py create mode 100644 module/plugins/hooks/AlldebridCom.py create mode 100644 module/plugins/hoster/AlldebridCom.py create mode 100644 module/plugins/hoster/CramitIn.py create mode 100644 module/plugins/hoster/FiledinoCom.py create mode 100644 module/plugins/hoster/RarefileNet.py create mode 100644 module/plugins/hoster/XFileSharingPro.py diff --git a/module/network/HTTPRequest.py b/module/network/HTTPRequest.py index 40f18f2a5..d4c33bbff 100644 --- a/module/network/HTTPRequest.py +++ b/module/network/HTTPRequest.py @@ -31,6 +31,7 @@ def myquote(url): return quote(url.encode('utf_8') if isinstance(url, unicode) else url, safe="%/:=&?~#+!$,;'@()*[]") def myurlencode(data): + data = dict(data) return urlencode(dict((x.encode('utf_8') if isinstance(x, unicode) else x, \ y.encode('utf_8') if isinstance(y, unicode) else y ) for x, y in data.iteritems())) diff --git a/module/plugins/accounts/AlldebridCom.py b/module/plugins/accounts/AlldebridCom.py new file mode 100644 index 000000000..4968e9bdd --- /dev/null +++ b/module/plugins/accounts/AlldebridCom.py @@ -0,0 +1,27 @@ +from module.plugins.Account import Account +import xml.dom.minidom as dom +from time import time + +class AlldebridCom(Account): + __name__ = "AlldebridCom" + __version__ = "0.1" + __type__ = "account" + __description__ = """AllDebrid.com account plugin""" + __author_name__ = ("Andy, Voigt") + __author_mail__ = ("spamsales@online.de") + + def loadAccountInfo(self, user, req): + data = self.getAccountData(user) + page = req.load("http://www.alldebrid.com/api.php?action=info_user&login=%s&pw=%s" % (user, data["password"])) + self.log.debug(page) + xml = dom.parseString(page) + account_info = {"validuntil": (time()+int(xml.getElementsByTagName("date")[0].childNodes[0].nodeValue)*86400), + "trafficleft": -1} + + return account_info + + def login(self, user, data, req): + page = req.load("http://www.alldebrid.com/register/?action=login&login_login=%s&login_password=%s" % (user, data["password"])) + + if "This login doesn't exist" in page: + self.wrongPassword() diff --git a/module/plugins/accounts/BayfilesCom.py b/module/plugins/accounts/BayfilesCom.py index 803e602cb..0d036488b 100644 --- a/module/plugins/accounts/BayfilesCom.py +++ b/module/plugins/accounts/BayfilesCom.py @@ -20,23 +20,28 @@ from module.plugins.Account import Account from module.common.json_layer import json_loads import re -from time import mktime, strptime +from time import time, mktime, strptime class BayfilesCom(Account): __name__ = "BayfilesCom" - __version__ = "0.01" + __version__ = "0.02" __type__ = "account" __description__ = """bayfiles.com account plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") def loadAccountInfo(self, user, req): - response = json_loads(req.load("http://api.bayfiles.com/v1/account/info")) - self.logDebug(response) - + for i in range(2): + response = json_loads(req.load("http://api.bayfiles.com/v1/account/info")) + self.logDebug(response) + if not response["error"]: + break + self.logWarning(response["error"]) + self.relogin() + return {"premium": bool(response['premium']), \ "trafficleft": -1, \ - "validuntil": response['expires'] if response['expires'] > 0 else -1} + "validuntil": response['expires'] if response['expires'] >= int(time()) else -1} def login(self, user, data, req): response = json_loads(req.load("http://api.bayfiles.com/v1/account/login/%s/%s" % (user, data["password"]))) diff --git a/module/plugins/hooks/AlldebridCom.py b/module/plugins/hooks/AlldebridCom.py new file mode 100644 index 000000000..d3d6ff294 --- /dev/null +++ b/module/plugins/hooks/AlldebridCom.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# should be working + +from module.network.RequestFactory import getURL +from module.plugins.internal.MultiHoster import MultiHoster + +class AlldebridCom(MultiHoster): + __name__ = "AlldebridCom" + __version__ = "0.1" + __type__ = "hook" + + __config__ = [("activated", "bool", "Activated", "False"), + ("https", "bool", "Enable HTTPS", "False")] + + __description__ = """Real-Debrid.com hook plugin""" + __author_name__ = ("Andy, Voigt") + __author_mail__ = ("spamsales@online.de") + + replacements = [("freakshare.net", "freakshare.com")] + + def getHoster(self): + https = "https" if self.getConfig("https") else "http" + page = getURL(https + "://www.alldebrid.com/api.php?action=get_host").replace("\"","").strip() + + return[x.strip() for x in page.split(",") if x.strip()] diff --git a/module/plugins/hoster/AlldebridCom.py b/module/plugins/hoster/AlldebridCom.py new file mode 100644 index 000000000..56e3a9040 --- /dev/null +++ b/module/plugins/hoster/AlldebridCom.py @@ -0,0 +1,65 @@ +#!/usr/nv python +# -*- coding: utf-8 -*- + +import BeautifulSoup +from urllib import quote, unquote +from random import randrange + +from module.plugins.Hoster import Hoster + +class AlldebridCom(Hoster): + __name__ = "AlldebridCom" + __version__ = "0.1" + __type__ = "hoster" + + __pattern__ = r"https?://.*alldebrid\..*" + __description__ = """Alldebrid.com hoster plugin""" + __author_name__ = ("Andy, Voigt") + __author_mail__ = ("spamsales@online.de") + + def getFilename(self, url): + try: + name = unquote(url.rsplit("/", 1)[1]) + except IndexError: + name = "Unknown_Filename..." + if name.endswith("..."): #incomplete filename, append random stuff + name += "%s.tmp" % randrange(100,999) + return name + + def init(self): + self.tries = 0 + self.chunkLimit = 3 + self.resumeDownload = True + + + def process(self, pyfile): + url="http://www.alldebrid.com/service.php?link=%s" %(pyfile.url) + + page = self.load(url) + + soup = BeautifulSoup.BeautifulSoup(page) + for link in soup.findAll("a"): + new_url = link.get("href") + + + if self.getConfig("https"): + new_url = new_url.replace("http://", "https://") + else: + new_url = new_url.replace("https://", "http://") + + self.log.debug("AllDebrid: New URL: %s" % new_url) + + + if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown"): + #only use when name wasnt already set + pyfile.name = self.getFilename(new_url) + + self.download(new_url, disposition=True) + + check = self.checkDownload( + {"error": "An error occured while processing your request"}) + + if check == "error": + #usual this download can safely be retried + self.retry(reason="An error occured while generating link.", wait_time=60) + diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py index 794e978b2..d6288883d 100644 --- a/module/plugins/hoster/BitshareCom.py +++ b/module/plugins/hoster/BitshareCom.py @@ -92,6 +92,8 @@ class BitshareCom(Hoster): self.handleFree() def handleFree(self): + if "Only Premium members can access this file" in self.html: + self.fail("Only Premium members can access this file") # Get download info self.logDebug("Getting download info") diff --git a/module/plugins/hoster/CramitIn.py b/module/plugins/hoster/CramitIn.py new file mode 100644 index 000000000..a7935c744 --- /dev/null +++ b/module/plugins/hoster/CramitIn.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo + +class CramitIn(XFileSharingPro): + __name__ = "CramitIn" + __type__ = "hoster" + __pattern__ = r"http://(?:\w*\.)*cramit.in/\w{12}" + __version__ = "0.03" + __description__ = """Cramit.in hoster plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + FILE_INFO_PATTERN = r'\s*(?P.*?).*?\s*\((?P.*?)\)' + DIRECT_LINK_PATTERN = r'href="(http://cramit.in/file_download/.*?)"' + HOSTER_NAME = "cramit.in" + + def setup(self): + self.multiDL = self.premium + +getInfo = create_getInfo(CramitIn) \ No newline at end of file diff --git a/module/plugins/hoster/EasybytezCom.py b/module/plugins/hoster/EasybytezCom.py index 4fbd08756..25de9b341 100644 --- a/module/plugins/hoster/EasybytezCom.py +++ b/module/plugins/hoster/EasybytezCom.py @@ -16,129 +16,59 @@ @author: zoidberg """ -import re -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo -from random import random +from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo -class EasybytezCom(SimpleHoster): +class EasybytezCom(XFileSharingPro): __name__ = "EasybytezCom" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)?easybytez.com/(\w+).*" - __version__ = "0.05" + __version__ = "0.06" __description__ = """easybytez.com""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") - - # shares code with TurbouploadCom FILE_NAME_PATTERN = r'[^<]+ \((?P[^<]+)\)' FILE_INFO_PATTERN = r'Filename:(?P[^<]+)\s*.*?\((?P[^<]+)\)' - FILE_OFFLINE_PATTERN = r'

File Not Found

' - FORM_INPUT_PATTERN = r']* name="([^"]+)"[^>]*value="([^"]*)"' - WAIT_PATTERN = r'[^>]*>(\d+) seconds' DIRECT_LINK_PATTERN = r'(http://(\w+\.easybytez\.com|\d+\.\d+\.\d+\.\d+)/files/\d+/\w+/[^"<]+)' - - FORM_PATTERN = r'
]*action=["\']?([^"\' ]+)(.*?)
' OVR_DOWNLOAD_LINK_PATTERN = r'

Download Link

\s*]*>([^<]+)' OVR_KILL_LINK_PATTERN = r'

Delete Link

\s*]*>([^<]+)' - TEXTAREA_PATTERN = r"" - - HOSTER_URL = "www.easybytez.com" - - def process(self, pyfile): - if not re.match(self.__pattern__, self.pyfile.url): - if self.premium: - self.handleOverriden() - else: - self.fail("Only premium users can download from other hosters with %s" % self.HOSTER_URL) - else: - self.html = self.load(pyfile.url, cookies = False, decode = True) - self.file_info = self.getFileInfo() - - header = self.load(self.pyfile.url, just_header = True, cookies = True) - self.logDebug(header) - - if 'location' in header and re.match(self.DIRECT_LINK_PATTERN, header['location']): - self.downloadLink(header['location']) - elif self.premium: - self.handlePremium() - else: - self.handleFree() - def handleFree(self): - self.download(self.pyfile.url, post = self.getPostParameters(), ref = True, cookies = True) + HOSTER_NAME = "easybytez.com" + def setup(self): + self.resumeDownload = self.multiDL = self.premium + def handlePremium(self): - self.html = self.load(self.pyfile.url, post = self.getPostParameters(premium=True)) + self.html = self.load(self.pyfile.url, post = self.getPostParameters()) found = re.search(self.DIRECT_LINK_PATTERN, self.html) if not found: self.parseError('DIRECT LINK') - self.downloadLink(found.group(1)) - + self.startDownload(found.group(1)) + def handleOverriden(self): self.html = self.load(self.HOSTER_URL) - action, form = re.search(self.FORM_PATTERN % "url", self.html, re.DOTALL).groups() - inputs = dict(re.findall(self.FORM_INPUT_PATTERN, form)) + action, inputs = self.parseHtmlForm('') upload_id = "%012d" % int(random()*10**12) - action += upload_id + "&js_on=1&utype=prem&upload_type=url" + action += upload_id + "&js_on=1&utype=prem&upload_type=url" inputs['tos'] = '1' inputs['url_mass'] = self.pyfile.url - inputs['up1oad_type'] = 'url' - + inputs['up1oad_type'] = 'url' + self.logDebug(action, inputs) self.html = self.load(action, post = inputs) - - found = re.search(self.FORM_PATTERN % "F1", self.html, re.S | re.I) - if not found: - self.logDebug(self.html) - self.fail("upload failed") - action, form = found.groups() - - inputs = dict(re.findall(self.TEXTAREA_PATTERN, form)) + + action, inputs = self.parseHtmlForm('name="F1"') if not inputs: parseError('TEXTAREA') - self.logDebug(inputs) + self.logDebug(inputs) if inputs['st'] == 'OK': self.html = self.load(action, post = inputs) else: self.fail(inputs['st']) - + found = re.search(self.OVR_DOWNLOAD_LINK_PATTERN, self.html) if not found: self.parseError('DIRECT LINK (OVR)') self.pyfile.url = found.group(1) self.retry() - - def downloadLink(self, link): - self.logDebug('DIRECT LINK: %s' % link) - self.download(link) - - def getPostParameters(self, premium=False): - inputs = dict(re.findall(self.FORM_INPUT_PATTERN, self.html)) - self.logDebug(inputs) - - if 'op' in inputs and inputs['op'] == 'download2': return inputs - - inputs['referer'] = self.pyfile.url - - if premium: - inputs['method_premium'] = "Premium Download" - if 'method_free' in inputs: del inputs['method_free'] - else: - inputs['method_free'] = "Free Download" - if 'method_premium' in inputs: del inputs['method_premium'] - - self.html = self.load(self.pyfile.url, post = inputs, ref = True, cookies = True) - inputs = dict(re.findall(self.FORM_INPUT_PATTERN, self.html)) - self.logDebug(inputs) - - if not premium: - found = re.search(self.WAIT_PATTERN, self.html) - self.setWait(int(found.group(1)) + 1 if found else 60) - self.wait() - - return inputs - - def urlParseFileName(self): - return html_unescape(urlparse(self.pyfile.url).path.split("/")[-1]) getInfo = create_getInfo(EasybytezCom) \ No newline at end of file diff --git a/module/plugins/hoster/FiledinoCom.py b/module/plugins/hoster/FiledinoCom.py new file mode 100644 index 000000000..7d1a82df4 --- /dev/null +++ b/module/plugins/hoster/FiledinoCom.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo + +class FiledinoCom(XFileSharingPro): + __name__ = "FiledinoCom" + __type__ = "hoster" + __pattern__ = r"http://(?:\w*\.)*filedino.com/\w{12}" + __version__ = "0.01" + __description__ = """FileDino.com hoster plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + FILE_SIZE_PATTERN = r'File Size : (?P.+?)' + + HOSTER_NAME = "filedino.com" + DIRECT_LINK_PATTERN = r'http://www\.filedino\.com/cgi-bin/dl\.cgi/' + +getInfo = create_getInfo(FiledinoCom) \ No newline at end of file diff --git a/module/plugins/hoster/FreakshareCom.py b/module/plugins/hoster/FreakshareCom.py index 869b8a99e..a36fe7207 100644 --- a/module/plugins/hoster/FreakshareCom.py +++ b/module/plugins/hoster/FreakshareCom.py @@ -9,7 +9,7 @@ class FreakshareCom(Hoster): __name__ = "FreakshareCom" __type__ = "hoster" __pattern__ = r"http://(?:www\.)?freakshare\.(net|com)/files/\S*?/" - __version__ = "0.33" + __version__ = "0.34" __description__ = """Freakshare.com Download Hoster""" __author_name__ = ("sitacuisses","spoob","mkaay") __author_mail__ = ("sitacuisses@yahoo.de","spoob@pyload.org","mkaay@mkaay.de") @@ -36,10 +36,15 @@ class FreakshareCom(Hoster): self.download(self.pyfile.url, post=self.req_opts) - check = self.checkDownload({"bad": "bad try"}) + check = self.checkDownload({"bad": "bad try", + "paralell": "> Sorry, you cant download more then 1 files at time. <"}) + if check == "bad": self.fail("Bad Try.") - + if check == "paralell": + self.setWait(300, True) + self.wait() + self.retry() def prepare(self): pyfile = self.pyfile @@ -134,10 +139,7 @@ class FreakshareCom(Hoster): def get_download_options(self): re_envelope = re.search(r".*?value=\"Free\sDownload\".*?\n*?(.*?<.*?>\n*)*?\n*\s*?", self.html).group(0) #get the whole request to_sort = re.findall(r"", re_envelope) - request_options = [] - - for item in to_sort: #Name value pairs are output reversed from regex, so we reorder them - request_options.append((item[1], item[0])) + request_options = {n: v for v, n in to_sort} herewego = self.load(self.pyfile.url, None, request_options) # the actual download-Page @@ -146,21 +148,16 @@ class FreakshareCom(Hoster): # fp.write(herewego) to_sort = re.findall(r"", herewego) - request_options = [] + request_options = {n: v for v, n in to_sort} # comment this in, when it doesnt work as well #print "\n\n%s\n\n" % ";".join(["%s=%s" % x for x in to_sort]) - - for item in to_sort: #Same as above - request_options.append((item[1], item[0])) challenge = re.search(r"http://api\.recaptcha\.net/challenge\?k=([0-9A-Za-z]+)", herewego) if challenge: re_captcha = ReCaptcha(self) - challenge, result = re_captcha.challenge(challenge.group(1)) - - request_options.append(("recaptcha_challenge_field", challenge)) - request_options.append(("recaptcha_response_field", result)) + request_options["recaptcha_challenge_field"], request_options["recaptcha_response_field"] \ + = re_captcha.challenge(challenge.group(1)) return request_options diff --git a/module/plugins/hoster/RarefileNet.py b/module/plugins/hoster/RarefileNet.py new file mode 100644 index 000000000..8339d40eb --- /dev/null +++ b/module/plugins/hoster/RarefileNet.py @@ -0,0 +1,26 @@ +# -*- 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.01" + __description__ = """Rarefile.net hoster plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + FILE_NAME_PATTERN = r'(?P.*?)' + FILE_SIZE_PATTERN = r'Size : (?P.+?) ' + + def handleCaptcha(self, inputs): + captcha_div = re.search(r'Enter code.*?(.*?)', self.html, re.S).group(1) + 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) + return 3 + +getInfo = create_getInfo(RarefileNet) \ No newline at end of file diff --git a/module/plugins/hoster/XFileSharingPro.py b/module/plugins/hoster/XFileSharingPro.py new file mode 100644 index 000000000..c7a59c81e --- /dev/null +++ b/module/plugins/hoster/XFileSharingPro.py @@ -0,0 +1,224 @@ +# -*- 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 . + + @author: zoidberg +""" + +import re +from random import random +from urllib import unquote +from pycurl import FOLLOWLOCATION +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.ReCaptcha import ReCaptcha + +class XFileSharingPro(SimpleHoster): + """ + Common base for XFileSharingPro hosters like EasybytezCom, CramitIn, FiledinoCom... + Some hosters may work straight away when added to __pattern__ + """ + __name__ = "XFileSharingPro" + __type__ = "hoster" + __pattern__ = r"http://(?:\w*\.)*(boosterking\.com|migahost\.com|fileband\.com|ravishare\.com)/\w{12}" + __version__ = "0.01" + __description__ = """XFileSharingPro common hoster base""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + FILE_NAME_PATTERN = r'[^<]+ \((?P[^<]+)\)' + FILE_INFO_PATTERN = r'Filename:(?P[^<]+)\s*.*?\((?P[^<]+)\)' + FILE_OFFLINE_PATTERN = r'<(b|h2)>File Not Found' + + WAIT_PATTERN = r'.*?>(\d+)' + OVR_DOWNLOAD_LINK_PATTERN = r'

Download Link

\s*]*>([^<]+)' + OVR_KILL_LINK_PATTERN = r'

Delete Link

\s*]*>([^<]+)' + CAPTCHA_URL_PATTERN = r'(http://[^"\']+?/captchas/[^"\']+)' + RECAPTCHA_URL_PATTERN = r'http://[^"\']+?recaptcha[^"\']+?\?k=([^"\']+)"' + ERROR_PATTERN = r'class="err">(.*?)<' + + DIRECT_LINK_PATTERN = r'This direct link.*?href=["\'](.*?)["\']' + + def setup(self): + self.HOSTER_NAME = re.search(self.__pattern__, self.pyfile.url).group(1) + self.multiDL = True + + def process(self, pyfile): + self.captcha = self.errmsg = None + self.passwords = self.getPassword().splitlines() + + if not re.match(self.__pattern__, self.pyfile.url): + if self.premium: + self.handleOverriden() + else: + self.fail("Only premium users can download from other hosters with %s" % self.HOSTER_NAME) + else: + self.html = self.load(pyfile.url, cookies = False, decode = True) + self.file_info = self.getFileInfo() + + self.header = self.load(self.pyfile.url, just_header = True, cookies = True) + self.logDebug(self.header) + + if 'location' in self.header and re.match(self.DIRECT_LINK_PATTERN, self.header['location']): + self.startDownload(self.header['location']) + elif self.premium: + self.handlePremium() + else: + self.handleFree() + + def handleFree(self): + for i in range(5): + data = self.getPostParameters() + + self.req.http.c.setopt(FOLLOWLOCATION, 0) + self.html = self.load(self.pyfile.url, post = data, ref = True) + self.header = self.req.http.header + self.req.http.c.setopt(FOLLOWLOCATION, 1) + + found = re.search("Location\s*:\s*(.*)", self.header, re.I) + if found: + break + elif not self.checkErrors(): + found = re.search(self.DIRECT_LINK_PATTERN, self.html, re.S) + if not found: self.parseError('Download Link') + break + + else: self.fail("No valid captcha code entered") + + self.startDownload(found.group(1)) + + def handlePremium(self): + self.html = self.load(self.pyfile.url, post = self.getPostParameters()) + found = re.search(self.DIRECT_LINK_PATTERN, self.html) + if not found: self.parseError('DIRECT LINK') + self.startDownload(found.group(1)) + + def handleOverriden(self): + self.html = self.load("http://www.%s" % self.HOSTER_NAME) + action, inputs = self.parseHtmlForm('') + upload_id = "%012d" % int(random()*10**12) + action += upload_id + "&js_on=1&utype=prem&upload_type=url" + inputs['tos'] = '1' + inputs['url_mass'] = self.pyfile.url + inputs['up1oad_type'] = 'url' + + self.logDebug(action, inputs) + self.html = self.load(action, post = inputs) + + action, inputs = self.parseHtmlForm('name="F1"') + if not inputs: parseError('TEXTAREA') + self.logDebug(inputs) + if inputs['st'] == 'OK': + self.html = self.load(action, post = inputs) + else: + self.fail(inputs['st']) + + found = re.search(self.OVR_DOWNLOAD_LINK_PATTERN, self.html) + if not found: self.parseError('DIRECT LINK (OVR)') + self.pyfile.url = found.group(1) + self.retry() + + def startDownload(self, link): + if self.captcha: self.correctCaptcha() + self.logDebug('DIRECT LINK: %s' % link) + self.download(link) + + def checkErrors(self): + found = re.search(self.ERROR_PATTERN, self.html) + if found: + self.errmsg = found.group(1) + self.logWarning(self.errmsg) + + if 'wait' in self.errmsg: + wait_time = sum([int(v) * {"hour": 3600, "minute": 60, "second": 1}[u] for v, u in re.findall('(\d+)\s*(hour|minute|second)?', self.errmsg)]) + self.setWait(wait_time, True) + self.wait() + elif 'captcha' in self.errmsg: + self.invalidCaptcha() + elif 'countdown' in self.errmsg: + self.retry(3) + + else: + self.errmsg = None + + return self.errmsg + + def getPostParameters(self): + for i in range(3): + if not self.errmsg: self.checkErrors() + + action, inputs = self.parseHtmlForm("action=['\"]{2}") + if not inputs: + if self.errmsg: + self.retry() + else: + self.parseError("Form not found") + + self.logDebug(inputs) + + if 'op' in inputs and inputs['op'] == 'download2': + if "password" in inputs: + if self.passwords: + inputs['password'] = self.passwords.pop(0) + else: + self.fail("No or invalid passport") + + if not self.premium: + found = re.search(self.WAIT_PATTERN, self.html) + if found: + wait_time = int(found.group(1)) + 1 + self.setWait(wait_time, False) + else: + wait_time = 0 + + self.captcha = self.handleCaptcha(inputs) + + if wait_time: self.wait() + + return inputs + else: + inputs['referer'] = self.pyfile.url + + if self.premium: + inputs['method_premium'] = "Premium Download" + if 'method_free' in inputs: del inputs['method_free'] + else: + inputs['method_free'] = "Free Download" + if 'method_premium' in inputs: del inputs['method_premium'] + + self.html = self.load(self.pyfile.url, post = inputs, ref = True) + self.errmsg = None + + else: self.parseError('FORM: %s' % (inputs['op'] if 'op' in inputs else 'UNKNOWN')) + + def handleCaptcha(self, inputs): + found = re.search(self.RECAPTCHA_URL_PATTERN, self.html) + if found: + recaptcha_key = unquote(found.group(1)) + self.logDebug("RECAPTCHA KEY: %s" % recaptcha_key) + recaptcha = ReCaptcha(self) + inputs['recaptcha_challenge_field'], inputs['recaptcha_response_field'] = recaptcha.challenge(recaptcha_key) + return 1 + else: + found = re.search(self.CAPTCHA_URL_PATTERN, self.html) + if found: + captcha_url = found.group(1) + inputs['code'] = self.decryptCaptcha(captcha_url) + return 2 + return 0 + + def urlParseFileName(self): + return html_unescape(urlparse(self.pyfile.url).path.split("/")[-1]) + +getInfo = create_getInfo(XFileSharingPro) \ No newline at end of file diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index 555eefee3..3ae780ba2 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -42,8 +42,11 @@ def parseHtmlTagAttrValue(attr_name, tag): m = re.search(r"%s\s*=\s*([\"']?)((?<=\")[^\"]+|(?<=')[^']+|[^\s\"'][^>\s]+)\1" % attr_name, tag) return m.group(2) if m else '' -def parseFileInfo(self, url = '', html = '', infomode = False): +def parseFileInfo(self, url = '', html = ''): info = {"name" : url, "size" : 0, "status" : 3} + + if hasattr(self, "pyfile"): + url = self.pyfile.url if hasattr(self, "req") and self.req.http.code == '404': info['status'] = 1 @@ -58,9 +61,14 @@ def parseFileInfo(self, url = '', html = '', infomode = False): info['status'] = 1 else: online = False + try: + info.update(re.match(self.__pattern__, url).groupdict()) + except: + pass + for pattern in ("FILE_INFO_PATTERN", "FILE_NAME_PATTERN", "FILE_SIZE_PATTERN"): try: - info = dict(info, **re.search(getattr(self, pattern), html).groupdict()) + info.update(re.search(getattr(self, pattern), html).groupdict()) online = True except AttributeError: continue @@ -77,12 +85,10 @@ def parseFileInfo(self, url = '', html = '', infomode = False): if 'units' in info: info['size'] += info['units'] info['size'] = parseFileSize(info['size']) - if infomode: - if hasattr(self, "pyfile"): - info = dict(info, **re.match(self.__pattern__, self.pyfile.url).groupdict()) - return info - else: - return info['name'], info['size'], info['status'], url + if hasattr(self, "file_info"): + self.file_info = info + + return info['name'], info['size'], info['status'], url def create_getInfo(plugin): def getInfo(urls): @@ -106,7 +112,7 @@ class PluginParseError(Exception): class SimpleHoster(Hoster): __name__ = "SimpleHoster" - __version__ = "0.20" + __version__ = "0.22" __pattern__ = None __type__ = "hoster" __description__ = """Base hoster plugin""" @@ -127,7 +133,10 @@ class SimpleHoster(Hoster): SH_BROKEN_ENCODING = False # Set to True or encoding name if encoding in http header is not correct SH_COOKIES = True # or False or list of tuples [(domain, name, value)] - SH_CHECK_TRAFFIC = False # True = force check traffic left for a premium account + SH_CHECK_TRAFFIC = False # True = force check traffic left for a premium account + + def init(self): + self.file_info = {} def setup(self): self.resumeDownload = self.multiDL = True if self.premium else False @@ -136,7 +145,7 @@ class SimpleHoster(Hoster): def process(self, pyfile): pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS) self.html = self.load(pyfile.url, decode = not self.SH_BROKEN_ENCODING, cookies = self.SH_COOKIES) - self.file_info = self.getFileInfo() + self.getFileInfo() if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): self.handlePremium() else: @@ -147,25 +156,26 @@ class SimpleHoster(Hoster): if hasattr(self, "TEMP_OFFLINE_PATTERN") and re.search(self.TEMP_OFFLINE_PATTERN, self.html): self.tempOffline() - file_info = parseFileInfo(self, infomode = True) - if file_info['status'] == 1: + name, size, status = parseFileInfo(self)[:3] + + if status == 1: self.offline() - elif file_info['status'] != 2: - self.logDebug(file_info) + elif status != 2: + self.logDebug(self.file_info) self.parseError('File info') - if file_info['name']: - self.pyfile.name = file_info['name'] + if name: + self.pyfile.name = name else: self.pyfile.name = html_unescape(urlparse(self.pyfile.url).path.split("/")[-1]) - if file_info['size']: - self.pyfile.size = file_info['size'] + if size: + self.pyfile.size = size else: self.logError("File size not parsed") self.logDebug("FILE NAME: %s FILE SIZE: %s" % (self.pyfile.name, self.pyfile.size)) - return file_info + return self.file_info def handleFree(self): self.fail("Free download not implemented") @@ -179,10 +189,10 @@ class SimpleHoster(Hoster): def parseHtmlForm(self, attr_str): inputs = {} action = None - form = re.search(r"(?P]*%s[^>]*>)(?P.*?)]*>" % attr_str, self.html, re.S) + form = re.search(r"(?P]*%s[^>]*>)(?P.*?)]*>" % attr_str, self.html, re.S | re.I) if form: action = parseHtmlTagAttrValue("action", form.group('tag')) - for input in re.finditer(r'(<(?:input|textarea)[^>]*>)', form.group('content')): + for input in re.finditer(r'(<(?:input|textarea)[^>]*>)', form.group('content'), re.S | re.I): name = parseHtmlTagAttrValue("name", input.group(1)) if name: inputs[name] = parseHtmlTagAttrValue("value", input.group(1)) -- cgit v1.2.3