diff options
Diffstat (limited to 'module')
24 files changed, 564 insertions, 220 deletions
diff --git a/module/plugins/accounts/CzshareCom.py b/module/plugins/accounts/CzshareCom.py index e68248aa8..7b1a8edc5 100644 --- a/module/plugins/accounts/CzshareCom.py +++ b/module/plugins/accounts/CzshareCom.py @@ -17,42 +17,41 @@ @author: zoidberg """ -from module.plugins.Account import Account from time import mktime, strptime -from string import replace import re +from module.plugins.Account import Account + + class CzshareCom(Account): __name__ = "CzshareCom" - __version__ = "0.11" + __version__ = "0.13" __type__ = "account" __description__ = """czshare.com account plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") - + __author_name__ = ("zoidberg", "stickell") + __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") + CREDIT_LEFT_PATTERN = r'<tr class="active">\s*<td>([0-9 ,]+) (KiB|MiB|GiB)</td>\s*<td>([^<]*)</td>\s*</tr>' def loadAccountInfo(self, user, req): - self.relogin(user) html = req.load("http://czshare.com/prehled_kreditu/") - + found = re.search(self.CREDIT_LEFT_PATTERN, html) - if found is None: - credits, validuntil = 0, 0 + if not found: + return {"validuntil": 0, "trafficleft": 0} else: - credits = float(found.group(1).replace(' ', '').replace(',','.')) - credits = credits * 1024**{'KiB' : 0, 'MiB' : 1, 'GiB' : 2}[found.group(2)] + credits = float(found.group(1).replace(' ', '').replace(',', '.')) + credits = credits * 1024 ** {'KiB': 0, 'MiB': 1, 'GiB': 2}[found.group(2)] validuntil = mktime(strptime(found.group(3), '%d.%m.%y %H:%M')) - - return {"validuntil": validuntil, "trafficleft": credits} - + return {"validuntil": validuntil, "trafficleft": credits} + def login(self, user, data, req): - + html = req.load('https://czshare.com/index.php', post={ - "Prihlasit": "Prihlasit", - "login-password": data["password"], - "login-name": user - }) - + "Prihlasit": "Prihlasit", + "login-password": data["password"], + "login-name": user + }) + if '<div class="login' in html: self.wrongPassword() diff --git a/module/plugins/accounts/FastshareCz.py b/module/plugins/accounts/FastshareCz.py index 333ee3761..69bbb0827 100644 --- a/module/plugins/accounts/FastshareCz.py +++ b/module/plugins/accounts/FastshareCz.py @@ -21,32 +21,34 @@ import re from module.plugins.Account import Account from module.utils import parseFileSize + class FastshareCz(Account): __name__ = "FastshareCz" - __version__ = "0.01" + __version__ = "0.02" __type__ = "account" __description__ = """fastshare.cz account plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") - + __author_name__ = ("zoidberg", "stickell") + __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") + def loadAccountInfo(self, user, req): - html = req.load("http://www.fastshare.cz/user", decode = True) - - found = re.search(r'Kredit: </td><td>(.+?) ', html) + html = req.load("http://www.fastshare.cz/user", decode=True) + + found = re.search(r'(?:Kredit|Credit)\s*: </td><td>(.+?) ', html) if found: - trafficleft = parseFileSize(found.group(1)) / 1024 + trafficleft = parseFileSize(found.group(1)) / 1024 premium = True if trafficleft else False else: trafficleft = None - premium = False + premium = False return {"validuntil": -1, "trafficleft": trafficleft, "premium": premium} - + def login(self, user, data, req): - html = req.load('http://www.fastshare.cz/sql.php', post = { + req.load('http://www.fastshare.cz/login') # Do not remove or it will not login + html = req.load('http://www.fastshare.cz/sql.php', post={ "heslo": data['password'], "login": user - }, decode = True) - + }, decode=True) + if u'>Špatné uživatelské jméno nebo heslo.<' in html: self.wrongPassword()
\ No newline at end of file diff --git a/module/plugins/accounts/FilefactoryCom.py b/module/plugins/accounts/FilefactoryCom.py index 356c5d22a..8e163e2f6 100644 --- a/module/plugins/accounts/FilefactoryCom.py +++ b/module/plugins/accounts/FilefactoryCom.py @@ -23,13 +23,13 @@ from time import mktime, strptime class FilefactoryCom(Account): __name__ = "FilefactoryCom" - __version__ = "0.12" + __version__ = "0.13" __type__ = "account" __description__ = """filefactory.com account plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") + __author_name__ = ("zoidberg", "stickell") + __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") - ACCOUNT_INFO_PATTERN = r'<a href="/premium/">.*?datetime="(.*?)"' + ACCOUNT_INFO_PATTERN = r'<time datetime="([\d-]+)">' def loadAccountInfo(self, user, req): html = req.load("http://www.filefactory.com/member/") @@ -37,7 +37,7 @@ class FilefactoryCom(Account): found = re.search(self.ACCOUNT_INFO_PATTERN, html) if found: premium = True - validuntil = mktime(strptime(re.sub(r"(\d)[a-z]{2} ", r"\1 ", found.group(1)),"%d %B, %Y")) + validuntil = mktime(strptime(found.group(1),"%Y-%m-%d")) else: premium = False validuntil = -1 diff --git a/module/plugins/crypter/Movie2kTo.py b/module/plugins/crypter/Movie2kTo.py index f2c5ece55..097cb702e 100644 --- a/module/plugins/crypter/Movie2kTo.py +++ b/module/plugins/crypter/Movie2kTo.py @@ -9,7 +9,7 @@ class Movie2kTo(Crypter): __name__ = 'Movie2kTo' __type__ = 'container' __pattern__ = r'http://(?:www\.)?movie2k\.to/(.*)\.html' - __version__ = '0.4' + __version__ = '0.5' __config__ = [('accepted_hosters', 'str', 'List of accepted hosters', 'Xvidstage, Putlocker, '), ('dir_quality', 'bool', 'Show the quality of the footage in the folder name', 'True'), ('whole_season', 'bool', 'Download whole season', 'False'), @@ -132,12 +132,19 @@ class Movie2kTo(Crypter): self.html = self.load('%s/tvshows-%s-%s.html' % (self.BASE_URL, h_id, self.name)) else: self.logDebug('This is already the right ID') - try: - url = re.search(r'<a target="_blank" href="(http://[^"]*?)"', self.html).group(1) - self.logDebug('id: %s, %s: %s' % (h_id, hoster, url)) - links.append(url) - except: - self.logDebug('Failed to find the URL') + # The iframe tag must continue with a width. There where + # two iframes in the site and I try to make sure that it + # matches the right one. This is not (yet) nessesary + # because the right iframe happens to be the first iframe. + for pattern in (r'<a target="_blank" href="(http://[^"]*?)"', r'<iframe src="(http://[^"]*?)" width'): + try: + url = re.search(pattern, self.html).group(1) + except: + self.logDebug('Failed to find the URL (pattern %s)' % pattern) + else: + self.logDebug('id: %s, %s: %s' % (h_id, hoster, url)) + links.append(url) + break else: self.logDebug('Not accepted: %s, ID: %s%s' % (hoster, h_id, q_s)) # self.logDebug(links) diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py index 5e1ea347c..e1cd30475 100644 --- a/module/plugins/crypter/NCryptIn.py +++ b/module/plugins/crypter/NCryptIn.py @@ -11,7 +11,7 @@ class NCryptIn(Crypter): __name__ = "NCryptIn"
__type__ = "crypter"
__pattern__ = r"http://(?:www\.)?ncrypt.in/folder-([^/\?]+)"
- __version__ = "1.21"
+ __version__ = "1.22"
__description__ = """NCrypt.in Crypter Plugin"""
__author_name__ = ("fragonib")
__author_mail__ = ("fragonib[AT]yahoo[DOT]es")
diff --git a/module/plugins/crypter/YoutubeBatch.py b/module/plugins/crypter/YoutubeBatch.py index 567191bb9..72b72aab7 100644 --- a/module/plugins/crypter/YoutubeBatch.py +++ b/module/plugins/crypter/YoutubeBatch.py @@ -11,8 +11,8 @@ API_KEY = "AIzaSyCKnWLNlkX-L4oD1aEzqqhRw1zczeD6_k0" class YoutubeBatch(Crypter): __name__ = "YoutubeBatch" __type__ = "container" - __pattern__ = r"http://(?:[^/]*?)youtube\.com/((?:view_play_list|playlist|.*?feature=PlayList).*?[\?&](?:list|p)=)([a-zA-Z0-9-_]+)" - __version__ = "0.92" + __pattern__ = r"https?://(?:[^/]*?)youtube\.com/(?:(?:view_play_list|playlist|.*?feature=PlayList).*?[?&](?:list|p)=)([a-zA-Z0-9-_]+)" + __version__ = "0.93" __description__ = """Youtube.com Channel Download Plugin""" __author_name__ = ("RaNaN", "Spoob", "zoidberg", "roland") __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org", "zoidberg@mujmail.cz", "roland@enkore.de") @@ -35,7 +35,7 @@ class YoutubeBatch(Crypter): def decrypt(self, pyfile): match_id = re.match(self.__pattern__, self.pyfile.url) new_links = [] - playlist_id = match_id.group(2) + playlist_id = match_id.group(1) new_links.extend(self.get_videos(playlist_id)) diff --git a/module/plugins/hooks/Captcha9kw.py b/module/plugins/hooks/Captcha9kw.py index a01ce9576..bb2b8c862 100755 --- a/module/plugins/hooks/Captcha9kw.py +++ b/module/plugins/hooks/Captcha9kw.py @@ -30,17 +30,22 @@ from module.plugins.Hook import Hook class Captcha9kw(Hook):
__name__ = "Captcha9kw"
- __version__ = "0.03"
+ __version__ = "0.04"
__description__ = """send captchas to 9kw.eu"""
__config__ = [("activated", "bool", "Activated", True),
("force", "bool", "Force CT even if client is connected", True),
+ ("https", "bool", "Enable HTTPS", "False"),
+ ("confirm", "bool", "Confirm Captcha", "False"),
+ ("captchaperhour", "int", "Captcha per hour", "9999"),
+ ("prio", "int", "Prio (1-10)", "0"),
("passkey", "password", "API key", ""),]
__author_name__ = ("RaNaN")
__author_mail__ = ("RaNaN@pyload.org")
- API_URL = "http://www.9kw.eu/index.cgi"
+ API_URL = "://www.9kw.eu/index.cgi"
def setup(self):
+ self.API_URL = "https"+self.API_URL if self.getConfig("https") else "http"+self.API_URL
self.info = {}
def getCredits(self):
@@ -68,6 +73,10 @@ class Captcha9kw(Hook): response = getURL(self.API_URL, post = {
"apikey": self.getConfig("passkey"),
+ "prio": self.getConfig("prio"),
+ "confirm": self.getConfig("confirm"),
+ "captchaperhour": self.getConfig("captchaperhour"),
+ "maxtimeout": "220",
"pyload": "1",
"source": "pyload",
"base64": "1",
@@ -78,7 +87,7 @@ class Captcha9kw(Hook): if response.isdigit():
self.logInfo(_("NewCaptchaID from upload: %s : %s" % (response,task.captchaFile)))
- for i in range(1, 200, 2):
+ for i in range(1, 220, 1):
response2 = getURL(self.API_URL, get = { "apikey": self.getConfig("passkey"), "id": response,"pyload": "1","source": "pyload", "action": "usercaptchacorrectdata" })
if(response2 != ""):
diff --git a/module/plugins/hooks/DeleteFinished.py b/module/plugins/hooks/DeleteFinished.py new file mode 100644 index 000000000..01cb1b8e1 --- /dev/null +++ b/module/plugins/hooks/DeleteFinished.py @@ -0,0 +1,93 @@ + # -*- coding: utf-8 -*- + +""" + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + @author: Walter Purcaro +""" + +from module.database import style +from module.plugins.Hook import Hook + + +class DeleteFinished(Hook): + __name__ = "DeleteFinished" + __version__ = "1.02" + __description__ = "Automatically delete finished packages from queue" + __config__ = [ + ("activated", "bool", "Activated", "False"), + ("interval", "int", "Delete every (hours)", "72") + ] + __author_name__ = ("Walter Purcaro") + __author_mail__ = ("vuolter@gmail.com") + + ## overwritten methods ## + def periodical(self): + # self.logDebug("self.periodical") + if not self.info["sleep"]: + self.logInfo("self.deleteFinished") + self.deleteFinished() + self.info["sleep"] = True + self.addEvent("packageFinished", self.wakeup) + + def pluginConfigChanged(self, plugin, name, value): + # self.logDebug("self.pluginConfigChanged") + if name == "interval" and value != self.interval: + self.interval = value + self.initPeriodical() + + def unload(self): + # self.logDebug("self.unload") + self.removeEvent("packageFinished", self.wakeup) + + def coreReady(self): + # self.logDebug("self.coreReady") + self.info = {"sleep": True} + interval = self.getConfig("interval") * 3600 + self.pluginConfigChanged("DeleteFinished", "interval", interval) + self.addEvent("packageFinished", self.wakeup) + + ## own methods ## + @style.queue + def deleteFinished(self): + self.c.execute("DELETE FROM packages WHERE NOT EXISTS(SELECT 1 FROM links WHERE package=packages.id AND status NOT IN (0,4))") + self.c.execute("DELETE FROM links WHERE NOT EXISTS(SELECT 1 FROM packages WHERE id=links.package)") + + def wakeup(self, pypack): + # self.logDebug("self.wakeup") + self.removeEvent("packageFinished", self.wakeup) + self.info["sleep"] = False + + ## event managing ## + def addEvent(self, event, handler): + if event in self.manager.events: + if handler not in self.manager.events[event]: + self.manager.events[event].append(handler) + # self.logDebug("self.addEvent: " + event + ": added handler") + else: + # self.logDebug("self.addEvent: " + event + ": NOT added handler") + return False + else: + self.manager.events[event] = [handler] + # self.logDebug("self.addEvent: " + event + ": added event and handler") + return True + + def removeEvent(self, event, handler): + if event in self.manager.events and handler in self.manager.events[event]: + self.manager.events[event].remove(handler) + # self.logDebug("self.removeEvent: " + event + ": removed handler") + return True + else: + # self.logDebug("self.removeEvent: " + event + ": NOT removed handler") + return False diff --git a/module/plugins/hooks/LinkdecrypterCom.py b/module/plugins/hooks/LinkdecrypterCom.py index d3d6bce68..c117cafb9 100644 --- a/module/plugins/hooks/LinkdecrypterCom.py +++ b/module/plugins/hooks/LinkdecrypterCom.py @@ -24,9 +24,9 @@ from module.utils import remove_chars class LinkdecrypterCom(Hook): __name__ = "LinkdecrypterCom" - __version__ = "0.17" + __version__ = "0.18" __description__ = """linkdecrypter.com - regexp loader""" - __config__ = [ ("activated", "bool", "Activated" , "True") ] + __config__ = [ ("activated", "bool", "Activated" , "False") ] __author_name__ = ("zoidberg") def coreReady(self): diff --git a/module/plugins/hooks/RestartFailed.py b/module/plugins/hooks/RestartFailed.py new file mode 100644 index 000000000..7ee53deb9 --- /dev/null +++ b/module/plugins/hooks/RestartFailed.py @@ -0,0 +1,124 @@ + # -*- coding: utf-8 -*- + +""" + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + @author: Walter Purcaro +""" + +from module.plugins.Hook import Hook +from time import time + + +class RestartFailed(Hook): + __name__ = "RestartFailed" + __version__ = "1.5" + __description__ = "Automatically restart failed/aborted downloads" + __config__ = [ + ("activated", "bool", "Activated", "True"), + ("dlFail", "bool", "Restart when download fail", "True"), + ("dlFail_n", "int", "Only when failed downloads are at least", "5"), + ("dlFail_i", "int", "Only when elapsed time since last restart is (min)", "10"), + ("dlPrcs", "bool", "Restart after all downloads are processed", "True"), + ("recnt", "bool", "Restart after reconnecting", "True"), + ("rsLoad", "bool", "Restart on plugin activation", "False") + ] + __author_name__ = ("Walter Purcaro") + __author_mail__ = ("vuolter@gmail.com") + + def restart(self, arg=None): + # self.logDebug("self.restart") + self.info["timerflag"] = False + self.info["dlfailed"] = 0 + self.core.api.restartFailed() + self.logDebug("self.restart: self.core.api.restartFailed") + self.info["lastrstime"] = time() + + def periodical(self): + # self.logDebug("self.periodical") + if self.info["timerflag"]: + self.restart() + + def checkInterval(self, arg=None): + # self.logDebug("self.checkInterval") + now = time() + lastrstime = self.info["lastrstime"] + interval = self.getConfig("dlFail_i") * 60 + if now < lastrstime + interval: + self.info["timerflag"] = True + else: + self.restart() + + def checkFailed(self, pyfile): + # self.logDebug("self.checkFailed") + self.info["dlfailed"] += 1 + curr = self.info["dlfailed"] + max = self.getConfig("dlFail_n") + if curr >= max: + self.checkInterval() + + def addEvent(self, event, handler): + if event in self.manager.events: + if handler not in self.manager.events[event]: + self.manager.events[event].append(handler) + # self.logDebug("self.addEvent: " + event + ": added handler") + else: + # self.logDebug("self.addEvent: " + event + ": NOT added handler") + return False + else: + self.manager.events[event] = [handler] + # self.logDebug("self.addEvent: " + event + ": added event and handler") + return True + + def removeEvent(self, event, handler): + if event in self.manager.events and handler in self.manager.events[event]: + self.manager.events[event].remove(handler) + # self.logDebug("self.removeEvent: " + event + ": removed handler") + return True + else: + # self.logDebug("self.removeEvent: " + event + ": NOT removed handler") + return False + + def configEvents(self, plugin=None, name=None, value=None): + # self.logDebug("self.configEvents") + self.interval = self.getConfig("dlFail_i") * 60 + dlFail = self.getConfig("dlFail") + dlPrcs = self.getConfig("dlPrcs") + recnt = self.getConfig("recnt") + if dlPrcs: + self.addEvent("allDownloadsProcessed", self.checkInterval) + else: + self.removeEvent("allDownloadsProcessed", self.checkInterval) + if not dlFail: + self.info["timerflag"] = False + if recnt: + self.addEvent("afterReconnecting", self.restart) + else: + self.removeEvent("afterReconnecting", self.restart) + + def unload(self): + # self.logDebug("self.unload") + self.removeEvent("pluginConfigChanged", self.configEvents) + self.removeEvent("downloadFailed", self.checkFailed) + self.removeEvent("allDownloadsProcessed", self.checkInterval) + self.removeEvent("afterReconnecting", self.restart) + + def coreReady(self): + # self.logDebug("self.coreReady") + self.info = {"dlfailed": 0, "lastrstime": 0, "timerflag": False} + if self.getConfig("rsLoad"): + self.restart() + self.addEvent("downloadFailed", self.checkFailed) + self.addEvent("pluginConfigChanged", self.configEvents) + self.configEvents() diff --git a/module/plugins/hooks/SkipRev.py b/module/plugins/hooks/SkipRev.py new file mode 100644 index 000000000..561329122 --- /dev/null +++ b/module/plugins/hooks/SkipRev.py @@ -0,0 +1,46 @@ + # -*- coding: utf-8 -*- + +""" + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + @author: Walter Purcaro +""" + +from module.plugins.Hook import Hook +from os.path import basename +from re import search + + +class SkipRev(Hook): + __name__ = "SkipRev" + __version__ = "0.07" + __description__ = "Skip download when filename has rev extension" + __config__ = [ + ("activated", "bool", "Activated", "False"), + ("number", "int", "Do not skip until rev part", "1") + ] + __author_name__ = ("Walter Purcaro") + __author_mail__ = ("vuolter@gmail.com") + + def downloadPreparing(self, pyfile): + # self.logDebug("self.downloadPreparing") + name = basename(pyfile.name) + if not name.endswith(".rev"): + return + number = self.getConfig("number") + part = search(r'\.part(\d+)\.rev$', name) + if not part or int(part.group(1)) <= number: + return + self.logInfo("Skipping " + name) + pyfile.setStatus("skipped") diff --git a/module/plugins/hoster/CloudzerNet.py b/module/plugins/hoster/CloudzerNet.py index 08a54d509..7608b193d 100644 --- a/module/plugins/hoster/CloudzerNet.py +++ b/module/plugins/hoster/CloudzerNet.py @@ -20,7 +20,7 @@ class CloudzerNet(SimpleHoster): __name__ = "CloudzerNet" __type__ = "hoster" __pattern__ = r"http://(www\.)?(cloudzer\.net/file/|clz\.to/(file/)?)(?P<ID>\w+).*" - __version__ = "0.01" + __version__ = "0.02" __description__ = """Cloudzer.net hoster plugin""" __author_name__ = ("gs", "z00nx") __author_mail__ = ("I-_-I-_-I@web.de", "z00nx0@gmail.com") @@ -56,7 +56,7 @@ class CloudzerNet(SimpleHoster): self.retry() elif "Sie haben die max" in response["err"] or "You have reached the max" in response["err"]: self.logDebug("Download limit reached, waiting an hour") - self.setWait(3600) + self.setWait(3600, True) self.wait() if "type" in response: if response["type"] == "download": diff --git a/module/plugins/hoster/CzshareCom.py b/module/plugins/hoster/CzshareCom.py index a4a811e82..347427586 100644 --- a/module/plugins/hoster/CzshareCom.py +++ b/module/plugins/hoster/CzshareCom.py @@ -16,6 +16,9 @@ @author: zoidberg """ +# Test links (random.bin): +# http://czshare.com/5278880/random.bin + import re from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, PluginParseError from module.utils import parseFileSize @@ -24,7 +27,7 @@ class CzshareCom(SimpleHoster): __name__ = "CzshareCom" __type__ = "hoster" __pattern__ = r"http://(\w*\.)*czshare\.(com|cz)/(\d+/|download.php\?).*" - __version__ = "0.92" + __version__ = "0.93" __description__ = """CZshare.com""" __author_name__ = ("zoidberg") @@ -80,7 +83,7 @@ class CzshareCom(SimpleHoster): self.resetAccount() # download the file, destination is determined by pyLoad - self.download("http://czshare.com/profi_down.php", cookies=True, post=inputs) + self.download("http://czshare.com/profi_down.php", post=inputs, disposition=True) self.checkDownloadedFile() def handleFree(self): diff --git a/module/plugins/hoster/EgoFilesCom.py b/module/plugins/hoster/EgoFilesCom.py index 4e78a5b9a..7e6673210 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.12"
+ __version__ = "0.13"
__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+<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>[^\t]+)\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>'
diff --git a/module/plugins/hoster/FastshareCz.py b/module/plugins/hoster/FastshareCz.py index cc0b18c96..1dbf9fe8f 100644 --- a/module/plugins/hoster/FastshareCz.py +++ b/module/plugins/hoster/FastshareCz.py @@ -16,27 +16,39 @@ @author: zoidberg """ +# Test links (random.bin): +# http://www.fastshare.cz/2141189/random.bin + import re -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns + class FastshareCz(SimpleHoster): __name__ = "FastshareCz" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)?fastshare.cz/\d+/.+" - __version__ = "0.14" + __version__ = "0.15" __description__ = """FastShare.cz""" - __author_name__ = ("zoidberg") + __author_name__ = ("zoidberg", "stickell") - FILE_NAME_PATTERN = r'<h[23]><b><span style=color:black;>(?P<N>[^<]+)</b></h[23]>' - FILE_SIZE_PATTERN = r'<tr><td>Velikost: </td><td style=font-weight:bold>(?P<S>[^<]+)</td></tr>' + FILE_INFO_PATTERN = r'<h1 class="dwp">(?P<N>[^<]+)</h1>\s*<div class="fileinfo">\s*(?:Velikost|Size)\s*: (?P<S>[^,]+),' FILE_OFFLINE_PATTERN = ur'<td align=center>Tento soubor byl smazán' - SH_COOKIES = [("fastshare.cz","lang","cs")] FILE_URL_REPLACEMENTS = [('#.*','')] FREE_URL_PATTERN = ur'<form method=post action=(/free/.*?)><b>Stáhnout FREE.*?<img src="([^"]*)">' PREMIUM_URL_PATTERN = r'(http://data\d+\.fastshare\.cz/download\.php\?id=\d+\&[^\s\"\'<>]+)' NOT_ENOUGH_CREDIC_PATTERN = "Nem.te dostate.n. kredit pro sta.en. tohoto souboru" + def process(self, pyfile): + pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS) + self.req.setOption("timeout", 120) + if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): + self.handlePremium() + else: + self.html = self.load(pyfile.url, decode = not self.SH_BROKEN_ENCODING, cookies = self.SH_COOKIES) + self.getFileInfo() + self.handleFree() + def handleFree(self): if u">100% FREE slotů je plných.<" in self.html: self.setWait(60, False) @@ -60,13 +72,20 @@ class FastshareCz(SimpleHoster): self.retry(6, "Paralell download") def handlePremium(self): - if self.NOT_ENOUGH_CREDIC_PATTERN in self.html: - self.logWarning('Not enough traffic left') - self.resetAccount() + header = self.load(self.pyfile.url, just_header=True) + if 'location' in header: + url = header['location'] + else: + self.html = self.load(self.pyfile.url) + self.getFileInfo() + if self.NOT_ENOUGH_CREDIC_PATTERN in self.html: + self.logWarning('Not enough traffic left') + self.resetAccount() + + found = re.search(self.PREMIUM_URL_PATTERN, self.html) + if not found: self.parseError("Premium URL") + url = found.group(1) - found = re.search(self.PREMIUM_URL_PATTERN, self.html) - if not found: self.parseError("Premium URL") - url = found.group(1) self.logDebug("PREMIUM URL: %s" % url) self.download(url) diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index aebf0f38d..fdde1f9d7 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -57,12 +57,19 @@ class FilefactoryCom(SimpleHoster): __name__ = "FilefactoryCom" __type__ = "hoster" __pattern__ = r"https?://(?:www\.)?filefactory\.com/file/(?P<id>[a-zA-Z0-9]+)" - __version__ = "0.39" + __version__ = "0.41" __description__ = """Filefactory.Com File Download Hoster""" __author_name__ = ("stickell") __author_mail__ = ("l.stickell@yahoo.it") + DIRECT_LINK_PATTERN = r'<section id="downloadLink">\s*<p class="textAlignCenter">\s*<a href="([^"]+)">[^<]+</a>\s*</p>\s*</section>' + def process(self, pyfile): + if not re.match(self.__pattern__ + r'/n/.+', pyfile.url): # Not in standard format + header = self.load(pyfile.url, just_header=True) + if 'location' in header: + self.pyfile.url = 'http://www.filefactory.com' + header['location'] + if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): self.handlePremium() else: @@ -115,7 +122,12 @@ class FilefactoryCom(SimpleHoster): elif 'content-disposition' in header: url = self.pyfile.url else: - self.parseError('Unable to detect premium direct link') + html = self.load(self.pyfile.url) + found = re.search(self.DIRECT_LINK_PATTERN, html) + if found: + url = found.group(1) + else: + self.parseError('Unable to detect premium direct link') self.logDebug('DIRECT PREMIUM LINK: ' + url) self.download(url, disposition=True) diff --git a/module/plugins/hoster/Premium4Me.py b/module/plugins/hoster/Premium4Me.py index 2679916e9..08479b59c 100644 --- a/module/plugins/hoster/Premium4Me.py +++ b/module/plugins/hoster/Premium4Me.py @@ -2,20 +2,22 @@ # -*- coding: utf-8 -*-
from urllib import quote
-from module.plugins.Hoster import Hoster
-from module.utils import fs_encode
from os.path import exists
from os import remove
+from module.plugins.Hoster import Hoster
+from module.utils import fs_encode
+
+
class Premium4Me(Hoster):
__name__ = "Premium4Me"
- __version__ = "0.04"
+ __version__ = "0.06"
__type__ = "hoster"
__pattern__ = r"http://premium4.me/.*"
__description__ = """premium4.me hoster plugin"""
- __author_name__ = ("RaNaN", "zoidberg")
- __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz")
+ __author_name__ = ("RaNaN", "zoidberg", "stickell")
+ __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it")
def setup(self):
self.resumeDownload = True
@@ -29,33 +31,40 @@ class Premium4Me(Hoster): self.logDebug("premium4.me: Old URL: %s" % pyfile.url)
tra = self.getTraffic()
-
+
#raise timeout to 2min
self.req.setOption("timeout", 120)
-
- self.download("http://premium4.me/api/getfile.php?authcode=%s&link=%s" % (self.account.authcode, quote(pyfile.url, "")), disposition=True)
-
- err = ''
+
+ self.download(
+ "http://premium4.me/api/getfile.php?authcode=%s&link=%s" % (self.account.authcode, quote(pyfile.url, "")),
+ disposition=True)
+
+ check = self.checkDownload({"nopremium": "No premium account available"})
+
+ if check == "nopremium":
+ self.retry(60, 300, 'No premium account available')
+
+ err = ''
if self.req.http.code == '420':
# Custom error code send - fail
lastDownload = fs_encode(self.lastDownload)
-
- if exists(lastDownload):
+
+ if exists(lastDownload):
f = open(lastDownload, "rb")
err = f.read(256).strip()
f.close()
remove(lastDownload)
else:
err = 'File does not exist'
-
+
trb = self.getTraffic()
- self.logInfo("Filesize: %d, Traffic used %d, traffic left %d" % (pyfile.size, tra-trb, trb))
-
+ self.logInfo("Filesize: %d, Traffic used %d, traffic left %d" % (pyfile.size, tra - trb, trb))
+
if err: self.fail(err)
-
+
def getTraffic(self):
try:
- traffic = int(self.load ("http://premium4.me/api/traffic.php?authcode=%s" % self.account.authcode))
+ traffic = int(self.load("http://premium4.me/api/traffic.php?authcode=%s" % self.account.authcode))
except:
- traffic = 0
+ traffic = 0
return traffic
diff --git a/module/plugins/hoster/PutlockerCom.py b/module/plugins/hoster/PutlockerCom.py index 9eff0dc2b..b2016472d 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.24" + __version__ = "0.25" __description__ = """Putlocker.Com""" __author_name__ = ("jeix", "stickell") __author_mail__ = ("l.stickell@yahoo.it") @@ -37,6 +37,8 @@ class PutlockerCom(SimpleHoster): FILE_INFO_PATTERN = r'site-content">\s*<h1>(?P<N>.+)<strong>\( (?P<S>[^)]+) \)</strong></h1>' def handleFree(self): + self.pyfile.url = re.sub(r'http://putlocker\.com', r'http://www.putlocker.com', self.pyfile.url) + self.html = self.load(self.pyfile.url, decode=True) link = self._getLink() diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py index 1cc3ff8ae..d2ca77e0f 100644 --- a/module/plugins/hoster/RapidgatorNet.py +++ b/module/plugins/hoster/RapidgatorNet.py @@ -29,9 +29,9 @@ class RapidgatorNet(SimpleHoster): __name__ = "RapidgatorNet" __type__ = "hoster" __pattern__ = r"http://(?:www\.)?(rapidgator.net)/file/(\w+)" - __version__ = "0.16" + __version__ = "0.17" __description__ = """rapidgator.net""" - __author_name__ = ("zoidberg","chrox") + __author_name__ = ("zoidberg", "chrox", "stickell") API_URL = 'http://rapidgator.net/api/file' @@ -39,7 +39,7 @@ class RapidgatorNet(SimpleHoster): FILE_OFFLINE_PATTERN = r'<title>File not found</title>' JSVARS_PATTERN = r"\s+var\s*(startTimerUrl|getDownloadUrl|captchaUrl|fid|secs)\s*=\s*'?(.*?)'?;" - DOWNLOAD_LINK_PATTERN = r"location.href = '([^']+)';\s*}\s*return false;" + DOWNLOAD_LINK_PATTERN = r"return '(http[^']+)';\s*}\s*}\s*}\);" RECAPTCHA_KEY_PATTERN = r'"http://api.recaptcha.net/challenge?k=(.*?)"' ADSCAPTCHA_SRC_PATTERN = r'(http://api.adscaptcha.com/Get.aspx[^"\']*)' SOLVEMEDIA_PATTERN = r'http:\/\/api\.solvemedia\.com\/papi\/challenge\.script\?k=(.*?)"' diff --git a/module/plugins/hoster/RyushareCom.py b/module/plugins/hoster/RyushareCom.py index c2ff54e0c..7bfe4e8fe 100644 --- a/module/plugins/hoster/RyushareCom.py +++ b/module/plugins/hoster/RyushareCom.py @@ -7,7 +7,7 @@ class RyushareCom(XFileSharingPro): __name__ = "RyushareCom" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)*?ryushare.com/\w{11,}" - __version__ = "0.10" + __version__ = "0.11" __description__ = """ryushare.com hoster plugin""" __author_name__ = ("zoidberg", "stickell") __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") @@ -18,7 +18,9 @@ class RyushareCom(XFileSharingPro): DIRECT_LINK_PATTERN = r'<a href="([^"]+)">Click here to download</a>' def setup(self): - self.resumeDownload = self.multiDL = self.premium + self.resumeDownload = self.multiDL = True + if not self.premium: + self.limitDL = 2 # Up to 3 chunks allowed in free downloads. Unknown for premium self.chunkLimit = 3 diff --git a/module/plugins/hoster/UploadheroCom.py b/module/plugins/hoster/UploadheroCom.py index eb7b5fb23..a2348b9f9 100644 --- a/module/plugins/hoster/UploadheroCom.py +++ b/module/plugins/hoster/UploadheroCom.py @@ -16,14 +16,17 @@ @author: zoidberg """ +# Test link (random.bin): +# http://uploadhero.co/dl/wQBRAVSM + import re from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class UploadheroCom(SimpleHoster): __name__ = "UploadheroCom" __type__ = "hoster" - __pattern__ = r"http://(?:www\.)?uploadhero\.com/dl/\w+" - __version__ = "0.12" + __pattern__ = r"http://(?:www\.)?uploadhero\.com?/dl/\w+" + __version__ = "0.13" __description__ = """UploadHero.com plugin""" __author_name__ = ("mcmyst", "zoidberg") __author_mail__ = ("mcmyst@hotmail.fr", "zoidberg@mujmail.cz") @@ -81,4 +84,4 @@ class UploadheroCom(SimpleHoster): self.wait() self.retry() -getInfo = create_getInfo(UploadheroCom)
\ No newline at end of file +getInfo = create_getInfo(UploadheroCom) diff --git a/module/plugins/hoster/XvidstageCom.py b/module/plugins/hoster/XvidstageCom.py index 14079df43..4962c05af 100644 --- a/module/plugins/hoster/XvidstageCom.py +++ b/module/plugins/hoster/XvidstageCom.py @@ -1,105 +1,114 @@ # -*- coding: utf-8 -*- """ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU 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. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. - @author: 4Christopher + @author: 4Christopher """ -from module.plugins.Hoster import Hoster -from module.network.RequestFactory import getURL import re import HTMLParser +from module.plugins.Hoster import Hoster +from module.network.RequestFactory import getURL + + def setup(self): - self.wantReconnect = False - self.resumeDownload = True - self.multiDL = True + self.wantReconnect = False + self.resumeDownload = True + self.multiDL = True + def getInfo(urls): - result = [] - - for url in urls: - result.append(parseFileInfo(url, getInfoMode = True)) - yield result - -def parseFileInfo(url, getInfoMode = False): - html = getURL(url) - info = {"name" : url, "size" : 0, "status" : 3} - try: - info['name'] = re.search(r'(?:Filename|Dateiname):</b></td><td nowrap[^>]*?>(.*?)<', html).group(1) - info['size'] = re.search(r'(?:Size|Größe):</b></td><td>.*? <small>\((\d+?) bytes\)', html).group(1) - except: ## The file is offline - info['status'] = 1 - else: - info['status'] = 2 - - if getInfoMode: - return info['name'], info['size'], info['status'], url - else: - return info['name'], info['size'], info['status'], html + result = [] + + for url in urls: + result.append(parseFileInfo(url, getInfoMode=True)) + yield result + + +def parseFileInfo(url, getInfoMode=False): + html = getURL(url) + info = {"name": url, "size": 0, "status": 3} + try: + info['name'] = re.search(r'(?:Filename|Dateiname):</b></td><td nowrap[^>]*?>(.*?)<', html).group(1) + info['size'] = re.search(r'(?:Size|Größe):</b></td><td>.*? <small>\((\d+?) bytes\)', html).group(1) + except: ## The file is offline + info['status'] = 1 + else: + info['status'] = 2 + + if getInfoMode: + return info['name'], info['size'], info['status'], url + else: + return info['name'], info['size'], info['status'], html + class XvidstageCom(Hoster): - __name__ = 'XvidstageCom' - __version__ = '0.3' - __pattern__ = r'http://(?:www.)?xvidstage.com/(?P<id>[0-9A-Za-z]+)' - __type__ = 'hoster' - __description__ = """A Plugin that allows you to download files from http://xvidstage.com""" - __author_name__ = ('4Christopher') - __author_mail__ = ('4Christopher@gmx.de') - - - def process(self, pyfile): - pyfile.name, pyfile.size, pyfile.status, self.html = parseFileInfo(pyfile.url) - self.logDebug('Name: %s' % pyfile.name) - if pyfile.status == 1: ## offline - self.fail() - self.id = re.search(self.__pattern__, pyfile.url).group('id') - - wait_sec = int(re.search(r'countdown_str">.+?>(\d+?)<', self.html).group(1)) - self.setWait(wait_sec, reconnect=False) - self.logDebug('Waiting %d seconds before submitting the captcha' % wait_sec) - self.wait() - - rand = re.search(r'<input type="hidden" name="rand" value="(.*?)">', self.html).group(1) - self.logDebug('rand: %s, id: %s' % (rand, self.id)) - self.html = self.req.load(pyfile.url, post={'op': 'download2', 'id' : self.id, 'rand' : rand, 'code': self.get_captcha()}) - file_url = re.search(r'<a href="(?P<url>.*?)">(?P=url)</a>', self.html).group('url') - try: - hours_file_available = int(re.search(r'This direct link will be available for your IP next (?P<hours>\d+?) hours', self.html).group('hours')) - self.logDebug('You have %d hours to download this file with your current IP address.' % hours_file_available) - except: - self.logDebug('Failed') - self.logDebug('Download file: %s' % file_url) - self.download(file_url) - check = self.checkDownload({'empty': re.compile(r'^$')}) - - if check == 'empty': - self.logInfo('Downloaded File was empty') - # self.retry() - - def get_captcha(self): - ## <span style='position:absolute;padding-left:7px;padding-top:6px;'>1 … - cap_chars = {} - for pad_left, char in re.findall(r"position:absolute;padding-left:(\d+?)px;.*?;'>(.*?)<", self.html): - cap_chars[int(pad_left)] = char - - h = HTMLParser.HTMLParser() - ## Sorting after padding-left - captcha = '' - for pad_left in sorted(cap_chars): - captcha += h.unescape(cap_chars[pad_left]) - - self.logDebug('The captcha is: %s' % captcha) - return captcha + __name__ = 'XvidstageCom' + __version__ = '0.4' + __pattern__ = r'http://(?:www.)?xvidstage.com/(?P<id>[0-9A-Za-z]+)' + __type__ = 'hoster' + __description__ = """A Plugin that allows you to download files from http://xvidstage.com""" + __author_name__ = ('4Christopher') + __author_mail__ = ('4Christopher@gmx.de') + + + def process(self, pyfile): + pyfile.name, pyfile.size, pyfile.status, self.html = parseFileInfo(pyfile.url) + self.logDebug('Name: %s' % pyfile.name) + if pyfile.status == 1: ## offline + self.offline() + self.id = re.search(self.__pattern__, pyfile.url).group('id') + + wait_sec = int(re.search(r'countdown_str">.+?>(\d+?)<', self.html).group(1)) + self.setWait(wait_sec, reconnect=False) + self.logDebug('Waiting %d seconds before submitting the captcha' % wait_sec) + self.wait() + + rand = re.search(r'<input type="hidden" name="rand" value="(.*?)">', self.html).group(1) + self.logDebug('rand: %s, id: %s' % (rand, self.id)) + self.html = self.req.load(pyfile.url, + post={'op': 'download2', 'id': self.id, 'rand': rand, 'code': self.get_captcha()}) + file_url = re.search(r'<a href="(?P<url>.*?)">(?P=url)</a>', self.html).group('url') + try: + hours_file_available = int( + re.search(r'This direct link will be available for your IP next (?P<hours>\d+?) hours', + self.html).group('hours')) + self.logDebug( + 'You have %d hours to download this file with your current IP address.' % hours_file_available) + except: + self.logDebug('Failed') + self.logDebug('Download file: %s' % file_url) + self.download(file_url) + check = self.checkDownload({'empty': re.compile(r'^$')}) + + if check == 'empty': + self.logInfo('Downloaded File was empty') + # self.retry() + + def get_captcha(self): + ## <span style='position:absolute;padding-left:7px;padding-top:6px;'>1 … + cap_chars = {} + for pad_left, char in re.findall(r"position:absolute;padding-left:(\d+?)px;.*?;'>(.*?)<", self.html): + cap_chars[int(pad_left)] = char + + h = HTMLParser.HTMLParser() + ## Sorting after padding-left + captcha = '' + for pad_left in sorted(cap_chars): + captcha += h.unescape(cap_chars[pad_left]) + + self.logDebug('The captcha is: %s' % captcha) + return captcha diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py index 304cffd69..70db597cf 100644 --- a/module/plugins/hoster/YoutubeCom.py +++ b/module/plugins/hoster/YoutubeCom.py @@ -33,8 +33,8 @@ def which(program): class YoutubeCom(Hoster): __name__ = "YoutubeCom" __type__ = "hoster" - __pattern__ = r"(http|https)://(www\.)?(de\.)?\youtube\.com/watch\?v=.*" - __version__ = "0.31" + __pattern__ = r"https?://(?:[^/]*?)youtube\.com/watch.*?[?&]v=.*" + __version__ = "0.32" __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), @@ -47,9 +47,9 @@ class YoutubeCom(Hoster): __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz") # name, width, height, quality ranking, 3D - formats = {5: (".flv", 400, 240, 1, False), + formats = {5: (".flv", 400, 240, 1, False), 6: (".flv", 640, 400, 4, False), - 17: (".3gp", 176, 144, 0, False), + 17: (".3gp", 176, 144, 0, False), 18: (".mp4", 480, 360, 2, False), 22: (".mp4", 1280, 720, 8, False), 43: (".webm", 640, 360, 3, False), @@ -59,7 +59,7 @@ class YoutubeCom(Hoster): 37: (".mp4", 1920, 1080, 9, False), 38: (".mp4", 4096, 3072, 10, False), 44: (".webm", 854, 480, 5, False), - 45: (".webm", 1280, 720, 7, False), + 45: (".webm", 1280, 720, 7, False), 46: (".webm", 1920, 1080, 9, False), 82: (".mp4", 640, 360, 3, True), 83: (".mp4", 400, 240, 1, True), @@ -81,49 +81,49 @@ class YoutubeCom(Hoster): if "We have been receiving a large volume of requests from your network." in html: self.tempOffline() - + #get config use3d = self.getConf("3d") if use3d: - quality = {"sd":82,"hd":84,"fullhd":85,"240p":83,"360p":82,"480p":82,"720p":84,"1080p":85,"3072p":85} + quality = {"sd":82,"hd":84,"fullhd":85,"240p":83,"360p":82,"480p":82,"720p":84,"1080p":85,"3072p":85} else: - quality = {"sd":18,"hd":22,"fullhd":37,"240p":5,"360p":18,"480p":35,"720p":22,"1080p":37,"3072p":38} + quality = {"sd":18,"hd":22,"fullhd":37,"240p":5,"360p":18,"480p":35,"720p":22,"1080p":37,"3072p":38} desired_fmt = self.getConf("fmt") if desired_fmt and desired_fmt not in self.formats: - self.logWarning("FMT %d unknown - using default." % desired_fmt) - desired_fmt = 0 + self.logWarning("FMT %d unknown - using default." % desired_fmt) + desired_fmt = 0 if not desired_fmt: - desired_fmt = quality.get(self.getConf("quality"), 18) - + desired_fmt = quality.get(self.getConf("quality"), 18) + #parse available streams streams = re.search(r'"url_encoded_fmt_stream_map": "(.*?)",', html).group(1) streams = [x.split('\u0026') for x in streams.split(',')] streams = [dict((y.split('=',1)) for y in x) for x in streams] streams = [(int(x['itag']), "%s&signature=%s" % (unquote(x['url']), x['sig'])) for x in streams] - #self.logDebug("Found links: %s" % streams) - self.logDebug("AVAILABLE STREAMS: %s" % [x[0] for x in streams]) - + #self.logDebug("Found links: %s" % streams) + self.logDebug("AVAILABLE STREAMS: %s" % [x[0] for x in streams]) + #build dictionary of supported itags (3D/2D) - allowed = lambda x: self.getConfig(self.formats[x][0]) + allowed = lambda x: self.getConfig(self.formats[x][0]) streams = [x for x in streams if x[0] in self.formats and allowed(x[0])] if not streams: self.fail("No available stream meets your preferences") - fmt_dict = dict([x for x in streams if self.formats[x[0]][4] == use3d] or streams) - - self.logDebug("DESIRED STREAM: ITAG:%d (%s) %sfound, %sallowed" % - (desired_fmt, + fmt_dict = dict([x for x in streams if self.formats[x[0]][4] == use3d] or streams) + + self.logDebug("DESIRED STREAM: ITAG:%d (%s) %sfound, %sallowed" % + (desired_fmt, "%s %dx%d Q:%d 3D:%s" % self.formats[desired_fmt], - "" if desired_fmt in fmt_dict else "NOT ", + "" if desired_fmt in fmt_dict else "NOT ", "" if allowed(desired_fmt) else "NOT ") - ) + ) - #return fmt nearest to quality index + #return fmt nearest to quality index if desired_fmt in fmt_dict and allowed(desired_fmt): fmt = desired_fmt else: sel = lambda x: self.formats[x][3] #select quality index comp = lambda x, y: abs(sel(x) - sel(y)) - + self.logDebug("Choosing nearest fmt: %s" % [(x, allowed(x), comp(x, desired_fmt)) for x in fmt_dict.keys()]) fmt = reduce(lambda x, y: x if comp(x, desired_fmt) <= comp(y, desired_fmt) and sel(x) > sel(y) else y, fmt_dict.keys()) @@ -132,7 +132,7 @@ class YoutubeCom(Hoster): url = fmt_dict[fmt] self.logDebug("URL: %s" % url) - #set file name + #set file name file_suffix = self.formats[fmt][0] if fmt in self.formats else ".flv" file_name_pattern = '<meta name="title" content="(.+?)">' name = re.search(file_name_pattern, html).group(1).replace("/", "") diff --git a/module/plugins/hoster/ZippyshareCom.py b/module/plugins/hoster/ZippyshareCom.py index 84974e7ba..756a92ef3 100644 --- a/module/plugins/hoster/ZippyshareCom.py +++ b/module/plugins/hoster/ZippyshareCom.py @@ -10,10 +10,10 @@ class ZippyshareCom(SimpleHoster): __name__ = "ZippyshareCom" __type__ = "hoster" __pattern__ = r"(?P<HOST>http://www\d{0,2}\.zippyshare.com)/v(?:/|iew.jsp.*key=)(?P<KEY>\d+)" - __version__ = "0.37" + __version__ = "0.38" __description__ = """Zippyshare.com Download Hoster""" - __author_name__ = ("spoob", "zoidberg") - __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz") + __author_name__ = ("spoob", "zoidberg", "stickell") + __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") __config__ = [("swfdump_path", "string", "Path to swfdump", "")] FILE_NAME_PATTERN = r'>Name:</font>\s*<font [^>]*>(?P<N>[^<]+)</font><br />' @@ -62,7 +62,12 @@ class ZippyshareCom(SimpleHoster): found = re.search(self.DOWNLOAD_URL_PATTERN, self.html, re.S) if found: #Method #1: JS eval - url = self.js.eval("\n".join(found.groups())) + js = "\n".join(found.groups()) + regex = r"document.getElementById\(\\*'dlbutton\\*'\).omg" + omg = re.search(regex + r" = ([^;]+);", js).group(1) + js = re.sub(regex + r" = ([^;]+);", '', js) + js = re.sub(regex, omg, js) + url = self.js.eval(js) else: #Method #2: SWF eval seed_search = re.search(self.SEED_PATTERN, self.html) |