From bfb0134f75b1faed65de0d415c57bc296c7a37d7 Mon Sep 17 00:00:00 2001 From: Stefano Date: Tue, 24 Jun 2014 16:48:20 +0200 Subject: [YouTube] Support shortened "youtu.be" links. + Improved bad chars sanitation in filename. See #656 --- module/plugins/hoster/YoutubeCom.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py index 330aae190..6505eac1a 100644 --- a/module/plugins/hoster/YoutubeCom.py +++ b/module/plugins/hoster/YoutubeCom.py @@ -7,6 +7,7 @@ from urllib import unquote from module.utils import html_unescape from module.plugins.Hoster import Hoster +from module.plugins.internal.SimpleHoster import replace_patterns def which(program): @@ -34,8 +35,8 @@ def which(program): class YoutubeCom(Hoster): __name__ = "YoutubeCom" __type__ = "hoster" - __pattern__ = r'https?://(?:[^/]*\.)?youtube\.com/watch.*?[?&]v=.*' - __version__ = "0.39" + __pattern__ = r'https?://(?:[^/]*\.)?(?:youtube\.com|youtu\.be)/watch.*?[?&]v=.*' + __version__ = "0.40" __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,6 +48,11 @@ class YoutubeCom(Hoster): __author_name__ = ("spoob", "zoidberg") __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz") + FILE_URL_REPLACEMENTS = [(r'youtu\.be/', 'youtube.com/')] + + # Invalid characters that must be removed from the file name + invalidChars = u'\u2605:?><"|\\' + # name, width, height, quality ranking, 3D formats = {5: (".flv", 400, 240, 1, False), 6: (".flv", 640, 400, 4, False), @@ -74,6 +80,7 @@ class YoutubeCom(Hoster): self.resumeDownload = self.multiDL = True def process(self, pyfile): + pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS) html = self.load(pyfile.url, decode=True) if re.search(r'
', html): @@ -138,6 +145,8 @@ class YoutubeCom(Hoster): # Cleaning invalid characters from the file name name = name.encode('ascii', 'replace') + for c in self.invalidChars: + name = name.replace(c, '_') pyfile.name = html_unescape(name) -- cgit v1.2.3 From 0fed2d0cbe7741d0a647553a04f95d40960641be Mon Sep 17 00:00:00 2001 From: EvolutionClip Date: Wed, 25 Jun 2014 16:21:58 +0200 Subject: [SimplyPremium] Updated API Merges #655 --- module/plugins/hooks/SimplyPremiumCom.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/plugins/hooks/SimplyPremiumCom.py b/module/plugins/hooks/SimplyPremiumCom.py index ca1122e45..60d164c66 100644 --- a/module/plugins/hooks/SimplyPremiumCom.py +++ b/module/plugins/hooks/SimplyPremiumCom.py @@ -22,7 +22,7 @@ from module.common.json_layer import json_loads class SimplyPremiumCom(MultiHoster): __name__ = "SimplyPremiumCom" - __version__ = "0.01" + __version__ = "0.02" __type__ = "hook" __config__ = [("activated", "bool", "Activated", "False"), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), @@ -30,13 +30,13 @@ class SimplyPremiumCom(MultiHoster): ("unloadFailing", "bool", "Revert to standard download if download fails", "False"), ("interval", "int", "Reload interval in hours (0 to disable)", "24")] __description__ = """Simply-Premium.Com hook plugin""" - __author_name__ = ("EvolutionClip") - __author_mail__ = ("evolutionclip@live.de") + __author_name__ = "EvolutionClip" + __author_mail__ = "evolutionclip@live.de" def getHoster(self): json_data = getURL('http://www.simply-premium.com/api/hosts.php?format=json&online=1') json_data = json_loads(json_data) - host_list = [element['host'] for element in json_data['result']] + host_list = [element['regex'] for element in json_data['result']] return host_list -- cgit v1.2.3 From a6684ce241093935d3812b16da0094aab915d85d Mon Sep 17 00:00:00 2001 From: Samir Boulema Date: Wed, 25 Jun 2014 16:28:24 +0200 Subject: [Filefactory] Improved free links detect Merges #638 --- module/plugins/hoster/FilefactoryCom.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index 273a717b5..21b803649 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -23,7 +23,7 @@ class FilefactoryCom(SimpleHoster): __name__ = "FilefactoryCom" __type__ = "hoster" __pattern__ = r'https?://(?:www\.)?filefactory\.com/file/(?P[a-zA-Z0-9]+)' - __version__ = "0.47" + __version__ = "0.48" __description__ = """Filefactory.com hoster plugin""" __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" @@ -40,7 +40,7 @@ class FilefactoryCom(SimpleHoster): elif "All free download slots on this server are currently in use" in self.html: self.retry(50, 15 * 60, "All free slots are busy") - m = re.search(r'data-href-direct="(http://[^"]+)"', self.html) + m = re.search(r'data-href(?:-direct)?="(http://[^"]+)"', self.html) if m: t = re.search(r'
', self.html) if t: @@ -65,7 +65,7 @@ class FilefactoryCom(SimpleHoster): self.wait(int(waittime.group(1))) # Parse the direct link and download it - direct = re.search(r'data-href-direct="(.*)" class="button', self.html) + direct = re.search(r'data-href(?:-direct)?="(.*)" class="button', self.html) if not direct: self.parseError('Unable to detect free direct link') direct = direct.group(1) -- cgit v1.2.3 From 3dec02dd4cf0346f840ef2f859bfe7a00f0b448d Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 26 Jun 2014 13:35:29 +0200 Subject: [Fshare] Fixed #651 --- module/plugins/accounts/FshareVn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/plugins/accounts/FshareVn.py b/module/plugins/accounts/FshareVn.py index cb2ad700c..61122b996 100644 --- a/module/plugins/accounts/FshareVn.py +++ b/module/plugins/accounts/FshareVn.py @@ -26,7 +26,7 @@ from module.plugins.Account import Account class FshareVn(Account): __name__ = "FshareVn" - __version__ = "0.06" + __version__ = "0.07" __type__ = "account" __description__ = """Fshare.vn account plugin""" __author_name__ = ("zoidberg", "stickell") @@ -63,10 +63,10 @@ class FshareVn(Account): self.html = req.load('https://www.fshare.vn/login.php', post={ "login_password": data['password'], "login_useremail": user, - "url_refe": "https://www.fshare.vn/login.php" + "url_refe": "http://www.fshare.vn/index.php" }, referer=True, decode=True) - if not 'VIP Date: Thu, 26 Jun 2014 21:35:11 +0200 Subject: [UpdateManager] rewritten --- module/plugins/hooks/UpdateManager.py | 269 +++++++++++++++++++--------------- 1 file changed, 151 insertions(+), 118 deletions(-) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 5f88ea6d0..7ed4dc19f 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -2,6 +2,7 @@ import sys import re + from os import remove, stat from os.path import join, isfile from time import time @@ -13,86 +14,120 @@ from module.plugins.Hook import threaded, Expose, Hook class UpdateManager(Hook): __name__ = "UpdateManager" - __version__ = "0.16" - __description__ = """Checks for updates""" + __version__ = "0.22" + __description__ = """Check for updates""" __config__ = [("activated", "bool", "Activated", True), - ("interval", "int", "Check interval in minutes", 480), - ("debug", "bool", "Check for plugin changes when in debug mode", False)] - __author_name__ = ("RaNaN", "stickell") - __author_mail__ = ("ranan@pyload.org", "l.stickell@yahoo.it") + ("mode", "pyLoad + plugins;plugins only", "Check updates for", "pyLoad + plugins"), + ("interval", "int", "Check interval in hours", 8), + ("reloadplugins", "bool", "Monitor plugins for code changes (debug mode only)", True), + ("nodebugupdate", "bool", "Don't check for updates in debug mode", True)] + __author_name__ = ("RaNaN", "stickell", "Walter Purcaro") + __author_mail__ = ("ranan@pyload.org", "l.stickell@yahoo.it", "vuolter@gmail.com") - URL = "http://updatemanager.pyload.org" - MIN_TIME = 3 * 60 * 60 # 3h minimum check interval + SERVER_URL = "http://updatemanager.pyload.org" + MIN_TIME = 3 * 60 * 60 #: 3h minimum check interval - @property - def debug(self): - return self.core.debug and self.getConfig("debug") + event_list = ["pluginConfigChanged"] - def setup(self): - if self.debug: - self.logDebug("Monitoring file changes") - self.interval = 4 - self.last_check = 0 # timestamp of updatecheck - self.old_periodical = self.periodical - self.periodical = self.checkChanges - self.mtimes = {} # recordes times - else: - self.interval = max(self.getConfig("interval") * 60, self.MIN_TIME) - self.updated = False - self.reloaded = True - self.version = "None" + def pluginConfigChanged(self, plugin, name, value): + if name == "interval" and 0 < value != self.interval: + self.interval = max(value * 60 * 60, self.MIN_TIME) + self.initPeriodical() + elif name == "reloadplugins": + if self.cb2: + self.core.scheduler.removeJob(self.cb2) + if value and self.core.debug: + self.periodical2() + def coreReady(self): + self.pluginConfigChanged(self.__name__, "reloadplugins", self.getConfig("reloadplugins")) + + def setup(self): + self.cb2 = None + self.interval = self.MIN_TIME + self.updating = False self.info = {"pyload": False, "plugins": False} + self.mtimes = {} #: store modification time for each plugin - @threaded - def periodical(self): - updates = self.checkForUpdate() - if updates: - self.checkPlugins(updates) - - if self.updated and not self.reloaded: - self.info["plugins"] = True - self.logInfo(_("*** Plugins have been updated, please restart pyLoad ***")) - elif self.updated and self.reloaded: - self.logInfo(_("Plugins updated and reloaded")) - self.updated = False - elif self.version == "None": - self.logInfo(_("No plugin updates available")) + + def periodical2(self): + if not self.updating: + self.autoreloadPlugins() + self.cb2 = self.core.scheduler.addJob(10, self.periodical2, threaded=True) @Expose - def recheckForUpdates(self): - """recheck if updates are available""" - self.periodical() + def autoreloadPlugins(self): + """ reload and reindex all modified plugins """ + modules = filter( + lambda m: m and (m.__name__.startswith("module.plugins.") or m.__name__.startswith( + "userplugins.")) and m.__name__.count(".") >= 2, sys.modules.itervalues()) + + reloads = [] + + for m in modules: + root, type, name = m.__name__.rsplit(".", 2) + id = (type, name) + if type in self.core.pluginManager.plugins: + f = m.__file__.replace(".pyc", ".py") + if not isfile(f): + continue + + mtime = stat(f).st_mtime - def checkForUpdate(self): - """checks if an update is available, return result""" + if id not in self.mtimes: + self.mtimes[id] = mtime + elif self.mtimes[id] < mtime: + reloads.append(id) + self.mtimes[id] = mtime + + return True if self.core.pluginManager.reloadPlugins(reloads) else False + + @threaded + def periodical(self): + if not self.info["pyload"] and not (self.getConfig("nodebugupdate") and self.core.debug): + self.updating = True + self.update(onlyplugin=True if self.getConfig("mode") == "plugins only" else False) + self.updating = False + + def server_response(self): try: - if self.version == "None": # No updated known - version_check = getURL(self.URL, get={'v': self.core.api.getServerVersion()}).splitlines() - self.version = version_check[0] - - # Still no updates, plugins will be checked - if self.version == "None": - self.logInfo(_("No Updates for pyLoad")) - return version_check[1:] - - self.info["pyload"] = True - self.logInfo(_("*** New pyLoad Version %s available ***") % self.version) - self.logInfo(_("*** Get it here: http://pyload.org/download ***")) + return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines() except: - self.logWarning(_("Not able to connect server for updates")) + self.logWarning(_("Not able to connect server to get updates")) - return None # Nothing will be done + @Expose + def updatePlugins(self): + """ simple wrapper for calling plugin update quickly """ + return self.update(onlyplugin=True) + + @Expose + def update(self, onlyplugin=False): + """ check for updates """ + data = self.server_response() + if not data: + r = False + elif data[0] == "None": + self.logInfo(_("No pyLoad version available")) + updates = data[1:] + r = self._updatePlugins(updates) + elif onlyplugin: + r = False + else: + newversion = data[0] + # self.info["pyload"] = newversion + self.logInfo(_("*** New pyLoad Version %s available ***") % newversion) + self.logInfo(_("*** Get it here: https://github.com/pyload/pyload/releases ***")) + r = self.info["pyload"] = True + return r - def checkPlugins(self, updates): - """ checks for plugins updates""" + def _updatePlugins(self, updates): + """ check for plugin updates """ - # plugins were already updated if self.info["plugins"]: - return + return False #: plugins were already updated - reloads = [] + updated = [] vre = re.compile(r'__version__.*=.*("|\')([0-9.]+)') url = updates[0] @@ -123,79 +158,77 @@ class UpdateManager(Hook): plugins = getattr(self.core.pluginManager, "%sPlugins" % type) - if name in plugins: - if float(plugins[name]["v"]) >= float(version): - continue - - if name in IGNORE or (type, name) in IGNORE: + if name not in plugins or name in IGNORE or (type, name) in IGNORE: continue - self.logInfo(_("New version of %(type)s|%(name)s : %(version).2f") % { - "type": type, - "name": name, - "version": float(version) - }) + oldver = float(plugins[name]["v"]) + newver = float(version) + + if oldver >= newver: + continue + else: + self.logInfo(_("New version of [%(type)s] %(name)s (v%(oldver)s -> v%(newver)s)") % { + "type": type, + "name": name, + "oldver": oldver, + "newver": newver + }) try: content = getURL(url % info) except Exception, e: - self.logWarning(_("Error when updating %s") % filename, str(e)) + self.logError(_("Error when updating plugin %s") % filename, str(e)) continue m = vre.search(content) if not m or m.group(2) != version: - self.logWarning(_("Error when updating %s") % name, _("Version mismatch")) + self.logError(_("Error when updating plugin %s") % name, _("Version mismatch")) continue f = open(join("userplugins", prefix, filename), "wb") f.write(content) f.close() - self.updated = True - - reloads.append((prefix, name)) + updated.append((prefix, name)) if blacklist: - self.executeBlacklist(blacklist) - - self.reloaded = self.core.pluginManager.reloadPlugins(reloads) - - def executeBlacklist(self, blacklist): - for b in blacklist: - type, name = b.split('|') - if isfile(join("userplugins", type, name)): - self.logInfo(_("Removing blacklisted plugin %(type)s|%(name)s") % { - "type": type, - "name": name + removed = self.removePlugins(map(lambda x: x.split('|'), blacklist)) + for t, n in removed: + self.logInfo(_("Removed blacklisted plugin: [%(type)s] %(name)s") % { + "type": t, + "name": n }) - remove(join("userplugins", type, name)) - if isfile(join("userplugins", type, name.replace('.py', '.pyc'))): - remove(join("userplugins", type, name.replace('.py', '.pyc'))) - - def checkChanges(self): - if self.last_check + max(self.getConfig("interval") * 60, self.MIN_TIME) < time(): - self.old_periodical() - self.last_check = time() - - modules = filter( - lambda m: m and (m.__name__.startswith("module.plugins.") or m.__name__.startswith( - "userplugins.")) and m.__name__.count(".") >= 2, sys.modules.itervalues()) - - reloads = [] - for m in modules: - root, type, name = m.__name__.rsplit(".", 2) - id = (type, name) - if type in self.core.pluginManager.plugins: - f = m.__file__.replace(".pyc", ".py") - if not isfile(f): - continue - - mtime = stat(f).st_mtime - - if id not in self.mtimes: - self.mtimes[id] = mtime - elif self.mtimes[id] < mtime: - reloads.append(id) - self.mtimes[id] = mtime + if updated: + reloaded = self.core.pluginManager.reloadPlugins(updated) + if reloaded: + self.logInfo(_("Plugins updated and reloaded")) + else: + self.logInfo(_("*** Plugins have been updated, pyLoad will be restarted now ***")) + self.info["plugins"] = True + self.core.scheduler.addJob(4, self.core.api.restart(), threaded=False) #: risky, but pyload doesn't let more + return True + else: + self.logInfo(_("No plugin updates available")) + return False - self.core.pluginManager.reloadPlugins(reloads) + @Expose + def removePlugins(self, type_plugins): + """ delete plugins under userplugins directory""" + if not type_plugins: + return None + + self.logDebug("Request deletion of plugins: %s" % type_plugins) + + removed = [] + + for type, name in type_plugins: + py = join("userplugins", type, name) + pyc = py[::-1].replace('.py', '.pyc')[::-1] + if isfile(py): + id = (type, name) + remove(py) + removed.append(id) + if isfile(pyc): + remove(pyc) + + return removed #: return a list of the plugins successfully removed -- cgit v1.2.3 From d80acfcf88491b758019c8c6881e43089bf17e46 Mon Sep 17 00:00:00 2001 From: stickell Date: Thu, 26 Jun 2014 21:39:23 +0200 Subject: [UpdateManager] bump Fix commit hash on the update manager server --- module/plugins/hooks/UpdateManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 7ed4dc19f..a824ee902 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -14,7 +14,7 @@ from module.plugins.Hook import threaded, Expose, Hook class UpdateManager(Hook): __name__ = "UpdateManager" - __version__ = "0.22" + __version__ = "0.23" __description__ = """Check for updates""" __config__ = [("activated", "bool", "Activated", True), ("mode", "pyLoad + plugins;plugins only", "Check updates for", "pyLoad + plugins"), -- cgit v1.2.3 From 7d78210720ed3bde25ca240f8bd061cc6210e3fb Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 26 Jun 2014 22:02:55 +0200 Subject: [SimplyPremium] Fix #649 --- module/plugins/hoster/SimplyPremiumCom.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/module/plugins/hoster/SimplyPremiumCom.py b/module/plugins/hoster/SimplyPremiumCom.py index c9fbf2ff1..17060e00d 100644 --- a/module/plugins/hoster/SimplyPremiumCom.py +++ b/module/plugins/hoster/SimplyPremiumCom.py @@ -34,12 +34,12 @@ def secondsToMidnight(): class SimplyPremiumCom(Hoster): __name__ = "SimplyPremiumCom" - __version__ = "0.01" + __version__ = "0.02" __type__ = "hoster" __pattern__ = r"https?://.*(simply-premium)\.com" __description__ = """Simply-Premium.Com hoster plugin""" - __author_name__ = ("EvolutionClip") - __author_mail__ = ("evolutionclip@live.de") + __author_name__ = "EvolutionClip" + __author_mail__ = "evolutionclip@live.de" def setup(self): self.chunkLimit = 16 @@ -82,20 +82,19 @@ class SimplyPremiumCom(Hoster): #self.api_data = page[new_url] try: - start = page.index('') + len('') - end = page.index('', start) - self.pyfile.name = page[start:end] - except ValueError: + self.pyfile.name = re.search(r'([^<]+)', page).group(1) + except AttributeError: self.pyfile.name = "" try: - start = page.index('') + len('') - end = page.index('', start) - self.pyfile.size = int(float(page[start:end])) - except ValueError: + self.pyfile.size = re.search(r'(\d+)', page).group(1) + except AttributeError: self.pyfile.size = 0 - new_url = 'http://www.simply-premium.com/premium.php?link=' + pyfile.url + try: + new_url = re.search(r'([^<]+)', page).group(1) + except AttributeError: + new_url = 'http://www.simply-premium.com/premium.php?link=' + pyfile.url if new_url != pyfile.url: self.logDebug("New URL: " + new_url) -- cgit v1.2.3 From ce7916efe98bac98f178cadd0ab2c6af4d9e5b8f Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Thu, 26 Jun 2014 22:52:03 +0200 Subject: [UpdateManager] Fix removePlugins method --- module/plugins/hooks/UpdateManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index a824ee902..5b7bf76b0 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -14,7 +14,7 @@ from module.plugins.Hook import threaded, Expose, Hook class UpdateManager(Hook): __name__ = "UpdateManager" - __version__ = "0.23" + __version__ = "0.24" __description__ = """Check for updates""" __config__ = [("activated", "bool", "Activated", True), ("mode", "pyLoad + plugins;plugins only", "Check updates for", "pyLoad + plugins"), @@ -223,7 +223,7 @@ class UpdateManager(Hook): for type, name in type_plugins: py = join("userplugins", type, name) - pyc = py[::-1].replace('.py', '.pyc')[::-1] + pyc = join("userplugins", type, name.replace('.py', '.pyc')) if isfile(py): id = (type, name) remove(py) -- cgit v1.2.3 From 2945a72664d4b6e8ca6b50fa8efde483edfb9723 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Fri, 27 Jun 2014 00:59:12 +0200 Subject: Spare fixes --- module/plugins/hooks/HotFolder.py | 1 - module/plugins/hoster/MegacrypterCom.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py index 38bcaf440..a63b314d1 100644 --- a/module/plugins/hooks/HotFolder.py +++ b/module/plugins/hooks/HotFolder.py @@ -38,7 +38,6 @@ class HotFolder(Hook): ("watch_file", "bool", "Observe link file", False), ("keep", "bool", "Keep added containers", True), ("file", "str", "Link file", "links.txt")] - __threaded__ = [] __author_name__ = "RaNaN" __author_mail__ = "RaNaN@pyload.de" diff --git a/module/plugins/hoster/MegacrypterCom.py b/module/plugins/hoster/MegacrypterCom.py index 8b72606ce..ee6be39a2 100644 --- a/module/plugins/hoster/MegacrypterCom.py +++ b/module/plugins/hoster/MegacrypterCom.py @@ -36,7 +36,7 @@ class MegacrypterCom(MegaNz): dl = self.callApi(link=node, m="dl") # TODO: map error codes, implement password protection - # if info["pass"] == true: + # if info["pass"] == True: # crypted_file_key, md5_file_key = info["key"].split("#") key = self.b64_decode(info["key"]) -- cgit v1.2.3 From fb47817e99e9773b0cc1c39d537b7c594f6d71d3 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Fri, 27 Jun 2014 01:44:45 +0200 Subject: [UpdateManager] Store new pyload's version number when a system update is available --- module/plugins/hooks/UpdateManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 5b7bf76b0..9f8ccdb80 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -47,7 +47,7 @@ class UpdateManager(Hook): self.cb2 = None self.interval = self.MIN_TIME self.updating = False - self.info = {"pyload": False, "plugins": False} + self.info = {"pyload": False, "version": None, "plugins": False} self.mtimes = {} #: store modification time for each plugin @@ -115,10 +115,10 @@ class UpdateManager(Hook): r = False else: newversion = data[0] - # self.info["pyload"] = newversion self.logInfo(_("*** New pyLoad Version %s available ***") % newversion) self.logInfo(_("*** Get it here: https://github.com/pyload/pyload/releases ***")) r = self.info["pyload"] = True + self.info["version"] = newversion return r def _updatePlugins(self, updates): -- cgit v1.2.3 From 10ce4afb555375e2cf101c8e89b53f398ba67c8c Mon Sep 17 00:00:00 2001 From: igel-kun Date: Sun, 29 Jun 2014 21:30:29 +0200 Subject: Update FilepostCom.py --- module/plugins/hoster/FilepostCom.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/plugins/hoster/FilepostCom.py b/module/plugins/hoster/FilepostCom.py index 01ac76850..d173a0df4 100644 --- a/module/plugins/hoster/FilepostCom.py +++ b/module/plugins/hoster/FilepostCom.py @@ -34,7 +34,7 @@ class FilepostCom(SimpleHoster): __name__ = "FilepostCom" __type__ = "hoster" __pattern__ = r'https?://(?:www\.)?(?:filepost\.com/files|fp.io)/([^/]+).*' - __version__ = "0.27" + __version__ = "0.28" __description__ = """Filepost.com hoster plugin""" __author_name__ = "zoidberg" __author_mail__ = "zoidberg@mujmail.cz" @@ -44,6 +44,7 @@ class FilepostCom(SimpleHoster): FILE_OFFLINE_PATTERN = r'class="error_msg_title"> Invalid or Deleted File.
|
' RECAPTCHA_KEY_PATTERN = r"Captcha.init\({\s*key:\s*'([^']+)'" FLP_TOKEN_PATTERN = r"set_store_options\({token: '([^']+)'" + PREMIUM_ONLY_PATTERN = r'members only. Please upgrade to premium|a premium membership is required to download this file' def handleFree(self): # Find token and captcha key -- cgit v1.2.3 From 2d893a24d4bb8b5a7a00807ed6320358454577f8 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Sun, 29 Jun 2014 21:55:29 +0200 Subject: [SimpleHoster] Improve documentation of own public attributes --- module/plugins/internal/SimpleHoster.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index f10433e78..8c2e3daae 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -169,15 +169,19 @@ class SimpleHoster(Hoster): __description__ = """Simple hoster plugin""" __author_name__ = ("zoidberg", "stickell") __author_mail__ = ("zoidberg@mujmail.cz", "l.stickell@yahoo.it") + """ - These patterns should be defined by each hoster: - FILE_INFO_PATTERN = r'(?Pfile_name) (?Pfile_size) (?Punits)' - or FILE_NAME_PATTERN = r'(?Pfile_name)' - and FILE_SIZE_PATTERN = r'(?Pfile_size) (?Punits)' + Following patterns should be defined by each hoster: + FILE_INFO_PATTERN = r'(?Pfile_name) (?Pfile_size) (?Psize_unit)' + or + FILE_NAME_PATTERN = r'(?Pfile_name)' + FILE_SIZE_PATTERN = r'(?Pfile_size) (?Psize_unit)' + FILE_OFFLINE_PATTERN = r'File (deleted|not found)' TEMP_OFFLINE_PATTERN = r'Server maintainance' - You can also define a PREMIUM_ONLY_PATTERN to detect links that can be downloaded only with a premium account. + You can also define: + PREMIUM_ONLY_PATTERN = r'Premium account required' """ FILE_SIZE_REPLACEMENTS = [] -- cgit v1.2.3 From 3b7277cd0013539dd2cd65fd270f7643a5c3779a Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Mon, 30 Jun 2014 02:28:24 +0200 Subject: [RSDF] Improve code a bit (thx charlie89) --- module/plugins/container/RSDF.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/module/plugins/container/RSDF.py b/module/plugins/container/RSDF.py index 42296f2d5..f7d3f7377 100644 --- a/module/plugins/container/RSDF.py +++ b/module/plugins/container/RSDF.py @@ -6,9 +6,10 @@ import re from module.plugins.Container import Container + class RSDF(Container): __name__ = "RSDF" - __version__ = "0.21" + __version__ = "0.22" __pattern__ = r'.+\.rsdf' __description__ = """RSDF container decrypter plugin""" __author_name__ = ("RaNaN", "spoob") @@ -38,10 +39,12 @@ class RSDF(Container): links = [] for link in data: + if link == '': + continue link = base64.b64decode(link) link = obj.decrypt(link) decryptedUrl = link.replace('CCF: ', '') links.append(decryptedUrl) - self.log.debug("%s: adding package %s with %d links" % (self.__name__,pyfile.package().name,len(links))) + self.log.debug("%s: adding package %s with %d links" % (self.__name__, pyfile.package().name, len(links))) self.packages.append((pyfile.package().name, links)) -- cgit v1.2.3 From c0a976b02b13fcda9d20372b4562a1fdfae61f82 Mon Sep 17 00:00:00 2001 From: Stefano Date: Mon, 30 Jun 2014 13:06:54 +0200 Subject: [Bitshare] Fixed #663 --- module/plugins/hoster/BitshareCom.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py index d4b0668c0..c1a0d50f8 100644 --- a/module/plugins/hoster/BitshareCom.py +++ b/module/plugins/hoster/BitshareCom.py @@ -12,7 +12,7 @@ class BitshareCom(SimpleHoster): __name__ = "BitshareCom" __type__ = "hoster" __pattern__ = r'http://(?:www\.)?bitshare\.com/(files/(?P[a-zA-Z0-9]+)(/(?P.*?)\.html)?|\?f=(?P[a-zA-Z0-9]+))' - __version__ = "0.49" + __version__ = "0.50" __description__ = """Bitshare.com hoster plugin""" __author_name__ = ("Paul King", "fragonib") __author_mail__ = ("", "fragonib[AT]yahoo[DOT]es") @@ -70,6 +70,12 @@ class BitshareCom(SimpleHoster): self.logDebug("Downloading file with url [%s]" % url) self.download(url) + check = self.checkDownload({"404": ">404 Not Found<", "Error": ">Error occured<"}) + if check == "404": + self.retry(3, 60, 'Error 404') + elif check == "error": + self.retry(5, 5 * 60, "Bitshare host : Error occured") + def getDownloadUrl(self): # Return location if direct download is active if self.premium: -- cgit v1.2.3 From 821ed8c027a19c4a76d6fb81b161711b50ad773d Mon Sep 17 00:00:00 2001 From: nath_schwarz Date: Mon, 30 Jun 2014 13:33:10 +0200 Subject: [ImgurComAlbum] new crypter --- module/plugins/crypter/ImgurComAlbum.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 module/plugins/crypter/ImgurComAlbum.py diff --git a/module/plugins/crypter/ImgurComAlbum.py b/module/plugins/crypter/ImgurComAlbum.py new file mode 100644 index 000000000..f05cf553b --- /dev/null +++ b/module/plugins/crypter/ImgurComAlbum.py @@ -0,0 +1,21 @@ +import re + +from module.plugins.internal.SimpleCrypter import SimpleCrypter +from module.utils import uniqify + + +class ImgurComAlbum(SimpleCrypter): + __name__ = "ImgurComAlbum" + __type__ = "crypter" + __version__ = "0.3" + __description__ = """Imgur.com decrypter plugin""" + __pattern__ = r"https?://imgur\.com/(a|gallery|)/?\w{5,7}" + __author_name_ = "nath_schwarz" + __author_mail_ = "nathan.notwhite@gmail.com" + + TITLE_PATTERN = r'(?P.+) - Imgur' + LINK_PATTERN = r'i\.imgur\.com/\w{7}s?\.(?:jpeg|jpg|png|gif|apng)' + + def getLinks(self): + f = lambda url: "http://" + re.sub(r'(\w{7})s\.', r'\1.', url) + return uniqify(map(f, re.findall(self.LINK_PATTERN, self.html))) -- cgit v1.2.3 From aa3ca942268b88dce3f2ef78a39a969400dfa2c4 Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Tue, 1 Jul 2014 14:19:38 +0200 Subject: [FilerNetFolder] New crypter See also #660 --- module/plugins/crypter/FilerNetFolder.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 module/plugins/crypter/FilerNetFolder.py diff --git a/module/plugins/crypter/FilerNetFolder.py b/module/plugins/crypter/FilerNetFolder.py new file mode 100644 index 000000000..70c932d00 --- /dev/null +++ b/module/plugins/crypter/FilerNetFolder.py @@ -0,0 +1,19 @@ +import re + +from module.plugins.internal.SimpleCrypter import SimpleCrypter + + +class FilerNetFolder(SimpleCrypter): + __name__ = "FilerNetFolder" + __type__ = "crypter" + __version__ = "0.3" + __description__ = """Filer.net decrypter plugin""" + __pattern__ = r"https?://filer\.net/folder/\w{16}" + __author_name_ = ("nath_schwarz", "stickell") + __author_mail_ = ("nathan.notwhite@gmail.com", "l.stickell@yahoo.it") + + LINK_PATTERN = r'href="(/get/\w{16})">(?!<)' + TITLE_PATTERN = r'<h3>(?P<title>.+) - <small' + + def getLinks(self): + return ['http://filer.net%s' % link for link in re.findall(self.LINK_PATTERN, self.html)] -- cgit v1.2.3 From b0ce3ead2971a37f400ac722372def09a726c375 Mon Sep 17 00:00:00 2001 From: igel-kun <mathiaswe@gmx.de> Date: Tue, 1 Jul 2014 20:52:22 +0200 Subject: [Uploaded] Fixes Merges #668 --- module/plugins/hoster/UploadedTo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py index 6d17bcbd9..99db802cf 100644 --- a/module/plugins/hoster/UploadedTo.py +++ b/module/plugins/hoster/UploadedTo.py @@ -89,7 +89,7 @@ class UploadedTo(Hoster): __name__ = "UploadedTo" __type__ = "hoster" __pattern__ = r'https?://(?:www\.)?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)' - __version__ = "0.72" + __version__ = "0.73" __description__ = """Uploaded.net hoster plugin""" __author_name__ = ("spoob", "mkaay", "zoidberg", "netpok", "stickell") __author_mail__ = ("spoob@pyload.org", "mkaay@mkaay.de", "zoidberg@mujmail.cz", @@ -210,7 +210,7 @@ class UploadedTo(Hoster): self.setWait(3 * 60 * 60, True) self.wait() self.retry() - elif 'err:"captcha"' in result: + elif '"err":"captcha"' in result: self.logError("ul.net captcha is disabled") self.invalidCaptcha() elif "type:'download'" in result: @@ -218,7 +218,7 @@ class UploadedTo(Hoster): downloadURL = re.search("url:'([^']+)", result).group(1) break else: - self.fail("Unknown error '%s'") + self.fail("Unknown error '%s'" % result) if not downloadURL: self.fail("No Download url retrieved/all captcha attempts failed") -- cgit v1.2.3 From 1340c543e296f41a9a4ab7377f016c50e716535c Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Wed, 2 Jul 2014 14:29:44 +0200 Subject: [UpdateManager] Fix interval changing procedure --- module/plugins/hooks/UpdateManager.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 9f8ccdb80..8e8449a51 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -14,7 +14,7 @@ from module.plugins.Hook import threaded, Expose, Hook class UpdateManager(Hook): __name__ = "UpdateManager" - __version__ = "0.24" + __version__ = "0.25" __description__ = """Check for updates""" __config__ = [("activated", "bool", "Activated", True), ("mode", "pyLoad + plugins;plugins only", "Check updates for", "pyLoad + plugins"), @@ -25,15 +25,21 @@ class UpdateManager(Hook): __author_mail__ = ("ranan@pyload.org", "l.stickell@yahoo.it", "vuolter@gmail.com") SERVER_URL = "http://updatemanager.pyload.org" - MIN_TIME = 3 * 60 * 60 #: 3h minimum check interval + MIN_TIME = 3 * 60 * 60 #: 3h minimum check interval (seconds) event_list = ["pluginConfigChanged"] def pluginConfigChanged(self, plugin, name, value): - if name == "interval" and 0 < value != self.interval: - self.interval = max(value * 60 * 60, self.MIN_TIME) - self.initPeriodical() + if name == "interval": + interval = value * 60 * 60 + if self.MIN_TIME <= interval != self.interval: + if self.cb: + self.core.scheduler.removeJob(self.cb) + self.interval = interval + self.initPeriodical() + else: + self.logWarning("Invalid interval value, kept current") elif name == "reloadplugins": if self.cb2: self.core.scheduler.removeJob(self.cb2) -- cgit v1.2.3 From 47d3ef52a10e1a0db8b73fde81c9d3a7eaed00c3 Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Wed, 2 Jul 2014 14:56:10 +0200 Subject: [Filefactory] getInfo handle direct links Partially fixes #648 --- module/plugins/hoster/FilefactoryCom.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index 21b803649..05edf6b99 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -16,14 +16,26 @@ import re -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.internal.SimpleHoster import SimpleHoster, parseFileInfo +from module.network.RequestFactory import getURL + + +def getInfo(urls): + for url in urls: + h = getURL(url, just_header=True) + m = re.search(r'Location: (.+)\r\n', h) + if m and not re.match(m.group(1), FilefactoryCom.__pattern__): # It's a direct link! Skipping + yield (url, 0, 3, url) + else: # It's a standard html page + file_info = parseFileInfo(FilefactoryCom, url, getURL(url)) + yield file_info class FilefactoryCom(SimpleHoster): __name__ = "FilefactoryCom" __type__ = "hoster" __pattern__ = r'https?://(?:www\.)?filefactory\.com/file/(?P<id>[a-zA-Z0-9]+)' - __version__ = "0.48" + __version__ = "0.49" __description__ = """Filefactory.com hoster plugin""" __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" @@ -101,6 +113,3 @@ class FilefactoryCom(SimpleHoster): self.logDebug('DIRECT PREMIUM LINK: ' + url) self.download(url, disposition=True) - - -getInfo = create_getInfo(FilefactoryCom) -- cgit v1.2.3 From 521a8122e24cbcf27578e88d75fea356b4ea4a5f Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Wed, 2 Jul 2014 15:17:50 +0200 Subject: [Filefactory] Improved offline pattern Forced english locale --- module/plugins/hoster/FilefactoryCom.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index 05edf6b99..ab0d3232f 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -35,15 +35,16 @@ class FilefactoryCom(SimpleHoster): __name__ = "FilefactoryCom" __type__ = "hoster" __pattern__ = r'https?://(?:www\.)?filefactory\.com/file/(?P<id>[a-zA-Z0-9]+)' - __version__ = "0.49" + __version__ = "0.50" __description__ = """Filefactory.com hoster plugin""" __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" FILE_INFO_PATTERN = r'<div id="file_name"[^>]*>\s*<h2>(?P<N>[^<]+)</h2>\s*<div id="file_info">\s*(?P<S>[\d.]+) (?P<U>\w+) uploaded' DIRECT_LINK_PATTERN = r'<a href="(https?://[^"]+)"[^>]*><i[^>]*></i> Download with FileFactory Premium</a>' - FILE_OFFLINE_PATTERN = r'<h2>File Removed</h2>' + FILE_OFFLINE_PATTERN = r'<h2>File Removed</h2>|This file is no longer available' PREMIUM_ONLY_PATTERN = r'>Premium Account Required<' + SH_COOKIES = [('.filefactory.com', 'locale', 'en_US.utf8')] def handleFree(self): self.html = self.load(self.pyfile.url, decode=True) -- cgit v1.2.3 From 9c9cc6d4871b9847dada36c63ae1cbadfacef999 Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Wed, 2 Jul 2014 15:23:46 +0200 Subject: [SimpleCrypter] ability to set cookies --- module/plugins/internal/SimpleCrypter.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index b1a18f5e0..268efee86 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -21,12 +21,12 @@ import re from module.plugins.Crypter import Crypter from module.utils import html_unescape -from module.plugins.internal.SimpleHoster import replace_patterns +from module.plugins.internal.SimpleHoster import replace_patterns, set_cookies class SimpleCrypter(Crypter): __name__ = "SimpleCrypter" - __version__ = "0.07" + __version__ = "0.08" __pattern__ = None __type__ = "crypter" __description__ = """Simple decrypter plugin""" @@ -55,6 +55,12 @@ class SimpleCrypter(Crypter): FILE_URL_REPLACEMENTS = [] + SH_COOKIES = True # or False or list of tuples [(domain, name, value)] + + def setup(self): + if isinstance(self.SH_COOKIES, list): + set_cookies(self.req.cj, self.SH_COOKIES) + def decrypt(self, pyfile): pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS) -- cgit v1.2.3 From 59dbd29405af5847fc69a9801db23a695972cfd6 Mon Sep 17 00:00:00 2001 From: Stefano <l.stickell@yahoo.it> Date: Wed, 2 Jul 2014 15:24:23 +0200 Subject: [FilefactoryComFolder] Rewritten Fixes #648 --- module/plugins/crypter/FilefactoryComFolder.py | 47 +++++++------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/module/plugins/crypter/FilefactoryComFolder.py b/module/plugins/crypter/FilefactoryComFolder.py index aece1a01d..2147c48df 100644 --- a/module/plugins/crypter/FilefactoryComFolder.py +++ b/module/plugins/crypter/FilefactoryComFolder.py @@ -1,45 +1,22 @@ # -*- coding: utf-8 -*- -import re -from module.plugins.Crypter import Crypter +from module.plugins.internal.SimpleCrypter import SimpleCrypter -class FilefactoryComFolder(Crypter): +class FilefactoryComFolder(SimpleCrypter): __name__ = "FilefactoryComFolder" __type__ = "crypter" - __pattern__ = r'(http://(?:www\.)?filefactory\.com/f/\w+).*' - __version__ = "0.1" + __pattern__ = r'https?://(?:www\.)?filefactory\.com/(?:f|folder)/\w+' + __version__ = "0.2" __description__ = """Filefactory.com folder decrypter plugin""" - __author_name__ = "zoidberg" - __author_mail__ = "zoidberg@mujmail.cz" + __author_name__ = "stickell" + __author_mail__ = "l.stickell@yahoo.it" - FOLDER_PATTERN = r'<table class="items" cellspacing="0" cellpadding="0">(.*?)</table>' - LINK_PATTERN = r'<td class="name"><a href="([^"]+)">' - PAGINATOR_PATTERN = r'<div class="list">\s*<label>Pages</label>\s*<ul>(.*?)</ul>\s*</div>' - NEXT_PAGE_PATTERN = r'<li class="current">.*?</li>\s*<li class=""><a href="([^"]+)">' + LINK_PATTERN = r'<td><a href="([^"]+)">' + TITLE_PATTERN = r'<h1>Files in <span>(?P<title>.+)</span></h1>' + PAGES_PATTERN = r'data-paginator-totalPages="(?P<pages>\d+)"' - def decrypt(self, pyfile): - url_base = re.match(self.__pattern__, pyfile.url).group(1) - html = self.load(url_base) + SH_COOKIES = [('.filefactory.com', 'locale', 'en_US.utf8')] - new_links = [] - for i in xrange(1, 100): - self.logInfo("Fetching links from page %i" % i) - found = re.search(self.FOLDER_PATTERN, html, re.DOTALL) - if found is None: self.fail("Parse error (FOLDER)") - - new_links.extend(re.findall(self.LINK_PATTERN, found.group(1))) - - try: - paginator = re.search(self.PAGINATOR_PATTERN, html, re.DOTALL).group(1) - next_page = re.search(self.NEXT_PAGE_PATTERN, paginator).group(1) - html = self.load("%s/%s" % (url_base, next_page)) - except Exception, e: - break - else: - self.logInfo("Limit of 99 pages reached, aborting") - - if new_links: - self.core.files.addLinks(new_links, pyfile.package().id) - else: - self.fail('Could not extract any links') + def loadPage(self, page_n): + return self.load(self.pyfile.url, get={'page': page_n}) -- cgit v1.2.3 From 1609d320be17c87ff0c7640511c9ba911fdd862e Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Sat, 5 Jul 2014 02:24:04 +0200 Subject: Fixed https://github.com/pyload/pyload/issues/671 + improved threading --- module/plugins/hooks/UpdateManager.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 8e8449a51..ce06612bd 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -14,7 +14,7 @@ from module.plugins.Hook import threaded, Expose, Hook class UpdateManager(Hook): __name__ = "UpdateManager" - __version__ = "0.25" + __version__ = "0.26" __description__ = """Check for updates""" __config__ = [("activated", "bool", "Activated", True), ("mode", "pyLoad + plugins;plugins only", "Check updates for", "pyLoad + plugins"), @@ -34,8 +34,7 @@ class UpdateManager(Hook): if name == "interval": interval = value * 60 * 60 if self.MIN_TIME <= interval != self.interval: - if self.cb: - self.core.scheduler.removeJob(self.cb) + self.core.scheduler.removeJob(self.cb) self.interval = interval self.initPeriodical() else: @@ -43,10 +42,11 @@ class UpdateManager(Hook): elif name == "reloadplugins": if self.cb2: self.core.scheduler.removeJob(self.cb2) - if value and self.core.debug: + if value == True and self.core.debug: self.periodical2() def coreReady(self): + self.pluginConfigChanged(self.__name__, "interval", self.getConfig("interval")) self.pluginConfigChanged(self.__name__, "reloadplugins", self.getConfig("reloadplugins")) def setup(self): @@ -89,7 +89,6 @@ class UpdateManager(Hook): return True if self.core.pluginManager.reloadPlugins(reloads) else False - @threaded def periodical(self): if not self.info["pyload"] and not (self.getConfig("nodebugupdate") and self.core.debug): self.updating = True @@ -108,6 +107,7 @@ class UpdateManager(Hook): return self.update(onlyplugin=True) @Expose + @threaded def update(self, onlyplugin=False): """ check for updates """ data = self.server_response() -- cgit v1.2.3 From 2a79ebb957adf2ed610e6104fc00f7e51e835edc Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Sat, 5 Jul 2014 03:21:06 +0200 Subject: Cleaned ShareLinksBiz pattern + better if-check for RSDF plugin --- module/plugins/container/RSDF.py | 2 +- module/plugins/crypter/ShareLinksBiz.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/plugins/container/RSDF.py b/module/plugins/container/RSDF.py index f7d3f7377..41cdfccb7 100644 --- a/module/plugins/container/RSDF.py +++ b/module/plugins/container/RSDF.py @@ -39,7 +39,7 @@ class RSDF(Container): links = [] for link in data: - if link == '': + if not link: continue link = base64.b64decode(link) link = obj.decrypt(link) diff --git a/module/plugins/crypter/ShareLinksBiz.py b/module/plugins/crypter/ShareLinksBiz.py index 816842216..7353f30a7 100644 --- a/module/plugins/crypter/ShareLinksBiz.py +++ b/module/plugins/crypter/ShareLinksBiz.py @@ -11,7 +11,7 @@ from module.plugins.Crypter import Crypter class ShareLinksBiz(Crypter): __name__ = "ShareLinksBiz" __type__ = "crypter" - __pattern__ = r'(?P<base>http://(?:www\.)?(share-links|s2l)\.biz)/(?P<id>_?[0-9a-z]+)(/.*)?' + __pattern__ = r'http://(?:www\.)?(share-links|s2l)\.biz/(?P<ID>_?\w+)' __version__ = "1.13" __description__ = """Share-Links.biz decrypter plugin""" __author_name__ = "fragonib" @@ -64,7 +64,7 @@ class ShareLinksBiz(Crypter): if 's2l.biz' in url: url = self.load(url, just_header=True)['location'] self.baseUrl = re.match(self.__pattern__, url).group(1) - self.fileId = re.match(self.__pattern__, url).group('id') + self.fileId = re.match(self.__pattern__, url).group('ID') self.package = pyfile.package() def isOnline(self): -- cgit v1.2.3 From 389e5bd208feb97f4faca9cfd4bc0f037efc32d9 Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Sat, 5 Jul 2014 16:31:44 +0200 Subject: [VeohCom] Auto quality detection --- module/plugins/hoster/VeohCom.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/module/plugins/hoster/VeohCom.py b/module/plugins/hoster/VeohCom.py index c1ebffb81..15d7a98b0 100644 --- a/module/plugins/hoster/VeohCom.py +++ b/module/plugins/hoster/VeohCom.py @@ -23,8 +23,8 @@ class VeohCom(SimpleHoster): __name__ = "VeohCom" __type__ = "hoster" __pattern__ = r'http://(?:www\.)?veoh\.com/(tv/)?(watch|videos)/(?P<ID>v\w+)' - __version__ = "0.1" - __config__ = [("quality", "Low;High", "Quality", "High")] + __version__ = "0.2" + __config__ = [("quality", "Low;High;Auto", "Quality", "Auto")] __description__ = """Veoh.com hoster plugin""" __author_name__ = "Walter Purcaro" __author_mail__ = "vuolter@gmail.com" @@ -41,16 +41,22 @@ class VeohCom(SimpleHoster): self.chunkLimit = -1 def handleFree(self): - q = self.getConfig("quality") - pattern = r'"fullPreviewHash%sPath":"(.+?)"' % q - found = re.search(pattern, self.html) - if found: - self.pyfile.name += ".mp4" - link = found.group(1).replace("\\", "") - self.logDebug("Download link: " + link) - self.download(link) + quality = self.getConfig("quality") + if quality == "Auto": + quality = ("High", "Low") + for q in quality: + pattern = r'"fullPreviewHash%sPath":"(.+?)"' % q + found = re.search(pattern, self.html) + if found: + self.pyfile.name += ".mp4" + link = found.group(1).replace("\\", "") + self.logDebug("Download link: " + link) + self.download(link) + return + else: + self.logInfo("No %s quality video found" % q.upper()) else: - self.fail("No %s quality video found" % q.lower()) + self.fail("No video found!") getInfo = create_getInfo(VeohCom) -- cgit v1.2.3 From d016326ea5611c5dd9c0d5fcf2145fc202a45a9a Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Sat, 5 Jul 2014 16:33:12 +0200 Subject: New hoster: VimeoCom --- module/plugins/crypter/DownloadVimeoCom.py | 30 ----------- module/plugins/hoster/VimeoCom.py | 82 ++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 30 deletions(-) delete mode 100644 module/plugins/crypter/DownloadVimeoCom.py create mode 100644 module/plugins/hoster/VimeoCom.py diff --git a/module/plugins/crypter/DownloadVimeoCom.py b/module/plugins/crypter/DownloadVimeoCom.py deleted file mode 100644 index 3e137bab1..000000000 --- a/module/plugins/crypter/DownloadVimeoCom.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import HTMLParser -from module.plugins.Crypter import Crypter - - -class DownloadVimeoCom(Crypter): - __name__ = 'DownloadVimeoCom' - __type__ = 'crypter' - __pattern__ = r'(?:http://vimeo\.com/\d*|http://smotri\.com/video/view/\?id=.*)' - __version__ = '0.1' - __description__ = """Vimeo.com decrypter plugin""" - __author_name__ = "4Christopher" - __author_mail__ = "4Christopher@gmx.de" - - BASE_URL = 'http://downloadvimeo.com' - - def decrypt(self, pyfile): - self.package = pyfile.package() - html = self.load('%s/generate?url=%s' % (self.BASE_URL, pyfile.url)) - h = HTMLParser.HTMLParser() - try: - f = re.search(r'cmd quality="(?P<quality>[^"]+?)">\s*?(?P<URL>[^<]*?)</cmd>', html) - except: - self.logDebug('Failed to find the URL') - else: - url = h.unescape(f.group('URL')) - self.logDebug('Quality: %s, URL: %s' % (f.group('quality'), url)) - self.packages.append((self.package.name, [url], self.package.folder)) diff --git a/module/plugins/hoster/VimeoCom.py b/module/plugins/hoster/VimeoCom.py new file mode 100644 index 000000000..3d93d3d03 --- /dev/null +++ b/module/plugins/hoster/VimeoCom.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +############################################################################ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +############################################################################ + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class VimeoCom(SimpleHoster): + __name__ = "VimeoCom" + __type__ = "hoster" + __pattern__ = r'https?://(?:www\.)?(player\.)?vimeo\.com/(video/)?(?P<ID>\d+)' + __version__ = "0.01" + __config__ = [("quality", "Lowest;Mobile;SD;HD;Highest", "Quality", "Highest"), + ("original", "bool", "Try to download the original file first", True)] + __description__ = """Vimeo.com hoster plugin""" + __author_name__ = "Walter Purcaro" + __author_mail__ = "vuolter@gmail.com" + + FILE_NAME_PATTERN = r'<title>(?P<N>.+) on Vimeo<' + FILE_OFFLINE_PATTERN = r'class="exception_header"' + TEMP_OFFLINE_PATTERN = r'Please try again in a few minutes.<' + + FILE_URL_REPLACEMENTS = [(__pattern__, r'https://www.vimeo.com/\g<ID>')] + + SH_COOKIES = [(".vimeo.com", "language", "en")] + + + def setup(self): + self.resumeDownload = self.multiDL = True + self.chunkLimit = -1 + + def handleFree(self): + if self.js and 'class="btn iconify_down_b"' in self.html: + html = self.js.eval(self.load(self.pyfile.url, get={'action': "download"}, decode=True)) + pattern = r'href="(?P<URL>http://vimeo\.com.+?)".*?\>(?P<QL>.+?) ' + else: + id = re.match(self.__pattern__, self.pyfile.url).group("ID") + html = self.load("https://player.vimeo.com/video/" + id) + pattern = r'"(?P<QL>\w+)":{"profile".*?"(?P<URL>http://pdl\.vimeocdn\.com.+?)"' + + link = dict([(l.group('QL').lower(), l.group('URL')) for l in re.finditer(pattern, html)]) + + if self.getConfig("original"): + if "original" in link: + self.download(link[q]) + return + else: + self.logInfo("Original file not downloadable") + + quality = self.getConfig("quality") + if quality == "Highest": + qlevel = ("hd", "sd", "mobile") + elif quality == "Lowest": + qlevel = ("mobile", "sd", "hd") + else: + qlevel = quality.lower() + + for q in qlevel: + if q in link: + self.download(link[q]) + return + else: + self.logInfo("No %s quality video found" % q.upper()) + else: + self.fail("No video found!") + + +getInfo = create_getInfo(VimeoCom) -- cgit v1.2.3 From 3ebfa9a6348983437712e9cea22504d38f633588 Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Sat, 5 Jul 2014 16:34:09 +0200 Subject: [PutlockerCom] Renamed to FiredriveCom --- module/plugins/hoster/FiredriveCom.py | 51 +++++++++++++++++++++++++++++++++ module/plugins/hoster/PutlockerCom.py | 53 ----------------------------------- 2 files changed, 51 insertions(+), 53 deletions(-) create mode 100644 module/plugins/hoster/FiredriveCom.py delete mode 100644 module/plugins/hoster/PutlockerCom.py diff --git a/module/plugins/hoster/FiredriveCom.py b/module/plugins/hoster/FiredriveCom.py new file mode 100644 index 000000000..9c150bc11 --- /dev/null +++ b/module/plugins/hoster/FiredriveCom.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +############################################################################### +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +############################################################################### + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class FiredriveCom(SimpleHoster): + __name__ = "FiredriveCom" + __type__ = "hoster" + __pattern__ = r'https?://(?:www\.)?(firedrive|putlocker)\.com/(mobile/)?(file|embed)/(?P<ID>\w+)' + __version__ = "0.01" + __description__ = """Firedrive.com hoster plugin""" + __author_name__ = "Walter Purcaro" + __author_mail__ = "vuolter@gmail.com" + + FILE_NAME_PATTERN = r'<b>Name:</b> (?P<N>.+) <br>' + FILE_SIZE_PATTERN = r'<b>Size:</b> (?P<S>[\d.]+) (?P<U>[a-zA-Z]+) <br>' + FILE_OFFLINE_PATTERN = r'class="sad_face_image"' + + FILE_URL_REPLACEMENTS = [(__pattern__, r'http://www.firedrive.com/file/\g<ID>')] + + def setup(self): + self.multiDL = self.resumeDownload = True + self.chunkLimit = -1 + + def handleFree(self): + link = self._getLink() + self.logDebug("Direct link: " + link) + self.download(link, disposition=True) + + def _getLink(self): + self.html = self.load(self.pyfile.url, post={"confirm": re.search(r'name="confirm" value="(.*)"', self.html).group(1)}) + return re.search(r'<a href="(https?://dl\.firedrive\.com/.*?)"', self.html).group(1) + + +getInfo = create_getInfo(FiredriveCom) diff --git a/module/plugins/hoster/PutlockerCom.py b/module/plugins/hoster/PutlockerCom.py deleted file mode 100644 index a453eaf62..000000000 --- a/module/plugins/hoster/PutlockerCom.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################### -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# @author: Walter Purcaro -############################################################################### - -import re - -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo - - -class PutlockerCom(SimpleHoster): - __name__ = "PutlockerCom" - __type__ = "hoster" - __pattern__ = r'https?://(?:www\.)?(firedrive|putlocker)\.com/(mobile/)?(file|embed)/(?P<ID>\w+)' - __version__ = "0.33" - __description__ = """Firedrive.com hoster plugin""" - __author_name__ = "Walter Purcaro" - __author_mail__ = "vuolter@gmail.com" - - FILE_NAME_PATTERN = r'<b>Name:</b> (?P<N>.+) <br>' - FILE_SIZE_PATTERN = r'<b>Size:</b> (?P<S>[\d.]+) (?P<U>[a-zA-Z]+) <br>' - FILE_OFFLINE_PATTERN = r"<div class=\"sad_face_image\">" - - FILE_URL_REPLACEMENTS = [(__pattern__, r'http://www.firedrive.com/file/\g<ID>')] - - def setup(self): - self.multiDL = self.resumeDownload = True - self.chunkLimit = -1 - - def handleFree(self): - link = self._getLink() - self.logDebug("Direct link: " + link) - self.download(link, disposition=True) - - def _getLink(self): - self.html = self.load(self.pyfile.url, post={"confirm": re.search(r'name="confirm" value="(.*)"', self.html).group(1)}) - return re.search(r'<a href="(https?://dl\.firedrive\.com/.*?)"', self.html).group(1) - - -getInfo = create_getInfo(PutlockerCom) -- cgit v1.2.3 From cc0a1b0fc0de0690e0b98cfd9416fb3a61f5ea05 Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Sat, 5 Jul 2014 16:34:57 +0200 Subject: [DailymotionCom] Default quality changed to "Highest" --- module/plugins/hoster/DailymotionCom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/plugins/hoster/DailymotionCom.py b/module/plugins/hoster/DailymotionCom.py index 17e1ecf92..c377a0635 100644 --- a/module/plugins/hoster/DailymotionCom.py +++ b/module/plugins/hoster/DailymotionCom.py @@ -60,7 +60,7 @@ class DailymotionCom(Hoster): __type__ = "hoster" __pattern__ = r'https?://(?:www\.)?dailymotion\.com/.*?video/(?P<ID>[\w^_]+)' __version__ = "0.2" - __config__ = [("quality", "Lowest;LD 144p;LD 240p;SD 384p;HQ 480p;HD 720p;HD 1080p;Highest", "Quality", "HD 720p")] + __config__ = [("quality", "Lowest;LD 144p;LD 240p;SD 384p;HQ 480p;HD 720p;HD 1080p;Highest", "Quality", "Highest")] __description__ = """Dailymotion.com hoster plugin""" __author_name__ = "Walter Purcaro" __author_mail__ = "vuolter@gmail.com" -- cgit v1.2.3 From 15362ebceaee1eb66920d4822d2faa947151e74a Mon Sep 17 00:00:00 2001 From: Walter Purcaro <vuolter@gmail.com> Date: Sat, 5 Jul 2014 16:42:24 +0200 Subject: [SimpleCrypter] Better inline docs + support for offline & temp.offline check --- module/plugins/crypter/EasybytezComFolder.py | 4 +-- module/plugins/crypter/TusfilesNetFolder.py | 4 +-- module/plugins/internal/SimpleCrypter.py | 40 ++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/module/plugins/crypter/EasybytezComFolder.py b/module/plugins/crypter/EasybytezComFolder.py index b4a6284fc..7a8ee5424 100644 --- a/module/plugins/crypter/EasybytezComFolder.py +++ b/module/plugins/crypter/EasybytezComFolder.py @@ -21,12 +21,12 @@ class EasybytezComFolder(SimpleCrypter): __name__ = "EasybytezComFolder" __type__ = "crypter" __pattern__ = r'http://(?:www\.)?easybytez\.com/users/(?P<ID>\d+/\d+)' - __version__ = "0.05" + __version__ = "0.06" __description__ = """Easybytez.com decrypter plugin""" __author_name__ = "stickell" __author_mail__ = "l.stickell@yahoo.it" - FILE_URL_REPLACEMENTS = [(__pattern__, r"http://www.easybytez.com/users/\g<ID>?per_page=10000")] + URL_REPLACEMENTS = [(__pattern__, r"http://www.easybytez.com/users/\g<ID>?per_page=10000")] LINK_PATTERN = r'<td><a href="(http://www\.easybytez\.com/\w+)" target="_blank">.+(?:</a>)?</td>' TITLE_PATTERN = r'<Title>Files of \d+: (?P<title>.+) folder' diff --git a/module/plugins/crypter/TusfilesNetFolder.py b/module/plugins/crypter/TusfilesNetFolder.py index 0bc770f99..5ee32379d 100644 --- a/module/plugins/crypter/TusfilesNetFolder.py +++ b/module/plugins/crypter/TusfilesNetFolder.py @@ -27,7 +27,7 @@ class TusfilesNetFolder(SimpleCrypter): __name__ = "TusfilesNetFolder" __type__ = "crypter" __pattern__ = r'https?://(?:www\.)?tusfiles\.net/go/(?P\w+)/?' - __version__ = "0.01" + __version__ = "0.02" __description__ = """Tusfiles.net folder decrypter plugin""" __author_name__ = ("Walter Purcaro", "stickell") __author_mail__ = ("vuolter@gmail.com", "l.stickell@yahoo.it") @@ -36,7 +36,7 @@ class TusfilesNetFolder(SimpleCrypter): TITLE_PATTERN = r'.*?\: (?P<title>.+) folder' PAGES_PATTERN = r'>\((?P\d+) \w+\)<' - FILE_URL_REPLACEMENTS = [(__pattern__, r'https://www.tusfiles.net/go/\g/')] + URL_REPLACEMENTS = [(__pattern__, r'https://www.tusfiles.net/go/\g/')] def loadPage(self, page_n): return self.load(urljoin(self.pyfile.url, str(page_n)), decode=True) diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index 268efee86..2c024d738 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -26,34 +26,44 @@ from module.plugins.internal.SimpleHoster import replace_patterns, set_cookies class SimpleCrypter(Crypter): __name__ = "SimpleCrypter" - __version__ = "0.08" + __version__ = "0.09" __pattern__ = None __type__ = "crypter" __description__ = """Simple decrypter plugin""" __author_name__ = ("stickell", "zoidberg") __author_mail__ = ("l.stickell@yahoo.it", "zoidberg@mujmail.cz") + """ - These patterns should be defined by each crypter: + Following patterns should be defined by each crypter: + + LINK_PATTERN: group(1) must be a download link or a regex to catch more links + example: LINK_PATTERN = r'