diff options
Diffstat (limited to 'pyload')
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__] | 
