def process(self, pyfile): if not self.account: self.logError( _("Please enter your %s account or deactivate this plugin") % "Real-debrid") self.fail("No Real-debrid account provided") self.logDebug("Real-Debrid: Old URL: %s" % pyfile.url) if re.match(self.__pattern__, pyfile.url): new_url = pyfile.url else: password = self.getPassword().splitlines() if not password: password = "" else: password = password[0] url = "http://real-debrid.com/ajax/unrestrict.php?lang=en&link=%s&password=%s&time=%s" % ( quote(pyfile.url, ""), password, int(time() * 1000)) page = self.load(url) data = json_loads(page) self.logDebug("Returned Data: %s" % data) if data["error"] != 0: if data["message"] == "Your file is unavailable on the hoster.": self.offline() else: self.logWarning(data["message"]) self.tempOffline() else: if self.pyfile.name is not None and self.pyfile.name.endswith( '.tmp') and data["file_name"]: self.pyfile.name = data["file_name"] self.pyfile.size = parseFileSize(data["file_size"]) new_url = data['generated_links'][0][-1] if self.getConfig("https"): new_url = new_url.replace("http://", "https://") else: new_url = new_url.replace("https://", "http://") self.logDebug("Real-Debrid: New URL: %s" % new_url) if pyfile.name.startswith("http") or pyfile.name.startswith( "Unknown") or pyfile.name.endswith('..'): #only use when name wasnt already set pyfile.name = self.getFilename(new_url) self.download(new_url, disposition=True) check = self.checkDownload({ "error": "<title>An error occured while processing your request</title>" }) if check == "error": #usual this download can safely be retried self.retry(reason="An error occured while generating link.", wait_time=60)
def handlePremium(self, pyfile): data = json_loads(self.load("https://real-debrid.com/ajax/unrestrict.php", get={'lang' : "en", 'link' : pyfile.url, 'password': self.getPassword(), 'time' : int(time.time() * 1000)})) self.logDebug("Returned Data: %s" % data) if data['error'] != 0: if data['message'] == "Your file is unavailable on the hoster.": self.offline() else: self.logWarning(data['message']) self.tempOffline() else: if pyfile.name and pyfile.name.endswith('.tmp') and data['file_name']: pyfile.name = data['file_name'] pyfile.size = parseFileSize(data['file_size']) self.link = data['generated_links'][0][-1] if self.getConfig('ssl'): self.link = self.link.replace("http://", "https://") else: self.link = self.link.replace("https://", "http://")
def handle_premium(self, pyfile): data = json_loads(self.load("https://real-debrid.com/ajax/unrestrict.php", get={'lang' : "en", 'link' : pyfile.url, 'password': self.getPassword(), 'time' : int(time.time() * 1000)})) self.logDebug("Returned Data: %s" % data) if data['error'] != 0: if data['message'] == "Your file is unavailable on the hoster.": self.offline() else: self.logWarning(data['message']) self.tempOffline() else: if pyfile.name and pyfile.name.endswith('.tmp') and data['file_name']: pyfile.name = data['file_name'] pyfile.size = parseFileSize(data['file_size']) self.link = data['generated_links'][0][-1] if self.getConfig('ssl'): self.link = self.link.replace("http://", "https://") else: self.link = self.link.replace("https://", "http://")
def handle_premium(self, pyfile): https = "https" if self.getConfig('ssl') else "http" data = self.account.getAccountData(self.user) page = self.load(https + "://api.over-load.me/getdownload.php", get={ 'auth': data['password'], 'link': pyfile.url }) data = json_loads(page) self.logDebug(data) if data['error'] == 1: self.logWarning(data['msg']) self.tempOffline() else: if pyfile.name and pyfile.name.endswith( '.tmp') and data['filename']: pyfile.name = data['filename'] pyfile.size = parseFileSize(data['filesize']) http_repl = ["http://", "https://"] self.link = data['downloadlink'].replace( *http_repl if self.getConfig('ssl') else http_repl[::-1])
def checkTrafficLeft(self): # check if user logged in m = re.search(self.USER_CREDIT_PATTERN, self.html) if m is None: self.account.relogin(self.user) self.html = self.load(self.pyfile.url, decode=True) m = re.search(self.USER_CREDIT_PATTERN, self.html) if m is None: return False # check user credit try: credit = parseFileSize(m.group(1).replace(' ', ''), m.group(2)) self.logInfo( _("Premium download for %i KiB of Credit") % (self.pyfile.size / 1024)) self.logInfo( _("User %s has %i KiB left") % (self.user, credit / 1024)) if credit < self.pyfile.size: self.logInfo( _("Not enough credit to download file: %s") % self.pyfile.name) return False except Exception, e: # let's continue and see what happens... self.logError(e)
def process(self, pyfile): if not self.account: self.logError( _("Please enter your %s account or deactivate this plugin") % "AllDebrid") self.fail("No AllDebrid account provided") self.logDebug("AllDebrid: Old URL: %s" % pyfile.url) if re.match(self.__pattern__, pyfile.url): new_url = pyfile.url else: password = self.getPassword().splitlines() password = "" if not password else password[0] url = "http://www.alldebrid.com/service.php?link=%s&json=true&pw=%s" % ( pyfile.url, password) page = self.load(url) data = json_loads(page) self.logDebug("Json data: %s" % str(data)) if data["error"]: if data["error"] == "This link isn't available on the hoster website.": self.offline() else: self.logWarning(data["error"]) self.tempOffline() else: if self.pyfile.name and not self.pyfile.name.endswith('.tmp'): self.pyfile.name = data["filename"] self.pyfile.size = parseFileSize(data["filesize"]) new_url = data["link"] if self.getConfig("https"): new_url = new_url.replace("http://", "https://") else: new_url = new_url.replace("https://", "http://") self.logDebug("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": "<title>An error occured while processing your request</title>", "empty": re.compile(r"^$") }) if check == "error": self.retry(reason="An error occured while generating link.", wait_time=60) elif check == "empty": self.retry(reason="Downloaded File was empty.", wait_time=60)
def process(self, pyfile): if not self.account: self.logError(_("Please enter your %s account or deactivate this plugin") % "Real-debrid") self.fail("No Real-debrid account provided") self.logDebug("Real-Debrid: Old URL: %s" % pyfile.url) if re.match(self.__pattern__, pyfile.url): new_url = pyfile.url else: password = self.getPassword().splitlines() if not password: password = "" else: password = password[0] url = "http://real-debrid.com/ajax/unrestrict.php?lang=en&link=%s&password=%s&time=%s" % ( quote(pyfile.url, ""), password, int(time() * 1000)) page = self.load(url) data = json_loads(page) self.logDebug("Returned Data: %s" % data) if data["error"] != 0: if data["message"] == "Your file is unavailable on the hoster.": self.offline() else: self.logWarning(data["message"]) self.tempOffline() else: if self.pyfile.name is not None and self.pyfile.name.endswith('.tmp') and data["file_name"]: self.pyfile.name = data["file_name"] self.pyfile.size = parseFileSize(data["file_size"]) new_url = data['generated_links'][0][-1] if self.getConfig("https"): new_url = new_url.replace("http://", "https://") else: new_url = new_url.replace("https://", "http://") self.logDebug("Real-Debrid: New URL: %s" % new_url) if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown") or pyfile.name.endswith('..'): #only use when name wasnt already set pyfile.name = self.getFilename(new_url) self.download(new_url, disposition=True) check = self.checkDownload( {"error": "<title>An error occured while processing your request</title>"}) if check == "error": #usual this download can safely be retried self.retry(reason="An error occured while generating link.", wait_time=60)
def loadAccountInfo(self, user, req): #self.relogin(user) html = req.load("http://www.multishare.cz/profil/", decode=True) found = re.search(self.TRAFFIC_LEFT_PATTERN, html) trafficleft = parseFileSize(found.group('S'), found.group('U')) / 1024 if found else 0 self.premium = True if trafficleft else False html = req.load("http://www.multishare.cz/", decode=True) mms_info = dict(re.findall(self.ACCOUNT_INFO_PATTERN, html)) return dict(mms_info, **{"validuntil": -1, "trafficleft": trafficleft})
def checkFile(plugin, urls): html = getURL(plugin.URLS[1], post={"urls": "\n".join(urls)}, decode=True) file_info = [] for li in re.finditer(plugin.LINKCHECK_TR, html, re.S): try: cols = re.findall(plugin.LINKCHECK_TD, li.group(1)) if cols: file_info.append( (cols[1] if cols[1] != '--' else cols[0], parseFileSize(cols[2]) if cols[2] != '--' else 0, 2 if cols[3].startswith('Available') else 1, cols[0])) except Exception, e: continue
def process(self, pyfile): if not self.account: self.logError(_("Please enter your %s account or deactivate this plugin") % "AllDebrid") self.fail("No AllDebrid account provided") self.logDebug("AllDebrid: Old URL: %s" % pyfile.url) if re.match(self.__pattern__, pyfile.url): new_url = pyfile.url else: password = self.getPassword().splitlines() password = "" if not password else password[0] url = "http://www.alldebrid.com/service.php?link=%s&json=true&pw=%s" % (pyfile.url, password) page = self.load(url) data = json_loads(page) self.logDebug("Json data: %s" % str(data)) if data["error"]: if data["error"] == "This link isn't available on the hoster website.": self.offline() else: self.logWarning(data["error"]) self.tempOffline() else: if self.pyfile.name and not self.pyfile.name.endswith('.tmp'): self.pyfile.name = data["filename"] self.pyfile.size = parseFileSize(data["filesize"]) new_url = data["link"] if self.getConfig("https"): new_url = new_url.replace("http://", "https://") else: new_url = new_url.replace("https://", "http://") self.logDebug("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": "<title>An error occured while processing your request</title>", "empty": re.compile(r"^$")}) if check == "error": self.retry(reason="An error occured while generating link.", wait_time=60) elif check == "empty": self.retry(reason="Downloaded File was empty.", wait_time=60)
def checkFile(plugin, urls): html = getURL(plugin.URLS[1], post={"urls": "\n".join(urls)}, decode=True) file_info = [] for li in re.finditer(plugin.LINKCHECK_TR, html, re.S): try: cols = re.findall(plugin.LINKCHECK_TD, li.group(1)) if cols: file_info.append(( cols[1] if cols[1] != '--' else cols[0], parseFileSize(cols[2]) if cols[2] != '--' else 0, 2 if cols[3].startswith('Available') else 1, cols[0])) except Exception, e: continue
def checkTrafficLeft(self): # check if user logged in m = re.search(self.USER_CREDIT_PATTERN, self.html) if m is None: self.account.relogin(self.user) self.html = self.load(self.pyfile.url, decode=True) m = re.search(self.USER_CREDIT_PATTERN, self.html) if m is None: return False # check user credit try: credit = parseFileSize(m.group(1).replace(' ', ''), m.group(2)) self.logInfo(_("Premium download for %i KiB of Credit") % (self.pyfile.size / 1024)) self.logInfo(_("User %s has %i KiB left") % (self.user, credit / 1024)) if credit < self.pyfile.size: self.logInfo(_("Not enough credit to download file: %s") % self.pyfile.name) return False except Exception, e: # let's continue and see what happens... self.logError(e)
def handle_premium(self, pyfile): https = "https" if self.getConfig('ssl') else "http" data = self.account.getAccountData(self.user) page = self.load(https + "://api.over-load.me/getdownload.php", get={'auth': data['password'], 'link': pyfile.url}) data = json_loads(page) self.logDebug(data) if data['error'] == 1: self.logWarning(data['msg']) self.tempOffline() else: if pyfile.name and pyfile.name.endswith('.tmp') and data['filename']: pyfile.name = data['filename'] pyfile.size = parseFileSize(data['filesize']) http_repl = ["http://", "https://"] self.link = data['downloadlink'].replace(*http_repl if self.getConfig('ssl') else http_repl[::-1])
def handlePremium(self, pyfile): password = self.getPassword() data = json_loads(self.load("http://www.alldebrid.com/service.php", get={'link': pyfile.url, 'json': "true", 'pw': password})) self.logDebug("Json data", data) if data['error']: if data['error'] == "This link isn't available on the hoster website.": self.offline() else: self.logWarning(data['error']) self.tempOffline() else: if pyfile.name and not pyfile.name.endswith('.tmp'): pyfile.name = data['filename'] pyfile.size = parseFileSize(data['filesize']) self.link = data['link'] if self.getConfig('ssl'): self.link = self.link.replace("http://", "https://") else: self.link = self.link.replace("https://", "http://")
def parseTraffic(self, string): #returns kbyte return parseFileSize(string) / 1024
class SimpleHoster(Hoster): __name = "SimpleHoster" __type = "hoster" __version = "1.42" __pattern = r'^unmatchable$' __config = [("use_premium", "bool", "Use premium account if available", True), ("fallback", "bool", "Fallback to free download if premium fails", True)] __description = """Simple hoster plugin""" __license = "GPLv3" __authors = [("Walter Purcaro", "*****@*****.**")] """ Info patterns should be defined by each hoster: INFO_PATTERN: (optional) Name and Size of the file example: INFO_PATTERN = r'(?P<N>file_name) (?P<S>file_size) (?P<U>size_unit)' or NAME_PATTERN: (optional) Name that will be set for the file example: NAME_PATTERN = r'(?P<N>file_name)' SIZE_PATTERN: (optional) Size that will be checked for the file example: SIZE_PATTERN = r'(?P<S>file_size) (?P<U>size_unit)' HASHSUM_PATTERN: (optional) Hash code and type of the file example: HASHSUM_PATTERN = r'(?P<H>hash_code) (?P<T>MD5)' OFFLINE_PATTERN: (optional) Check if the page is unreachable example: OFFLINE_PATTERN = r'File (deleted|not found)' TEMP_OFFLINE_PATTERN: (optional) Check if the page is temporarily unreachable example: TEMP_OFFLINE_PATTERN = r'Server (maintenance|maintainance)' Error handling patterns are all optional: WAIT_PATTERN: (optional) Detect waiting time example: WAIT_PATTERN = r'' PREMIUM_ONLY_PATTERN: (optional) Check if the file can be downloaded only with a premium account example: PREMIUM_ONLY_PATTERN = r'Premium account required' ERROR_PATTERN: (optional) Detect any error preventing download example: ERROR_PATTERN = r'' Instead overriding handle_free and handle_premium methods you can define the following patterns for direct download: LINK_FREE_PATTERN: (optional) group(1) should be the direct link for free download example: LINK_FREE_PATTERN = r'<div class="link"><a href="(.+?)"' LINK_PREMIUM_PATTERN: (optional) group(1) should be the direct link for premium download example: LINK_PREMIUM_PATTERN = r'<div class="link"><a href="(.+?)"' """ NAME_REPLACEMENTS = [("&#?\w+;", fixup)] SIZE_REPLACEMENTS = [] URL_REPLACEMENTS = [] TEXT_ENCODING = False #: Set to True or encoding name if encoding value in http header is not correct COOKIES = True #: or False or list of tuples [(domain, name, value)] CHECK_TRAFFIC = False #: Set to True to force checking traffic left for premium account DIRECT_LINK = None #: Set to True to looking for direct link (as defined in handle_direct method), set to None to do it if self.account is True else False MULTI_HOSTER = False #: Set to True to leech other hoster link (as defined in handle_multi method) LOGIN_ACCOUNT = False #: Set to True to require account login DISPOSITION = True #: Set to True to use any content-disposition value in http header as file name directLink = getFileURL #@TODO: Remove in 0.4.10 @classmethod def parseInfos( cls, urls): #@TODO: Built-in in 0.4.10 core (remove from plugins) for url in urls: url = replace_patterns(url, cls.URL_REPLACEMENTS) yield cls.getInfo(url) @classmethod def apiInfo(cls, url="", get={}, post={}): url = urllib.unquote(url) url_p = urlparse.urlparse(url) return { 'name': (url_p.path.split('/')[-1] or url_p.query.split('=', 1)[::-1][0].split('&', 1)[0] or url_p.netloc.split('.', 1)[0]), 'size': 0, 'status': 3 if url else 8, 'url': url } @classmethod def getInfo(cls, url="", html=""): info = cls.apiInfo(url) online = info['status'] == 2 try: info['pattern'] = re.match( cls.__pattern, url).groupdict() #: pattern groups will be saved here except Exception: info['pattern'] = {} if not html and not online: if not url: info['error'] = "missing url" info['status'] = 1 elif info['status'] is 3 and not getFileURL(None, url): try: html = getURL(url, cookies=cls.COOKIES, decode=not cls.TEXT_ENCODING) if isinstance(cls.TEXT_ENCODING, basestring): html = unicode(html, cls.TEXT_ENCODING) except BadHeader, e: info['error'] = "%d: %s" % (e.code, e.content) if e.code is 404: info['status'] = 1 elif e.code is 503: info['status'] = 6 if html: if hasattr(cls, "OFFLINE_PATTERN") and re.search( cls.OFFLINE_PATTERN, html): info['status'] = 1 elif hasattr(cls, "TEMP_OFFLINE_PATTERN") and re.search( cls.TEMP_OFFLINE_PATTERN, html): info['status'] = 6 else: for pattern in ("INFO_PATTERN", "NAME_PATTERN", "SIZE_PATTERN", "HASHSUM_PATTERN"): try: attr = getattr(cls, pattern) pdict = re.search(attr, html).groupdict() if all(True for k in pdict if k not in info['pattern']): info['pattern'].update(pdict) except AttributeError: continue else: online = True if online: info['status'] = 2 if 'N' in info['pattern']: info['name'] = replace_patterns( urllib.unquote(info['pattern']['N'].strip()), cls.NAME_REPLACEMENTS) if 'S' in info['pattern']: size = replace_patterns( info['pattern']['S'] + info['pattern']['U'] if 'U' in info['pattern'] else info['pattern']['S'], cls.SIZE_REPLACEMENTS) info['size'] = parseFileSize(size) elif isinstance(info['size'], basestring): unit = info['units'] if 'units' in info else None info['size'] = parseFileSize(info['size'], unit) if 'H' in info['pattern']: hashtype = info['pattern']['T'] if 'T' in info[ 'pattern'] else "hash" info[hashtype] = info['pattern']['H'] if not info['pattern']: info.pop('pattern', None) return info
def parseTraffic(self, value, unit=None): #: return bytes if not unit and not isinstance(value, basestring): unit = "KB" return parseFileSize(value, unit)