diff options
Diffstat (limited to 'pyload/plugin')
53 files changed, 655 insertions, 183 deletions
diff --git a/pyload/plugin/Addon.py b/pyload/plugin/Addon.py index dc07a2513..14b5ee2a5 100644 --- a/pyload/plugin/Addon.py +++ b/pyload/plugin/Addon.py @@ -76,11 +76,9 @@ class Addon(Base): self.setup() - # self.initPeriodical() - def initPeriodical(self, delay=0, threaded=False): - self.cb = self.core.scheduler.addJob(delay, self._periodical, args=[threaded], threaded=threaded) + self.cb = self.core.scheduler.addJob(max(0, delay), self._periodical, args=[threaded], threaded=threaded) def _periodical(self, threaded): diff --git a/pyload/plugin/Captcha.py b/pyload/plugin/Captcha.py index 383eedac8..d7a506979 100644 --- a/pyload/plugin/Captcha.py +++ b/pyload/plugin/Captcha.py @@ -19,7 +19,7 @@ class Captcha(Base): def __init__(self, plugin): self.plugin = plugin self.key = None #: last key detected - super(CaptchaService, self).__init__(plugin.core) + super(Captcha, self).__init__(plugin.core) def detect_key(self, html=None): diff --git a/pyload/plugin/account/Keep2ShareCc.py b/pyload/plugin/account/Keep2ShareCc.py index 7ed15dc62..a3cc2c40d 100644 --- a/pyload/plugin/account/Keep2ShareCc.py +++ b/pyload/plugin/account/Keep2ShareCc.py @@ -1,32 +1,32 @@ # -*- coding: utf-8 -*- import re - -from time import gmtime, mktime, strptime +import time from pyload.plugin.Account import Account -class Keep2shareCc(Account): - __name__ = "Keep2shareCc" +class Keep2ShareCc(Account): + __name__ = "Keep2ShareCc" __type__ = "account" - __version__ = "0.02" + __version__ = "0.05" - __description__ = """Keep2share.cc account plugin""" + __description__ = """Keep2Share.cc account plugin""" __license__ = "GPLv3" - __authors__ = [("aeronaut", "aeronaut@pianoguy.de")] + __authors__ = [("aeronaut", "aeronaut@pianoguy.de"), + ("Walter Purcaro", "vuolter@gmail.com")] - VALID_UNTIL_PATTERN = r'Premium expires: <b>(.+?)</b>' - TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):<b><a href="/user/statistic.html">(.+?)</a>' + VALID_UNTIL_PATTERN = r'Premium expires:\s*<b>(.+?)<' + TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):\s*<b><a href="/user/statistic.html">(.+?)<' LOGIN_FAIL_PATTERN = r'Please fix the following input errors' def loadAccountInfo(self, user, req): validuntil = None - trafficleft = None - premium = None + trafficleft = -1 + premium = False html = req.load("http://keep2share.cc/site/profile.html", decode=True) @@ -35,26 +35,26 @@ class Keep2shareCc(Account): expiredate = m.group(1).strip() self.logDebug("Expire date: " + expiredate) - try: - validuntil = mktime(strptime(expiredate, "%Y.%m.%d")) + if expiredate == "LifeTime": + premium = True + validuntil = -1 + else: + try: + validuntil = time.mktime(time.strptime(expiredate, "%Y.%m.%d")) - except Exception, e: - self.logError(e) + except Exception, e: + self.logError(e) - else: - if validuntil > mktime(gmtime()): - premium = True else: - premium = False - validuntil = None + premium = True if validuntil > time.mktime(time.gmtime()) else False - m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: - try: - trafficleft = self.parseTraffic(m.group(1)) + m = re.search(self.TRAFFIC_LEFT_PATTERN, html) + if m: + try: + trafficleft = self.parseTraffic(m.group(1)) - except Exception, e: - self.logError(e) + except Exception, e: + self.logError(e) return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium} @@ -63,7 +63,11 @@ class Keep2shareCc(Account): req.cj.setCookie("keep2share.cc", "lang", "en") html = req.load("http://keep2share.cc/login.html", - post={'LoginForm[username]': user, 'LoginForm[password]': data['password']}) + post={'LoginForm[username]' : user, + 'LoginForm[password]' : data['password'], + 'LoginForm[rememberMe]': 1, + 'yt0' : ""}, + decode=True) if re.search(self.LOGIN_FAIL_PATTERN, html): self.wrongPassword() diff --git a/pyload/plugin/account/MegaRapidoNet.py b/pyload/plugin/account/MegaRapidoNet.py new file mode 100644 index 000000000..22979a09a --- /dev/null +++ b/pyload/plugin/account/MegaRapidoNet.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +import re +import time + +from pyload.plugin.Account import Account + + +class MegaRapidoNet(Account): + __name__ = "MegaRapidoNet" + __type__ = "account" + __version__ = "0.02" + + __description__ = """MegaRapido.net account plugin""" + __license__ = "GPLv3" + __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] + + + VALID_UNTIL_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?[\'"]premium_index[\'"][^>]*>[^<]*?<[^>]*?b[^>]*>\s*?TEMPO\s*?PREMIUM[^<]*<[^>]*?/b[^>]*>\s*?(\d*)[^\d]*?DIAS[^\d]*?(\d*)[^\d]*?HORAS[^\d]*?(\d*)[^\d]*?MINUTOS[^\d]*?(\d*)[^\d]*?SEGUNDOS' + USER_ID_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']checkbox_compartilhar["\'][^>]*>[^<]*<\s*?input[^>]*?name\s*?=\s*?["\']usar["\'][^>]*>[^<]*<\s*?input[^>]*?name\s*?=\s*?["\']user["\'][^>]*?value\s*?=\s*?["\'](.*?)\s*?["\']' + + + def loadAccountInfo(self, user, req): + validuntil = None + trafficleft = None + premium = False + + html = req.load("http://megarapido.net/gerador", decode=True) + + validuntil = re.search(self.VALID_UNTIL_PATTERN, html) + if validuntil: + #hier weitermachen!!! (müssen umbedingt die zeit richtig machen damit! (sollte aber möglich)) + validuntil = time.time() + int(validuntil.group(1)) * 24 * 3600 + int(validuntil.group(2)) * 3600 + int(validuntil.group(3)) * 60 + int(validuntil.group(4)) + trafficleft = -1 + premium = True + + return {'validuntil' : validuntil, + 'trafficleft': trafficleft, + 'premium' : premium} + + + def login(self, user, data, req): + req.load("http://megarapido.net/login") + req.load("http://megarapido.net/painel_user/ajax/logar.php", + post={'login': user, 'senha': data['password']}, + decode=True) + + html = req.load("http://megarapido.net/gerador") + + if "sair" not in html.lower(): + self.wrongPassword() + else: + m = re.search(self.USER_ID_PATTERN, html) + if m: + data['uid'] = m.group(1) + else: + self.fail("Couldn't find the user ID") diff --git a/pyload/plugin/addon/AndroidPhoneNotify.py b/pyload/plugin/addon/AndroidPhoneNotify.py index 53af8aa1c..d3b390e6e 100644 --- a/pyload/plugin/addon/AndroidPhoneNotify.py +++ b/pyload/plugin/addon/AndroidPhoneNotify.py @@ -28,11 +28,9 @@ class AndroidPhoneNotify(Addon): event_list = ["allDownloadsProcessed", "plugin_updated"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.last_notify = 0 self.notifications = 0 @@ -44,7 +42,7 @@ class AndroidPhoneNotify(Addon): self.notify(_("Plugins updated"), str(type_plugins)) - def coreExiting(self): + def exit(self): if not self.getConfig('notifyexit'): return diff --git a/pyload/plugin/addon/AntiVirus.py b/pyload/plugin/addon/AntiVirus.py new file mode 100644 index 000000000..619893735 --- /dev/null +++ b/pyload/plugin/addon/AntiVirus.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +import os +import shutil +import subprocess + +from pyload.plugin.Addon import Addon, Expose, threaded +from pyload.utils import fs_encode, fs_join + + +class AntiVirus(Addon): + __name__ = "AntiVirus" + __type__ = "addon" + __version__ = "0.05" + + #@TODO: add trash option (use Send2Trash lib) + __config__ = [("action" , "Antivirus default;Delete;Quarantine", "Manage infected files" , "Antivirus default"), + ("quardir" , "folder" , "Quarantine folder" , "" ), + ("scanfailed", "bool" , "Scan incompleted files (failed downloads)", False ), + ("cmdfile" , "file" , "Antivirus executable" , "" ), + ("cmdargs" , "str" , "Scan options" , "" ), + ("ignore-err", "bool" , "Ignore scan errors" , False )] + + __description__ = """Scan downloaded files with antivirus program""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + @Expose + @threaded + def scan(self, pyfile, thread): + file = fs_encode(pyfile.plugin.lastDownload) + filename = os.path.basename(pyfile.plugin.lastDownload) + cmdfile = fs_encode(self.getConfig('cmdfile')) + cmdargs = fs_encode(self.getConfig('cmdargs').strip()) + + if not os.path.isfile(file) or not os.path.isfile(cmdfile): + return + + thread.addActive(pyfile) + pyfile.setCustomStatus(_("virus scanning")) + + try: + p = subprocess.Popen([cmdfile, cmdargs, file], bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + out, err = map(str.strip, p.communicate()) + + if out: + self.logInfo(filename, out) + + if err: + self.logWarning(filename, err) + if not self.getConfig('ignore-err'): + self.logDebug("Delete/Quarantine task is aborted") + return + + if p.returncode: + pyfile.error = _("infected file") + action = self.getConfig('action') + try: + if action == "Delete": + os.remove(file) + + elif action == "Quarantine": + pyfile.setCustomStatus(_("file moving")) + pyfile.setProgress(0) + shutil.move(file, self.getConfig('quardir')) + + except (IOError, shutil.Error), e: + self.logError(filename, action + " action failed!", e) + + elif not out and not err: + self.logDebug(filename, "No infected file found") + + finally: + pyfile.setProgress(100) + thread.finishFile(pyfile) + + + def downloadFinished(self, pyfile): + return self.scan(pyfile) + + + def downloadFailed(self, pyfile): + #: Check if pyfile is still "failed", + # maybe might has been restarted in meantime + if pyfile.status == 8 and self.getConfig('scanfailed'): + return self.scan(pyfile) diff --git a/pyload/plugin/addon/Checksum.py b/pyload/plugin/addon/Checksum.py index 7ba5d7ab6..4b1380506 100644 --- a/pyload/plugin/addon/Checksum.py +++ b/pyload/plugin/addon/Checksum.py @@ -56,7 +56,6 @@ class Checksum(Addon): ("stickell" , "l.stickell@yahoo.it")] - interval = 0 #@TODO: Remove in 0.4.10 methods = {'sfv' : 'crc32', 'crc' : 'crc32', 'hash': 'md5'} @@ -72,7 +71,6 @@ class Checksum(Addon): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.algorithms = sorted( getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse=True) diff --git a/pyload/plugin/addon/ClickAndLoad.py b/pyload/plugin/addon/ClickAndLoad.py index 63647e30a..df8d09806 100644 --- a/pyload/plugin/addon/ClickAndLoad.py +++ b/pyload/plugin/addon/ClickAndLoad.py @@ -30,15 +30,12 @@ class ClickAndLoad(Addon): ("port" , "int" , "Port" , 9666), ("extern" , "bool", "Listen on the public network interface", True)] - __description__ = """Click'n'Load hook plugin""" + __description__ = """Click'n'Load addon plugin""" __license__ = "GPLv3" __authors__ = [("RaNaN" , "RaNaN@pyload.de" ), ("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def activate(self): if not self.config['webinterface']['activated']: return diff --git a/pyload/plugin/addon/DeleteFinished.py b/pyload/plugin/addon/DeleteFinished.py index aad05891e..989271fa8 100644 --- a/pyload/plugin/addon/DeleteFinished.py +++ b/pyload/plugin/addon/DeleteFinished.py @@ -25,7 +25,6 @@ class DeleteFinished(Addon): ## overwritten methods ## def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.interval = self.MIN_CHECK_INTERVAL @@ -56,6 +55,7 @@ class DeleteFinished(Addon): # self.pluginConfigChanged(self.__name__, 'interval', interval) self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60 * 60) self.addEvent('packageFinished', self.wakeup) + self.initPeriodical() ## own methods ## diff --git a/pyload/plugin/addon/DownloadScheduler.py b/pyload/plugin/addon/DownloadScheduler.py index ff65a478d..de961cc1f 100644 --- a/pyload/plugin/addon/DownloadScheduler.py +++ b/pyload/plugin/addon/DownloadScheduler.py @@ -20,14 +20,6 @@ class DownloadScheduler(Addon): ("stickell", "l.stickell@yahoo.it")] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.cb = None # callback to scheduler job; will be by removed hookmanager when hook unloaded - - def activate(self): self.updateSchedule() diff --git a/pyload/plugin/addon/ExternalScripts.py b/pyload/plugin/addon/ExternalScripts.py index 139be1299..502a6dc7b 100644 --- a/pyload/plugin/addon/ExternalScripts.py +++ b/pyload/plugin/addon/ExternalScripts.py @@ -28,7 +28,6 @@ class ExternalScripts(Addon): "all_archives_extracted", "all_archives_processed", "allDownloadsFinished" , "allDownloadsProcessed" , "packageDeleted"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): @@ -65,7 +64,7 @@ class ExternalScripts(Addon): return for filename in os.listdir(dir): - file = save_join(dir, filename) + file = fs_join(dir, filename) if not os.path.isfile(file): continue @@ -102,7 +101,7 @@ class ExternalScripts(Addon): self.callScript(script) - def coreExiting(self): + def exit(self): for script in self.scripts['pyload_restart' if self.core.do_restart else 'pyload_stop']: self.callScript(script) @@ -125,23 +124,23 @@ class ExternalScripts(Addon): def downloadFailed(self, pyfile): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) + download_folder = fs_join(self.config['general']['download_folder'], pyfile.package().folder) else: download_folder = self.config['general']['download_folder'] for script in self.scripts['download_failed']: - file = save_join(download_folder, pyfile.name) + file = fs_join(download_folder, pyfile.name) self.callScript(script, pyfile.id, pyfile.name, pyfile.pluginname, pyfile.url, file) def downloadFinished(self, pyfile): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) + download_folder = fs_join(self.config['general']['download_folder'], pyfile.package().folder) else: download_folder = self.config['general']['download_folder'] for script in self.scripts['download_finished']: - file = save_join(download_folder, pyfile.name) + file = fs_join(download_folder, pyfile.name) self.callScript(script, pyfile.id, pyfile.name, pyfile.pluginname, pyfile.url, file) @@ -157,7 +156,7 @@ class ExternalScripts(Addon): def packageFinished(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] @@ -169,7 +168,7 @@ class ExternalScripts(Addon): pack = self.core.api.getPackageInfo(pid) if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pack.folder) else: download_folder = self.config['general']['download_folder'] @@ -179,7 +178,7 @@ class ExternalScripts(Addon): def package_extract_failed(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] @@ -189,7 +188,7 @@ class ExternalScripts(Addon): def package_extracted(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] diff --git a/pyload/plugin/addon/ExtractArchive.py b/pyload/plugin/addon/ExtractArchive.py index 3c71e7e1a..419ca609e 100644 --- a/pyload/plugin/addon/ExtractArchive.py +++ b/pyload/plugin/addon/ExtractArchive.py @@ -137,8 +137,6 @@ class ExtractArchive(Addon): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.queue = ArchiveQueue(self, "Queue") self.failed = ArchiveQueue(self, "Failed") diff --git a/pyload/plugin/addon/IRCInterface.py b/pyload/plugin/addon/IRCInterface.py index 9038ce993..6d85a5681 100644 --- a/pyload/plugin/addon/IRCInterface.py +++ b/pyload/plugin/addon/IRCInterface.py @@ -37,9 +37,6 @@ class IRCInterface(Thread, Addon): __authors__ = [("Jeix", "Jeix@hasnomail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def __init__(self, core, manager): Thread.__init__(self) Addon.__init__(self, core, manager) diff --git a/pyload/plugin/addon/JustPremium.py b/pyload/plugin/addon/JustPremium.py index e69bc24f6..b878f302d 100644 --- a/pyload/plugin/addon/JustPremium.py +++ b/pyload/plugin/addon/JustPremium.py @@ -21,11 +21,6 @@ class JustPremium(Addon): event_list = ["linksAdded"] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 def linksAdded(self, links, pid): diff --git a/pyload/plugin/addon/MergeFiles.py b/pyload/plugin/addon/MergeFiles.py index 374604d82..e0233af10 100644 --- a/pyload/plugin/addon/MergeFiles.py +++ b/pyload/plugin/addon/MergeFiles.py @@ -23,15 +23,9 @@ class MergeFiles(Addon): __authors__ = [("and9000", "me@has-no-mail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - BUFFER_SIZE = 4096 - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - @threaded def packageFinished(self, pack): files = {} diff --git a/pyload/plugin/addon/MultiHome.py b/pyload/plugin/addon/MultiHome.py index 0cebf35b8..03974d6c6 100644 --- a/pyload/plugin/addon/MultiHome.py +++ b/pyload/plugin/addon/MultiHome.py @@ -17,11 +17,7 @@ class MultiHome(Addon): __authors__ = [("mkaay", "mkaay@mkaay.de")] - interval = 0 #@TODO: Remove in 0.4.10 - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.register = {} self.interfaces = [] diff --git a/pyload/plugin/addon/RestartFailed.py b/pyload/plugin/addon/RestartFailed.py index e34424a8c..c568bfb0a 100644 --- a/pyload/plugin/addon/RestartFailed.py +++ b/pyload/plugin/addon/RestartFailed.py @@ -40,3 +40,4 @@ class RestartFailed(Addon): def activate(self): # self.pluginConfigChanged(self.__name__, "interval", self.getConfig('interval')) self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60) + self.initPeriodical() diff --git a/pyload/plugin/addon/RestartSlow.py b/pyload/plugin/addon/RestartSlow.py index cd503518d..34416e79a 100644 --- a/pyload/plugin/addon/RestartSlow.py +++ b/pyload/plugin/addon/RestartSlow.py @@ -22,11 +22,12 @@ class RestartSlow(Addon): event_list = ["downloadStarts"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): self.info = {'chunk': {}} + + def periodical(self): if not self.pyfile.plugin.req.dl: return @@ -36,8 +37,8 @@ class RestartSlow(Addon): limit = 5 else: type = "premium" if self.pyfile.plugin.premium else "free" - time = max(30, self.getConfig("%s_time" % type) * 60) - limit = max(5, self.getConfig("%s_limit" % type) * 1024) + time = max(30, self.getConfig('%s_time' % type) * 60) + limit = max(5, self.getConfig('%s_limit' % type) * 1024) chunks = [chunk for chunk in self.pyfile.plugin.req.dl.chunks \ if chunk.id not in self.info['chunk'] or self.info['chunk'][chunk.id] is not (time, limit)] diff --git a/pyload/plugin/addon/SkipRev.py b/pyload/plugin/addon/SkipRev.py index 157b55bbd..1c42ddfd8 100644 --- a/pyload/plugin/addon/SkipRev.py +++ b/pyload/plugin/addon/SkipRev.py @@ -6,14 +6,14 @@ from types import MethodType from urllib import unquote from urlparse import urlparse -from module.PyFile import PyFile -from module.plugins.Hook import Hook -from module.plugins.Plugin import SkipDownload +from pyload.datatype.File import PyFile +from pyload.plugin.Addon import Addon +from pyload.plugin.Plugin import SkipDownload -class SkipRev(Hook): +class SkipRev(Addon): __name__ = "SkipRev" - __type__ = "hook" + __type__ = "addon" __version__ = "0.29" __config__ = [("mode" , "Auto;Manual", "Choose recovery archives to skip" , "Auto"), @@ -24,13 +24,6 @@ class SkipRev(Hook): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - @staticmethod def _setup(self): self.pyfile.plugin._setup() diff --git a/pyload/plugin/addon/UnSkipOnFail.py b/pyload/plugin/addon/UnSkipOnFail.py index 55de85082..f81066daa 100644 --- a/pyload/plugin/addon/UnSkipOnFail.py +++ b/pyload/plugin/addon/UnSkipOnFail.py @@ -16,9 +16,6 @@ class UnSkipOnFail(Addon): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def downloadFailed(self, pyfile): #: Check if pyfile is still "failed", # maybe might has been restarted in meantime diff --git a/pyload/plugin/addon/UpdateManager.py b/pyload/plugin/addon/UpdateManager.py index 643b5c2d1..cd8dc9a03 100644 --- a/pyload/plugin/addon/UpdateManager.py +++ b/pyload/plugin/addon/UpdateManager.py @@ -9,9 +9,9 @@ import time from operator import itemgetter -from module.network.RequestFactory import getURL -from module.plugins.Hook import Expose, Hook, threaded -from module.utils import save_join +from pyload.network.RequestFactory import getURL +from pyload.plugin.Addon import Expose, Addon, threaded +from pyload.utils import fs_join # Case-sensitive os.path.exists @@ -26,9 +26,9 @@ def exists(path): return False -class UpdateManager(Hook): +class UpdateManager(Addon): __name__ = "UpdateManager" - __type__ = "hook" + __type__ = "addon" __version__ = "0.50" __config__ = [("activated" , "bool", "Activated" , True ), @@ -43,14 +43,11 @@ class UpdateManager(Hook): __license__ = "GPLv3" __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - interval = 0 - SERVER_URL = "http://updatemanager.pyload.org" MIN_CHECK_INTERVAL = 3 * 60 * 60 #: 3 hours - def coreReady(self): + def activate(self): if self.checkonstart: self.update() @@ -189,7 +186,7 @@ class UpdateManager(Hook): # Protect UpdateManager from self-removing try: - type_plugins.remove(("hook", "UpdateManager")) + type_plugins.remove(("addon", "UpdateManager")) except ValueError: pass @@ -242,7 +239,7 @@ class UpdateManager(Hook): m = VERSION.search(content) if m and m.group(2) == version: - with open(save_join("userplugins", prefix, filename), "wb") as f: + with open(fs_join("userplugins", prefix, filename), "wb") as f: f.write(content) updated.append((prefix, name)) @@ -288,12 +285,12 @@ class UpdateManager(Hook): rootplugins = os.path.join(pypath, "module", "plugins") for dir in ("userplugins", rootplugins): - py_filename = save_join(dir, type, name + ".py") + py_filename = fs_join(dir, type, name + ".py") pyc_filename = py_filename + "c" - if type == "hook": + if type == "addon": try: - self.manager.deactivateHook(name) + self.manager.deactivateAddon(name) except Exception, e: self.logDebug(e) diff --git a/pyload/plugin/addon/WindowsPhoneNotify.py b/pyload/plugin/addon/WindowsPhoneNotify.py index e61057f9f..341e682b2 100644 --- a/pyload/plugin/addon/WindowsPhoneNotify.py +++ b/pyload/plugin/addon/WindowsPhoneNotify.py @@ -3,12 +3,12 @@ import httplib import time -from module.plugins.Hook import Hook, Expose +from pyload.plugin.Addon import Addon, Expose -class WindowsPhoneNotify(Hook): +class WindowsPhoneNotify(Addon): __name__ = "WindowsPhoneNotify" - __type__ = "hook" + __type__ = "addon" __version__ = "0.09" __config__ = [("id" , "str" , "Push ID" , "" ), @@ -29,11 +29,9 @@ class WindowsPhoneNotify(Hook): event_list = ["allDownloadsProcessed", "plugin_updated"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.last_notify = 0 self.notifications = 0 @@ -45,7 +43,7 @@ class WindowsPhoneNotify(Hook): self.notify(_("Plugins updated"), str(type_plugins)) - def coreExiting(self): + def exit(self): if not self.getConfig('notifyexit'): return diff --git a/pyload/plugin/captcha/AdYouLike.py b/pyload/plugin/captcha/AdYouLike.py index 0ff1a799b..d656acb09 100644 --- a/pyload/plugin/captcha/AdYouLike.py +++ b/pyload/plugin/captcha/AdYouLike.py @@ -8,6 +8,7 @@ from pyload.utils import json_loads class AdYouLike(Captcha): __name__ = "AdYouLike" + __type__ = "captcha" __version__ = "0.05" __description__ = """AdYouLike captcha service plugin""" diff --git a/pyload/plugin/captcha/AdsCaptcha.py b/pyload/plugin/captcha/AdsCaptcha.py index 75852e36d..5b23247c0 100644 --- a/pyload/plugin/captcha/AdsCaptcha.py +++ b/pyload/plugin/captcha/AdsCaptcha.py @@ -9,6 +9,7 @@ from pyload.plugin.Captcha import Captcha class AdsCaptcha(Captcha): __name__ = "AdsCaptcha" + __type__ = "captcha" __version__ = "0.08" __description__ = """AdsCaptcha captcha service plugin""" diff --git a/pyload/plugin/captcha/ReCaptcha.py b/pyload/plugin/captcha/ReCaptcha.py index 295491bd8..62b82d1d5 100644 --- a/pyload/plugin/captcha/ReCaptcha.py +++ b/pyload/plugin/captcha/ReCaptcha.py @@ -12,6 +12,7 @@ from pyload.plugin.Captcha import Captcha class ReCaptcha(Captcha): __name__ = "ReCaptcha" + __type__ = "captcha" __version__ = "0.14" __description__ = """ReCaptcha captcha service plugin""" diff --git a/pyload/plugin/captcha/SolveMedia.py b/pyload/plugin/captcha/SolveMedia.py index af45101b4..7f421f490 100644 --- a/pyload/plugin/captcha/SolveMedia.py +++ b/pyload/plugin/captcha/SolveMedia.py @@ -7,6 +7,7 @@ from pyload.plugin.Captcha import Captcha class SolveMedia(Captcha): __name__ = "SolveMedia" + __type__ = "captcha" __version__ = "0.12" __description__ = """SolveMedia captcha service plugin""" diff --git a/pyload/plugin/crypter/DailymotionComFolder.py b/pyload/plugin/crypter/DailymotionComFolder.py new file mode 100644 index 000000000..3c5000515 --- /dev/null +++ b/pyload/plugin/crypter/DailymotionComFolder.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import fs_join + + +class DailymotionComFolder(Crypter): + __name__ = "DailymotionComFolder" + __type__ = "crypter" + __version__ = "0.01" + + __pattern__ = r'https?://(?:www\.)?dailymotion\.com/((playlists/)?(?P<TYPE>playlist|user)/)?(?P<ID>[\w^_]+)(?(TYPE)|#)' + __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), + ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] + + __description__ = """Dailymotion.com channel & playlist decrypter""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + def api_response(self, ref, req=None): + url = urljoin("https://api.dailymotion.com/", ref) + html = self.load(url, get=req) + return json_loads(html) + + + def getPlaylistInfo(self, id): + ref = "playlist/" + id + req = {"fields": "name,owner.screenname"} + playlist = self.api_response(ref, req) + + if "error" in playlist: + return + + name = playlist['name'] + owner = playlist['owner.screenname'] + return name, owner + + + def _getPlaylists(self, user_id, page=1): + ref = "user/%s/playlists" % user_id + req = {"fields": "id", "page": page, "limit": 100} + user = self.api_response(ref, req) + + if "error" in user: + return + + for playlist in user['list']: + yield playlist['id'] + + if user['has_more']: + for item in self._getPlaylists(user_id, page + 1): + yield item + + + def getPlaylists(self, user_id): + return [(id,) + self.getPlaylistInfo(id) for id in self._getPlaylists(user_id)] + + + def _getVideos(self, id, page=1): + ref = "playlist/%s/videos" % id + req = {"fields": "url", "page": page, "limit": 100} + playlist = self.api_response(ref, req) + + if "error" in playlist: + return + + for video in playlist['list']: + yield video['url'] + + if playlist['has_more']: + for item in self._getVideos(id, page + 1): + yield item + + + def getVideos(self, playlist_id): + return list(self._getVideos(playlist_id))[::-1] + + + def decrypt(self, pyfile): + m = re.match(self.__pattern__, pyfile.url) + m_id = m.group('ID') + m_type = m.group('TYPE') + + if m_type == "playlist": + self.logDebug("Url recognized as Playlist") + p_info = self.getPlaylistInfo(m_id) + playlists = [(m_id,) + p_info] if p_info else None + else: + self.logDebug("Url recognized as Channel") + playlists = self.getPlaylists(m_id) + self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), m_id)) + + if not playlists: + self.fail(_("No playlist available")) + + for p_id, p_name, p_owner in playlists: + p_videos = self.getVideos(p_id) + p_folder = fs_join(self.config['general']['download_folder'], p_owner, p_name) + self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) + self.packages.append((p_name, p_videos, p_folder)) #: folder is NOT recognized by pyload 0.4.9! diff --git a/pyload/plugin/crypter/FilecryptCc.py b/pyload/plugin/crypter/FilecryptCc.py index c052573e1..1d8388dcd 100644 --- a/pyload/plugin/crypter/FilecryptCc.py +++ b/pyload/plugin/crypter/FilecryptCc.py @@ -10,7 +10,7 @@ from Crypto.Cipher import AES from urlparse import urljoin from pyload.plugin.Crypter import Crypter -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha class FilecryptCc(Crypter): diff --git a/pyload/plugin/crypter/YoutubeComFolder.py b/pyload/plugin/crypter/YoutubeComFolder.py new file mode 100644 index 000000000..e42615af0 --- /dev/null +++ b/pyload/plugin/crypter/YoutubeComFolder.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import fs_join + + +class YoutubeComFolder(Crypter): + __name__ = "YoutubeComFolder" + __type__ = "crypter" + __version__ = "1.01" + + __pattern__ = r'https?://(?:www\.|m\.)?youtube\.com/(?P<TYPE>user|playlist|view_play_list)(/|.*?[?&](?:list|p)=)(?P<ID>[\w-]+)' + __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True ), + ("subfolder_per_pack", "bool", "Create a subfolder for each package", True ), + ("likes" , "bool", "Grab user (channel) liked videos" , False), + ("favorites" , "bool", "Grab user (channel) favorite videos", False), + ("uploads" , "bool", "Grab channel unplaylisted videos" , True )] + + __description__ = """Youtube.com channel & playlist decrypter plugin""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + API_KEY = "AIzaSyCKnWLNlkX-L4oD1aEzqqhRw1zczeD6_k0" + + + def api_response(self, ref, req): + req.update({"key": self.API_KEY}) + url = urljoin("https://www.googleapis.com/youtube/v3/", ref) + html = self.load(url, get=req) + return json_loads(html) + + + def getChannel(self, user): + channels = self.api_response("channels", {"part": "id,snippet,contentDetails", "forUsername": user, "maxResults": "50"}) + if channels['items']: + channel = channels['items'][0] + return {"id": channel['id'], + "title": channel['snippet']['title'], + "relatedPlaylists": channel['contentDetails']['relatedPlaylists'], + "user": user} # One lone channel for user? + + + def getPlaylist(self, p_id): + playlists = self.api_response("playlists", {"part": "snippet", "id": p_id}) + if playlists['items']: + playlist = playlists['items'][0] + return {"id": p_id, + "title": playlist['snippet']['title'], + "channelId": playlist['snippet']['channelId'], + "channelTitle": playlist['snippet']['channelTitle']} + + + def _getPlaylists(self, id, token=None): + req = {"part": "id", "maxResults": "50", "channelId": id} + if token: + req.update({"pageToken": token}) + + playlists = self.api_response("playlists", req) + + for playlist in playlists['items']: + yield playlist['id'] + + if "nextPageToken" in playlists: + for item in self._getPlaylists(id, playlists['nextPageToken']): + yield item + + + def getPlaylists(self, ch_id): + return map(self.getPlaylist, self._getPlaylists(ch_id)) + + + def _getVideosId(self, id, token=None): + req = {"part": "contentDetails", "maxResults": "50", "playlistId": id} + if token: + req.update({"pageToken": token}) + + playlist = self.api_response("playlistItems", req) + + for item in playlist['items']: + yield item['contentDetails']['videoId'] + + if "nextPageToken" in playlist: + for item in self._getVideosId(id, playlist['nextPageToken']): + yield item + + + def getVideosId(self, p_id): + return list(self._getVideosId(p_id)) + + + def decrypt(self, pyfile): + m = re.match(self.__pattern__, pyfile.url) + m_id = m.group('ID') + m_type = m.group('TYPE') + + if m_type == "user": + self.logDebug("Url recognized as Channel") + user = m_id + channel = self.getChannel(user) + + if channel: + playlists = self.getPlaylists(channel['id']) + self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), channel['title'])) + + relatedplaylist = {p_name: self.getPlaylist(p_id) for p_name, p_id in channel['relatedPlaylists'].iteritems()} + self.logDebug("Channel's related playlists found = %s" % relatedplaylist.keys()) + + relatedplaylist['uploads']['title'] = "Unplaylisted videos" + relatedplaylist['uploads']['checkDups'] = True #: checkDups flag + + for p_name, p_data in relatedplaylist.iteritems(): + if self.getConfig(p_name): + p_data['title'] += " of " + user + playlists.append(p_data) + else: + playlists = [] + else: + self.logDebug("Url recognized as Playlist") + playlists = [self.getPlaylist(m_id)] + + if not playlists: + self.fail(_("No playlist available")) + + addedvideos = [] + urlize = lambda x: "https://www.youtube.com/watch?v=" + x + for p in playlists: + p_name = p['title'] + p_videos = self.getVideosId(p['id']) + p_folder = fs_join(self.config['general']['download_folder'], p['channelTitle'], p_name) + self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) + + if not p_videos: + continue + elif "checkDups" in p: + p_urls = [urlize(v_id) for v_id in p_videos if v_id not in addedvideos] + self.logDebug("%s video\s available on playlist \"%s\" after duplicates cleanup" % (len(p_urls), p_name)) + else: + p_urls = map(urlize, p_videos) + + self.packages.append((p_name, p_urls, p_folder)) #: folder is NOT recognized by pyload 0.4.9! + + addedvideos.extend(p_videos) diff --git a/pyload/plugin/extractor/UnRar.py b/pyload/plugin/extractor/UnRar.py index 5b9052bff..3bc4f3464 100644 --- a/pyload/plugin/extractor/UnRar.py +++ b/pyload/plugin/extractor/UnRar.py @@ -198,13 +198,13 @@ class UnRar(Extractor): if not self.fullpath and self.VERSION.startswith('5'): # NOTE: Unrar 5 always list full path for f in fs_decode(out).splitlines(): - f = save_join(self.out, os.path.basename(f.strip())) + f = fs_join(self.out, os.path.basename(f.strip())) if os.path.isfile(f): - result.add(save_join(self.out, os.path.basename(f))) + result.add(fs_join(self.out, os.path.basename(f))) else: for f in fs_decode(out).splitlines(): f = f.strip() - result.add(save_join(self.out, f)) + result.add(fs_join(self.out, f)) return list(result) diff --git a/pyload/plugin/hook/BypassCaptcha.py b/pyload/plugin/hook/BypassCaptcha.py index 786f5dff3..4579d17c5 100644 --- a/pyload/plugin/hook/BypassCaptcha.py +++ b/pyload/plugin/hook/BypassCaptcha.py @@ -40,8 +40,6 @@ class BypassCaptcha(Hook): ("zoidberg" , "zoidberg@mujmail.cz" )] - interval = 0 #@TODO: Remove in 0.4.10 - PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32" SUBMIT_URL = "http://bypasscaptcha.com/upload.php" diff --git a/pyload/plugin/hook/Captcha9Kw.py b/pyload/plugin/hook/Captcha9Kw.py index 38cbb5a21..012266739 100644 --- a/pyload/plugin/hook/Captcha9Kw.py +++ b/pyload/plugin/hook/Captcha9Kw.py @@ -36,8 +36,6 @@ class Captcha9kw(Hook): ("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.9kw.eu/index.cgi" diff --git a/pyload/plugin/hook/CaptchaBrotherhood.py b/pyload/plugin/hook/CaptchaBrotherhood.py index fbf2e2e29..3cbdb27d7 100644 --- a/pyload/plugin/hook/CaptchaBrotherhood.py +++ b/pyload/plugin/hook/CaptchaBrotherhood.py @@ -50,11 +50,14 @@ class CaptchaBrotherhood(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.captchabrotherhood.com/" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def getCredits(self): res = getURL(self.API_URL + "askCredits.aspx", get={"username": self.getConfig('username'), "password": self.getConfig('passkey')}) diff --git a/pyload/plugin/hook/DeathByCaptcha.py b/pyload/plugin/hook/DeathByCaptcha.py index 41d4d300b..0f0e66ea2 100644 --- a/pyload/plugin/hook/DeathByCaptcha.py +++ b/pyload/plugin/hook/DeathByCaptcha.py @@ -63,11 +63,14 @@ class DeathByCaptcha(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://api.dbcapi.me/api/" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def api_response(self, api="captcha", post=False, multipart=False): req = getRequest() req.c.setopt(HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.core.version]) diff --git a/pyload/plugin/hook/ExpertDecoders.py b/pyload/plugin/hook/ExpertDecoders.py index f1096b8ed..0f86baa17 100644 --- a/pyload/plugin/hook/ExpertDecoders.py +++ b/pyload/plugin/hook/ExpertDecoders.py @@ -25,11 +25,14 @@ class ExpertDecoders(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.fasttypers.org/imagepost.ashx" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def getCredits(self): res = getURL(self.API_URL, post={"key": self.getConfig('passkey'), "action": "balance"}) diff --git a/pyload/plugin/hook/ImageTyperz.py b/pyload/plugin/hook/ImageTyperz.py index a556b109a..a7c3389c1 100644 --- a/pyload/plugin/hook/ImageTyperz.py +++ b/pyload/plugin/hook/ImageTyperz.py @@ -44,8 +44,6 @@ class ImageTyperz(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - SUBMIT_URL = "http://captchatypers.com/Forms/UploadFileAndGetTextNEW.ashx" RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx" GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx" diff --git a/pyload/plugin/hook/MegaRapidoNet.py b/pyload/plugin/hook/MegaRapidoNet.py new file mode 100644 index 000000000..2f660c939 --- /dev/null +++ b/pyload/plugin/hook/MegaRapidoNet.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.MultiHook import MultiHook + + +class MegaRapidoNet(MultiHook): + __name__ = "MegaRapidoNet" + __type__ = "hook" + __version__ = "0.02" + + __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"), + ("pluginlist" , "str" , "Plugin list (comma separated)", "" ), + ("reload" , "bool" , "Reload plugin list" , True ), + ("reloadinterval", "int" , "Reload interval in hours" , 12 )] + + __description__ = """MegaRapido.net hook plugin""" + __license__ = "GPLv3" + __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] + + + def getHosters(self): + hosters = {'1fichier' : [],#leave it there are so many possible addresses? + '1st-files' : ['1st-files.com'], + '2shared' : ['2shared.com'], + '4shared' : ['4shared.com', '4shared-china.com'], + 'asfile' : ['http://asfile.com/'], + 'bitshare' : ['bitshare.com'], + 'brupload' : ['brupload.net'], + 'crocko' : ['crocko.com','easy-share.com'], + 'dailymotion' : ['dailymotion.com'], + 'depfile' : ['depfile.com'], + 'depositfiles': ['depositfiles.com', 'dfiles.eu'], + 'dizzcloud' : ['dizzcloud.com'], + 'dl.dropbox' : [], + 'extabit' : ['extabit.com'], + 'extmatrix' : ['extmatrix.com'], + 'facebook' : [], + 'file4go' : ['file4go.com'], + 'filecloud' : ['filecloud.io','ifile.it','mihd.net'], + 'filefactory' : ['filefactory.com'], + 'fileom' : ['fileom.com'], + 'fileparadox' : ['fileparadox.in'], + 'filepost' : ['filepost.com', 'fp.io'], + 'filerio' : ['filerio.in','filerio.com','filekeen.com'], + 'filesflash' : ['filesflash.com'], + 'firedrive' : ['firedrive.com', 'putlocker.com'], + 'flashx' : [], + 'freakshare' : ['freakshare.net', 'freakshare.com'], + 'gigasize' : ['gigasize.com'], + 'hipfile' : ['hipfile.com'], + 'junocloud' : ['junocloud.me'], + 'letitbit' : ['letitbit.net','shareflare.net'], + 'mediafire' : ['mediafire.com'], + 'mega' : ['mega.co.nz'], + 'megashares' : ['megashares.com'], + 'metacafe' : ['metacafe.com'], + 'netload' : ['netload.in'], + 'oboom' : ['oboom.com'], + 'rapidgator' : ['rapidgator.net'], + 'rapidshare' : ['rapidshare.com'], + 'rarefile' : ['rarefile.net'], + 'ryushare' : ['ryushare.com'], + 'sendspace' : ['sendspace.com'], + 'turbobit' : ['turbobit.net', 'unextfiles.com'], + 'uploadable' : ['uploadable.ch'], + 'uploadbaz' : ['uploadbaz.com'], + 'uploaded' : ['uploaded.to', 'uploaded.net', 'ul.to'], + 'uploadhero' : ['uploadhero.com'], + 'uploading' : ['uploading.com'], + 'uptobox' : ['uptobox.com'], + 'xvideos' : ['xvideos.com'], + 'youtube' : ['youtube.com']} + + hoster_list = [] + + for item in hosters.itervalues(): + hoster_list.extend(item) + + return hoster_list diff --git a/pyload/plugin/hook/XFileSharingPro.py b/pyload/plugin/hook/XFileSharingPro.py index 9599c8180..9560cbd08 100644 --- a/pyload/plugin/hook/XFileSharingPro.py +++ b/pyload/plugin/hook/XFileSharingPro.py @@ -23,7 +23,6 @@ class XFileSharingPro(Hook): # event_list = ["pluginConfigChanged"] - interval = 0 #@TODO: Remove in 0.4.10 regexp = {'hoster' : (r'https?://(?:www\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:embed-)?\w+'), 'crypter': (r'https?://(?:www\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:user|folder)s?/\w+', @@ -54,7 +53,7 @@ class XFileSharingPro(Hook): use_builtin_list = self.getConfig('use_builtin_list') for type in ("hoster", "crypter"): - every_plugin = not self.getConfig("use_%s_list" % type) + every_plugin = not self.getConfig('use_%s_list' % type) if every_plugin: self.logInfo(_("Handling any %s I can!") % type) diff --git a/pyload/plugin/hoster/ExtabitCom.py b/pyload/plugin/hoster/ExtabitCom.py index dfd37b0a0..c0fa782fa 100644 --- a/pyload/plugin/hoster/ExtabitCom.py +++ b/pyload/plugin/hoster/ExtabitCom.py @@ -4,7 +4,7 @@ import re from pyload.utils import json_loads -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight diff --git a/pyload/plugin/hoster/FileserveCom.py b/pyload/plugin/hoster/FileserveCom.py index 18322fa00..eb80889b1 100644 --- a/pyload/plugin/hoster/FileserveCom.py +++ b/pyload/plugin/hoster/FileserveCom.py @@ -6,7 +6,7 @@ from pyload.utils import json_loads from pyload.network.RequestFactory import getURL from pyload.plugin.Hoster import Hoster from pyload.plugin.Plugin import chunks -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import secondsToMidnight from pyload.utils import parseFileSize diff --git a/pyload/plugin/hoster/FreakshareCom.py b/pyload/plugin/hoster/FreakshareCom.py index 331d7f2a3..53eb10e55 100644 --- a/pyload/plugin/hoster/FreakshareCom.py +++ b/pyload/plugin/hoster/FreakshareCom.py @@ -3,7 +3,7 @@ import re from pyload.plugin.Hoster import Hoster -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import secondsToMidnight diff --git a/pyload/plugin/hoster/Keep2ShareCc.py b/pyload/plugin/hoster/Keep2ShareCc.py index 3c2b6c570..67af087b7 100644 --- a/pyload/plugin/hoster/Keep2ShareCc.py +++ b/pyload/plugin/hoster/Keep2ShareCc.py @@ -4,7 +4,7 @@ import re from urlparse import urljoin -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/LetitbitNet.py b/pyload/plugin/hoster/LetitbitNet.py index 01767cabf..545cde27c 100644 --- a/pyload/plugin/hoster/LetitbitNet.py +++ b/pyload/plugin/hoster/LetitbitNet.py @@ -12,7 +12,7 @@ from urlparse import urljoin from pyload.utils import json_loads, json_dumps from pyload.network.RequestFactory import getURL -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight diff --git a/pyload/plugin/hoster/MediafireCom.py b/pyload/plugin/hoster/MediafireCom.py index 3b39e2420..8b05a95ec 100644 --- a/pyload/plugin/hoster/MediafireCom.py +++ b/pyload/plugin/hoster/MediafireCom.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from module.plugins.internal.CaptchaService import SolveMedia -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from pyload.plugin.captcha.SolveMedia import SolveMedia +from pyload.plugin.internal.SimpleHoster import SimpleHoster class MediafireCom(SimpleHoster): @@ -58,6 +58,3 @@ class MediafireCom(SimpleHoster): self.fail(_("Incorrect password")) return super(MediafireCom, self).handleFree(pyfile) - - -getInfo = create_getInfo(MediafireCom) diff --git a/pyload/plugin/hoster/MegaRapidoNet.py b/pyload/plugin/hoster/MegaRapidoNet.py new file mode 100644 index 000000000..938b201d5 --- /dev/null +++ b/pyload/plugin/hoster/MegaRapidoNet.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +from random import randint + +from pyload.plugin.internal.MultiHoster import MultiHoster + + +def random_with_N_digits(n): + rand = "0." + not_zero = 0 + for i in range(1,n+1): + r = randint(0,9) + if(r > 0): + not_zero += 1 + rand += str(r) + + if not_zero > 0: + return rand + else: + return random_with_N_digits(n) + + +class MegaRapidoNet(MultiHoster): + __name__ = "MegaRapidoNet" + __type__ = "hoster" + __version__ = "0.02" + + __pattern__ = r'http://(?:www\.)?\w+\.megarapido\.net/\?file=\w+' + __config__ = [("use_premium", "bool", "Use premium account if available", True)] + + __description__ = """MegaRapido.net multi-hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] + + + LINK_PREMIUM_PATTERN = r'<\s*?a[^>]*?title\s*?=\s*?["\'][^"\']*?download["\'][^>]*?href=["\']([^"\']*)' + + ERROR_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']?alert-message error[^>]*>([^<]*)' + + + def handlePremium(self, pyfile): + self.html = self.load("http://megarapido.net/gerar.php", + post={'rand' :random_with_N_digits(16), + 'urllist' : pyfile.url, + 'links' : pyfile.url, + 'exibir' : "normal", + 'usar' : "premium", + 'user' : self.account.getAccountInfo(self.user).get('sid', None), + 'autoreset': ""}) + + if "desloga e loga novamente para gerar seus links" in self.html.lower(): + self.error("You have logged in at another place") + + return super(MegaRapidoNet, self).handlePremium(pyfile) diff --git a/pyload/plugin/hoster/NitroflareCom.py b/pyload/plugin/hoster/NitroflareCom.py index dfe33e59c..d2bcd871d 100644 --- a/pyload/plugin/hoster/NitroflareCom.py +++ b/pyload/plugin/hoster/NitroflareCom.py @@ -2,7 +2,7 @@ import re -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/RapidgatorNet.py b/pyload/plugin/hoster/RapidgatorNet.py index 2af0001df..98a8b97c9 100644 --- a/pyload/plugin/hoster/RapidgatorNet.py +++ b/pyload/plugin/hoster/RapidgatorNet.py @@ -6,8 +6,10 @@ from pycurl import HTTPHEADER from pyload.utils import json_loads from pyload.network.HTTPRequest import BadHeader -from pyload.plugin.internal.CaptchaService import AdsCaptcha, ReCaptcha, SolveMedia -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, secondsToMidnight +from pyload.plugin.captcha.AdsCaptcha import AdsCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha +from pyload.plugin.captcha.SolveMedia import SolveMedia +from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight class RapidgatorNet(SimpleHoster): diff --git a/pyload/plugin/hoster/SoundcloudCom.py b/pyload/plugin/hoster/SoundcloudCom.py index 31aa7ba3c..524fb6e13 100644 --- a/pyload/plugin/hoster/SoundcloudCom.py +++ b/pyload/plugin/hoster/SoundcloudCom.py @@ -2,8 +2,8 @@ import re -from module.plugin.internal.SimpleHoster import SimpleHoster -from module.common.json_layer import json_loads +from pyload.plugin.internal.SimpleHoster import SimpleHoster +from pyload.utils import json_loads class SoundcloudCom(SimpleHoster): @@ -51,6 +51,3 @@ class SoundcloudCom(SimpleHoster): if http_streams: stream_name, self.link = http_streams[0 if self.getConfig('quality') == "Higher" else -1] pyfile.name += '.' + stream_name.split('_')[1].lower() - - -getInfo = create_getInfo(SoundcloudCom) diff --git a/pyload/plugin/hoster/UploadedTo.py b/pyload/plugin/hoster/UploadedTo.py index 165b29c7a..207817122 100644 --- a/pyload/plugin/hoster/UploadedTo.py +++ b/pyload/plugin/hoster/UploadedTo.py @@ -4,7 +4,7 @@ import re import time from pyload.network.RequestFactory import getURL -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/ZippyshareCom.py b/pyload/plugin/hoster/ZippyshareCom.py index 784eccb68..9b1d432cc 100644 --- a/pyload/plugin/hoster/ZippyshareCom.py +++ b/pyload/plugin/hoster/ZippyshareCom.py @@ -4,7 +4,7 @@ import re from BeautifulSoup import BeautifulSoup -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/internal/BasePlugin.py b/pyload/plugin/internal/BasePlugin.py index ed4da72a1..0b6e8f102 100644 --- a/pyload/plugin/internal/BasePlugin.py +++ b/pyload/plugin/internal/BasePlugin.py @@ -6,7 +6,7 @@ from urllib import unquote from urlparse import urljoin, urlparse from pyload.network.HTTPRequest import BadHeader -from pyload.plugin.internal.SimpleHoster import create_getInfo, getFileURL +from pyload.plugin.internal.SimpleHoster import getFileURL from pyload.plugin.Hoster import Hoster @@ -99,6 +99,3 @@ class BasePlugin(Hoster): self.logWarning("Check result: " + errmsg, "Waiting 1 minute and retry") self.retry(3, 60, errmsg) - - -getInfo = create_getInfo(BasePlugin) diff --git a/pyload/plugin/internal/MultiHook.py b/pyload/plugin/internal/MultiHook.py index d43956691..ab96d30ca 100644 --- a/pyload/plugin/internal/MultiHook.py +++ b/pyload/plugin/internal/MultiHook.py @@ -54,8 +54,6 @@ class MultiHook(Hook): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.plugins = [] self.supported = [] self.new_supported = [] @@ -82,7 +80,7 @@ class MultiHook(Hook): self.pluginclass = getattr(self.pluginmodule, self.__name__) - def _loadAccount(self): + def loadAccount(self): self.account = self.core.accountManager.getAccountPlugin(self.pluginname) if self.account and not self.account.canUse(): @@ -94,7 +92,7 @@ class MultiHook(Hook): def activate(self): - self._loadAccount() + self.initPeriodical(threaded=True) def getURL(self, *args, **kwargs): #@TODO: Remove in 0.4.10 @@ -137,9 +135,9 @@ class MultiHook(Hook): return list() try: - configmode = self.getConfig("pluginmode", 'all') + configmode = self.getConfig('pluginmode', 'all') if configmode in ("listed", "unlisted"): - pluginlist = self.getConfig("pluginlist", '').replace('|', ',').replace(';', ',').split(',') + pluginlist = self.getConfig('pluginlist', '').replace('|', ',').replace(';', ',').split(',') configset = self._pluginSet(pluginlist) if configmode == "listed": @@ -183,24 +181,12 @@ class MultiHook(Hook): raise NotImplementedError - #: Threaded _periodical, remove in 0.4.10 and use built-in flag for that - def _periodical(self): - try: - if self.isActivated(): - self.periodical() - - except Exception, e: - self.core.log.error(_("Error executing hooks: %s") % str(e)) - if self.core.debug: - print_exc() - - self.cb = self.core.scheduler.addJob(self.interval, self._periodical) - - def periodical(self): """reload plugin list periodically""" - if self.getConfig("reload", True): - self.interval = max(self.getConfig("reloadinterval", 12) * 60 * 60, self.MIN_RELOAD_INTERVAL) + self.loadAccount() + + if self.getConfig('reload', True): + self.interval = max(self.getConfig('reloadinterval', 12) * 60 * 60, self.MIN_RELOAD_INTERVAL) else: self.core.scheduler.removeJob(self.cb) self.cb = None diff --git a/pyload/plugin/internal/MultiHoster.py b/pyload/plugin/internal/MultiHoster.py index 036570805..e9bb483da 100644 --- a/pyload/plugin/internal/MultiHoster.py +++ b/pyload/plugin/internal/MultiHoster.py @@ -85,7 +85,7 @@ class MultiHoster(SimpleHoster): self.logWarning(_("Premium download failed")) self.retryFree() - elif self.getConfig("revertfailed", True) \ + elif self.getConfig('revertfailed', True) \ and "new_module" in self.core.pluginManager.hosterPlugins[self.__name__]: hdict = self.core.pluginManager.hosterPlugins[self.__name__] |