Beispiel #1
0
    def deactivate(self):
        """
        Remove override for all plugins.
        """
        self.log_info(_("Reverting back to default hosters"))

        try:
            get_hook_manager().removeEvent("plugin_updated",
                                           self.plugins_updated)

        except ValueError:
            pass

        self.periodical.stop()

        self.fail_count = 0

        if self.supported:
            self.log_debug("Unload: %s" % ", ".join(self.supported))
            for plugin in self.supported:
                self.unload_plugin(plugin)

        #: Reset pattern
        hdict = get_plugin_manager().plugins[self.plugintype][self.classname]

        hdict['pattern'] = getattr(self.pluginclass, "__pattern__",
                                   r'^unmatchable$')
        hdict['re'] = re.compile(hdict['pattern'])
Beispiel #2
0
    def deletePackage(self, id):
        """delete package and all contained links"""

        p = self.getPackage(id)
        if not p:
            if id in self.packageCache: del self.packageCache[id]
            return

        oldorder = p.order
        queue = p.queue

        e = RemoveEvent("pack", id, "collector" if not p.queue else "queue")

        pyfiles = self.cache.values()

        for pyfile in pyfiles:
            if pyfile.packageid == id:
                pyfile.abortDownload()
                pyfile.release()

        self.db.deletePackage(p)
        get_pull_manager().addEvent(e)
        get_hook_manager().dispatchEvent("packageDeleted", id)

        if id in self.packageCache:
            del self.packageCache[id]

        packs = self.packageCache.values()
        for pack in packs:
            if pack.queue == queue and pack.order > oldorder:
                pack.order -= 1
                pack.notifyChange()
Beispiel #3
0
    def shutdown(self):
        self.log.info(_("shutting down..."))
        try:
            if self.config['webinterface']['activated'] and hasattr(self, "webserver"):
                self.webserver.quit()

            for thread in get_thread_manager().threads:
                thread.put("quit")
            pyfiles = self.files.cache.values()

            for pyfile in pyfiles:
                pyfile.abortDownload()

            get_hook_manager().coreExiting()

        except:
            if self.debug:
                print_exc()
            self.log.info(_("error while shutting down"))

        finally:
            self.files.syncSave()
            self.shuttedDown = True

        self.deletePidFile()
Beispiel #4
0
    def checkAllLinksFinished(self):
        """checks if all files are finished and dispatch event"""

        if not self.getQueueCount(True):
            get_hook_manager().dispatchEvent("allDownloadsFinished")
            self.core.log.debug("All downloads finished")
            return True

        return False
Beispiel #5
0
    def checkPackageFinished(self, pyfile):
        """ checks if package is finished and calls hookmanager """

        ids = self.db.getUnfinished(pyfile.packageid)
        if not ids or (pyfile.id in ids and len(ids) == 1):
            if not pyfile.package().setFinished:
                self.core.log.info(_("Package finished: %s") % pyfile.package().name)
                get_hook_manager().packageFinished(pyfile.package())
                pyfile.package().setFinished = True
Beispiel #6
0
    def addLinks(self, urls, package):
        """adds links"""

        get_hook_manager().dispatchEvent("linksAdded", urls, package)

        data = get_plugin_manager().parseUrls(urls)

        self.db.addLinks(data, package)
        get_thread_manager().createInfoThread(data, package)

        #@TODO change from reloadAll event to package update event
        get_pull_manager().addEvent(ReloadAllEvent("collector"))
Beispiel #7
0
    def checkAllLinksProcessed(self, fid):
        """checks if all files was processed and pyload would idle now, needs fid which will be ignored when counting"""

        # reset count so statistic will update (this is called when dl was processed)
        self.resetCount()

        if not self.db.processcount(1, fid):
            get_hook_manager().dispatchEvent("allDownloadsProcessed")
            self.core.log.debug("All downloads processed")
            return True

        return False
Beispiel #8
0
    def do_download(self, ip, port, file_name, file_size):
        if self.dl_started:
            return

        self.dl_started = True

        try:
            self.pyfile.name  = file_name
            self.req.filesize = file_size

            self.pyfile.setStatus("downloading")

            dl_folder = fsjoin(self.pyload.config.get('general', 'download_folder'),
                               self.pyfile.package().folder if self.pyload.config.get("general",
                                                                                      "folder_per_package") else "")
            if not exists(dl_folder):
                try:
                    os.makedirs(dl_folder)

                except Exception as e:
                    self.fail(e.message)

            self.set_permissions(dl_folder)

            self.check_duplicates()

            dl_file = fsjoin(dl_folder, self.pyfile.name)

            self.log_debug(_("DOWNLOAD XDCC '%s' from %s:%d") % (file_name, ip, port))

            get_hook_manager().dispatchEvent("download_start", self.pyfile, "%s:%s" % (ip, port), dl_file)

            newname = self.req.download(ip, port, dl_file, progressNotify=self.pyfile.setProgress, resume=self.xdcc_send_resume)
            if newname and newname != dl_file:
                self.log_info(_("%(name)s saved as %(newname)s") % {'name': self.pyfile.name, 'newname': newname})
                dl_file = newname

            self.last_download = dl_file

        except Abort:
            pass

        except Exception as e:
            bot  = self.info['pattern']['BOT']
            self.irc_client.xdcc_cancel_pack(bot)

            if not self.exc_info:
                self.exc_info = sys.exc_info()  #: pass the exception to the main thread

        self.dl_finished = True
Beispiel #9
0
    def getInfoByPlugin(self, plugin):
        """Returns information stored by a specific plugin.

        :param plugin: pluginname
        :return: dict of attr names mapped to value {"name": value}
        """
        return get_hook_manager().getInfo(plugin)
Beispiel #10
0
    def _finalize(self):
        pypack = self.pyfile.package()

        hook_manager = get_hook_manager()

        hook_manager.dispatchEvent("download_processed", self.pyfile)

        try:
            unfinished = any(
                fdata.get('status') in (3, 7)
                for fid, fdata in pypack.getChildren().items()
                if fid != self.pyfile.id)
            if unfinished:
                return

            hook_manager.dispatchEvent("package_processed", pypack)

            failed = any(
                fdata.get('status') in (1, 6, 8, 9, 14)
                for fid, fdata in pypack.getChildren().items())

            if not failed:
                return

            hook_manager.dispatchEvent("package_failed", pypack)

        finally:
            self.check_status()
Beispiel #11
0
    def hasService(self, plugin, func):
        """Checks wether a service is available.

        :param plugin:
        :param func:
        :return: bool
        """
        cont = get_hook_manager().methods
        return plugin in cont and func in cont[plugin]
Beispiel #12
0
    def getServices(self):
        """ A dict of available services, these can be defined by hook plugins.

        :return: dict with this style: {"plugin": {"method": "description"}}
        """
        data = {}
        for plugin, funcs in six.iteritems(get_hook_manager().methods):
            data[plugin] = funcs

        return data
Beispiel #13
0
    def setConfigValue(self, category, option, value, section="core"):
        """Set new config value.

        :param category:
        :param option:
        :param value: new config value
        :param section: 'plugin' or 'core
        """
        get_hook_manager().dispatchEvent("configChanged", category, option,
                                         value, section)

        if section == "core":
            self.core.config[category][option] = value

            if option in ("limit_speed",
                          "max_speed"):  # not so nice to update the limit
                get_request_factory().updateBucket()

        elif section == "plugin":
            self.core.config.setPlugin(category, option, value)
Beispiel #14
0
    def init_plugin(self):
        plugin_manager = get_plugin_manager()

        plugin, self.plugintype = plugin_manager.findPlugin(self.classname)

        if plugin:
            self.pluginmodule = plugin_manager.loadModule(
                self.plugintype, self.classname)
            self.pluginclass = plugin_manager.loadClass(
                self.plugintype, self.classname)

            get_hook_manager().addEvent("plugin_updated", self.plugins_updated)

            interval = self.config.get('mh_interval', 12) * 60 * 60
            self.periodical.start(interval, threaded=True, delay=2)

        else:
            self.log_warning(
                _("Multi-hoster feature will be deactivated due missing plugin reference"
                  ))
Beispiel #15
0
    def _check_download(self):
        self.log_info(_("Checking download..."))
        self.pyfile.setCustomStatus(_("checking"))

        if not self.last_download:
            if self.captcha.task:
                self.retry_captcha()
            else:
                self.error(_("No file downloaded"))

        elif self.scan_download(
            {'Empty file': re.compile(r'\A((.|)(\2|\s)*)\Z')}):
            if self.remove(self.last_download):
                self.last_download = ""
            self.error(_("Empty file"))

        else:
            get_hook_manager().dispatchEvent("download_check", self.pyfile)
            self.check_status()

        self.log_info(_("File is OK"))
Beispiel #16
0
    def _process(self, thread):
        """
        Handles important things to do before starting
        """
        self.thread = thread

        self._initialize()
        self._setup()

        #@TODO: Enable in 0.4.10
        # get_hook_manager().downloadPreparing(self.pyfile)
        # self.check_status()

        #@TODO: Remove in 0.4.10
        if self.__type__ == "crypter":
            get_hook_manager().downloadPreparing(self.pyfile)
            self.check_status()

        self.pyfile.setStatus("starting")

        self.log_info(_("Processing url: ") + self.pyfile.url)
        self.process(self.pyfile)
        self.check_status()
Beispiel #17
0
    def handleCaptcha(self, task):
        cli = self.core.isClientConnected()

        if cli:  #client connected -> should solve the captcha
            task.setWaiting(50)  #wait 50 sec for response

        for plugin in get_hook_manager().activePlugins():
            try:
                plugin.newCaptchaTask(task)
            except:
                if self.core.debug:
                    print_exc()

        if task.handler or cli:  #the captcha was handled
            self.tasks.append(task)
            return True

        task.error = _("No Client connected for captcha decrypting")

        return False
Beispiel #18
0
    def call(self, info):
        """Calls a service (a method in hook plugin).

        :param info: `ServiceCall`
        :return: result
        :raises: ServiceDoesNotExists, when its not available
        :raises: ServiceException, when a exception was raised
        """
        plugin = info.plugin
        func = info.func
        args = info.arguments
        parse = info.parseArguments

        if not self.hasService(plugin, func):
            raise ServiceDoesNotExists(plugin, func)

        try:
            ret = get_hook_manager().callRPC(plugin, func, args, parse)
            return str(ret)
        except Exception as e:
            raise ServiceException(e.message)
Beispiel #19
0
    def start(self, rpc=True, web=True):
        """ starts the fun :D """

        self.version = CURRENT_VERSION

        if not exists("pyload.conf"):
            from module.setup import Setup

            print("This is your first start, running configuration assistent now.")
            self.config = ConfigParser()
            s = Setup(pypath, self.config)
            res = False
            try:
                res = s.start()
            except SystemExit:
                pass
            except KeyboardInterrupt:
                print("\nSetup interrupted")
            except:
                res = False
                print_exc()
                print("Setup failed")
            if not res:
                remove("pyload.conf")

            exit()

        try: signal.signal(signal.SIGQUIT, self.quit)
        except: pass

        self.config = ConfigParser()

        gettext.setpaths([join(os.sep, "usr", "share", "pyload", "locale"), None])
        translation = gettext.translation("pyLoad", self.path("locale"),
                                          languages=[self.config['general']['language'],"en"],fallback=True)
        install_translation(translation)

        self.debug = self.doDebug or self.config['general']['debug_mode']
        self.remote &= self.config['remote']['activated']

        pid = self.isAlreadyRunning()
        if pid:
            print(_("pyLoad already running with pid %s") % pid)
            exit()

        if not IS_WINDOWS and self.config["general"]["renice"]:
            os.system("renice %d %d" % (self.config["general"]["renice"], os.getpid()))

        if self.config["permission"]["change_group"]:
            if not IS_WINDOWS:
                try:
                    from grp import getgrnam

                    group = getgrnam(self.config["permission"]["group"])
                    os.setgid(group[2])
                except Exception as e:
                    print(_("Failed changing group: %s") % e)

        if self.config["permission"]["change_user"]:
            if not IS_WINDOWS:
                try:
                    from pwd import getpwnam

                    user = getpwnam(self.config["permission"]["user"])
                    os.setuid(user[2])
                except Exception as e:
                    print(_("Failed changing user: %s") % e)

        self.check_file(
            self.config['log']['log_folder'],
            _("folder for logs"),
            is_folder=True,
        )

        if self.debug:
            self.init_logger(logging.DEBUG) # logging level
        else:
            self.init_logger(logging.INFO) # logging level

        sys.excepthook = exceptHook

        self.do_kill = False
        self.do_restart = False
        self.shuttedDown = False

        self.log.info(_("Starting") + " pyLoad %s" % CURRENT_VERSION)
        self.log.info(_("Using home directory: %s") % getcwd())

        self.writePidFile()

        #@TODO refractor

        remote.activated = self.remote
        self.log.debug("Remote activated: %s" % self.remote)

        self.check_install("Crypto", _("pycrypto to decode container files"))
        #img = self.check_install("Image", _("Python Image Libary (PIL) for captcha reading"))
        #self.check_install("pycurl", _("pycurl to download any files"), True, True)
        self.check_file("tmp", _("folder for temporary files"), is_folder=True)
        #tesser = self.check_install("tesseract", _("tesseract for captcha reading"), False) if not IS_WINDOWS else True

        self.captcha = True # checks seems to fail, althoug tesseract is available

        self.check_file(
            self.config['general']['download_folder'],
            _("folder for downloads"),
            is_folder=True,
        )

        if self.config['ssl']['activated']:
            self.check_install("OpenSSL", _("OpenSSL for secure connection"))

        self.setupDB()

        if self.deleteLinks:
            self.log.info(_("All links removed"))
            self.db.purgeLinks()

        set_request_factory(RequestFactory(self))

        self.lastClientConnected = 0

        # later imported because they would trigger api import, and remote value not set correctly
        from module import Api
        from module.HookManager import HookManager
        from module.ThreadManager import ThreadManager

        if Api.activated != self.remote:
            self.log.warning("Import error: API remote status not correct.")

        self.api = Api.Api(self)

        self.scheduler = Scheduler(self)

        #hell yeah, so many important managers :D
        set_plugin_manager(PluginManager(self))
        set_pull_manager(PullManager(self))
        set_thread_manager(ThreadManager(self))
        set_account_manager(AccountManager(self))
        set_captcha_manager(CaptchaManager(self))
        # HookManager sets itself as a singleton
        HookManager(self)
        set_remote_manager(RemoteManager(self))

        thread_manager = get_thread_manager()

        self.js = JsEngine()

        self.log.info(_("Downloadtime: %s") % self.api.isTimeDownload())

        if rpc:
            get_remote_manager().startBackends()

        if web:
            self.init_webserver()

        spaceLeft = freeSpace(self.config["general"]["download_folder"])

        self.log.info(_("Free space: %s") % formatSize(spaceLeft))

        self.config.save() #save so config files gets filled

        link_file = join(pypath, "links.txt")

        if exists(link_file):
            f = open(link_file, "rb")
            if f.read().strip():
                self.api.addPackage("links.txt", [link_file], 1)
            f.close()

        link_file = "links.txt"
        if exists(link_file):
            f = open(link_file, "rb")
            if f.read().strip():
                self.api.addPackage("links.txt", [link_file], 1)
            f.close()

        #self.scheduler.addJob(0, get_account_manager().getAccountInfos)
        self.log.info(_("Activating Accounts..."))
        get_account_manager().getAccountInfos()

        thread_manager.pause = False
        self.running = True

        self.log.info(_("Activating Plugins..."))
        get_hook_manager().coreReady()

        self.log.info(_("pyLoad is up and running"))

        #test api
#        from module.common.APIExerciser import startApiExerciser
#        startApiExerciser(self, 3)

        #some memory stats
#        from guppy import hpy
#        hp=hpy()
#        import objgraph
#        objgraph.show_most_common_types(limit=20)
#        import memdebug
#        memdebug.start(8002)

        locals().clear()

        while True:
            try:
                sleep(2)
            except IOError as e:
                if e.errno != 4:  # errno.EINTR
                    raise

            if self.do_restart:
                self.log.info(_("restarting pyLoad"))
                self.restart()

            if self.do_kill:
                self.shutdown()
                self.log.info(_("pyLoad quits"))
                self.removeLogger()
                _exit(0) #@TODO thrift blocks shutdown

            thread_manager.work()
            self.scheduler.work()
Beispiel #20
0
    def reactivate(self, refresh=False):
        reloading = self.info['data'].get('hosters') is not None

        if not self.info['login']['valid']:
            self.fail_count += 1
            if self.fail_count < 3:
                if reloading:
                    self.log_error(
                        _("Could not reload hoster list - invalid account, retry in 5 minutes"
                          ))

                else:
                    self.log_error(
                        _("Could not load hoster list - invalid account, retry in 5 minutes"
                          ))

                self.periodical.set_interval(5 * 60)

            else:
                if reloading:
                    self.log_error(
                        _("Could not reload hoster list - invalid account, deactivating"
                          ))

                else:
                    self.log_error(
                        _("Could not load hoster list - invalid account, deactivating"
                          ))

                self.deactivate()

            return

        if not self.logged:
            if not self.relogin():
                self.fail_count += 1
                if self.fail_count < 3:
                    if reloading:
                        self.log_error(
                            _("Could not reload hoster list - login failed, retry in 5 minutes"
                              ))

                    else:
                        self.log_error(
                            _("Could not load hoster list - login failed, retry in 5 minutes"
                              ))

                    self.periodical.set_interval(5 * 60)

                else:
                    if reloading:
                        self.log_error(
                            _("Could not reload hoster list - login failed, deactivating"
                              ))

                    else:
                        self.log_error(
                            _("Could not load hoster list - login failed, deactivating"
                              ))

                    self.deactivate()

                return

        #: Make sure we have one active hook
        hook_manager = get_hook_manager()
        try:
            hook_manager.removeEvent("plugin_updated", self.plugins_updated)

        except ValueError:
            pass

        hook_manager.addEvent("plugin_updated", self.plugins_updated)

        if refresh or not reloading:
            if not self.get_plugins(cached=False):
                self.fail_count += 1
                if self.fail_count < 3:
                    self.log_error(
                        _("Failed to load hoster list for user `%s`, retry in 5 minutes"
                          ) % self.user)
                    self.periodical.set_interval(5 * 60)

                else:
                    self.log_error(
                        _("Failed to load hoster list for user `%s`, deactivating"
                          ) % self.user)
                    self.deactivate()

                return

        if self.fail_count:
            self.fail_count = 0

            interval = self.config.get('mh_interval', 12) * 60 * 60
            self.periodical.set_interval(interval)

        self._override()
Beispiel #21
0
    def download(self,
                 url,
                 get={},
                 post={},
                 ref=True,
                 cookies=True,
                 disposition=False):
        """Downloads the content at url to download folder

        :param url:
        :param get:
        :param post:
        :param ref:
        :param cookies:
        :param disposition: if True and server provides content-disposition header\
        the filename will be changed if needed
        :return: The location where the file was saved
        """

        self.checkForSameFiles()

        self.pyfile.setStatus("downloading")

        download_folder = self.config['general']['download_folder']

        location = save_join(download_folder, self.pyfile.package().folder)

        if not exists(location):
            makedirs(location, int(self.core.config["permission"]["folder"],
                                   8))

            if self.core.config["permission"]["change_dl"] and not IS_WINDOWS:
                try:
                    uid = getpwnam(self.config["permission"]["user"])[2]
                    gid = getgrnam(self.config["permission"]["group"])[2]

                    chown(location, uid, gid)
                except Exception as e:
                    self.log.warning(
                        _("Setting User and Group failed: %s") % str(e))

        # convert back to unicode
        location = fs_decode(location)
        name = save_path(self.pyfile.name)

        filename = join(location, name)

        get_hook_manager().dispatchEvent("downloadStarts", self.pyfile, url,
                                         filename)

        try:
            newname = self.req.httpDownload(
                url,
                filename,
                get=get,
                post=post,
                ref=ref,
                cookies=cookies,
                chunks=self.getChunkCount(),
                resume=self.resumeDownload,
                progressNotify=self.pyfile.setProgress,
                disposition=disposition)
        finally:
            self.pyfile.size = self.req.size

        if disposition and newname and newname != name:  #triple check, just to be sure
            self.log.info("%(name)s saved as %(newname)s" % {
                "name": name,
                "newname": newname
            })
            self.pyfile.name = newname
            filename = join(location, newname)

        fs_filename = fs_encode(filename)

        if self.core.config["permission"]["change_file"]:
            chmod(fs_filename, int(self.core.config["permission"]["file"], 8))

        if self.core.config["permission"]["change_dl"] and not IS_WINDOWS:
            try:
                uid = getpwnam(self.config["permission"]["user"])[2]
                gid = getgrnam(self.config["permission"]["group"])[2]

                chown(fs_filename, uid, gid)
            except Exception as e:
                self.log.warning(
                    _("Setting User and Group failed: %s") % str(e))

        self.lastDownload = filename
        return self.lastDownload
Beispiel #22
0
 def __new__(cls, fn, *args, **kwargs):
     get_hook_manager().addRPC(fn.__module__, fn.__name__, fn.__doc__)
     return fn
Beispiel #23
0
 def run(*args, **kwargs):
     get_hook_manager().startThread(fn, *args, **kwargs)
Beispiel #24
0
    def getAllInfo(self):
        """Returns all information stored by hook plugins. Values are always strings

        :return: {"plugin": {"name": value } }
        """
        return get_hook_manager().getAllInfo()
Beispiel #25
0
    def run(self):
        """run method"""
        pyfile = None

        while True:
            del pyfile
            self.active = self.queue.get()
            pyfile = self.active

            if self.active == "quit":
                self.active = False
                self.m.threads.remove(self)
                return True

            hook_manager = get_hook_manager()

            try:
                if not pyfile.hasPlugin(): continue
                #this pyfile was deleted while queueing

                pyfile.plugin.checkForSameFiles(starting=True)
                self.m.log.info(_("Download starts: %s" % pyfile.name))

                # start download
                hook_manager.downloadPreparing(pyfile)
                pyfile.plugin.preprocessing(self)

                self.m.log.info(_("Download finished: %s") % pyfile.name)
                hook_manager.downloadFinished(pyfile)
                self.m.core.files.checkPackageFinished(pyfile)

            except NotImplementedError:
                self.m.log.error(
                    _("Plugin %s is missing a function.") % pyfile.pluginname)
                pyfile.setStatus("failed")
                pyfile.error = "Plugin does not work"
                self.clean(pyfile)
                continue

            except Abort:
                try:
                    self.m.log.info(_("Download aborted: %s") % pyfile.name)
                except:
                    pass

                pyfile.setStatus("aborted")

                self.clean(pyfile)
                continue

            except Reconnect:
                self.queue.put(pyfile)
                #pyfile.req.clearCookies()

                while self.m.reconnecting.isSet():
                    sleep(0.5)

                continue

            except Retry as e:
                reason = e.args[0]
                self.m.log.info(
                    _("Download restarted: %(name)s | %(msg)s") % {
                        "name": pyfile.name,
                        "msg": reason
                    })
                self.queue.put(pyfile)
                continue

            except Fail as e:
                msg = e.args[0]

                if msg == "offline":
                    pyfile.setStatus("offline")
                    self.m.log.warning(
                        _("Download is offline: %s") % pyfile.name)
                elif msg == "temp. offline":
                    pyfile.setStatus("temp. offline")
                    self.m.log.warning(
                        _("Download is temporary offline: %s") % pyfile.name)
                else:
                    pyfile.setStatus("failed")
                    self.m.log.warning(
                        _("Download failed: %(name)s | %(msg)s") % {
                            "name": pyfile.name,
                            "msg": msg
                        })
                    pyfile.error = msg

                hook_manager.downloadFailed(pyfile)
                self.clean(pyfile)
                continue

            except error as e:
                if len(e.args) == 2:
                    code, msg = e.args
                else:
                    code = 0
                    msg = e.args

                self.m.log.debug("pycurl exception %s: %s" % (code, msg))

                if code in (7, 18, 28, 52, 56):
                    self.m.log.warning(
                        _("Couldn't connect to host or connection reset, waiting 1 minute and retry."
                          ))
                    wait = time() + 60

                    pyfile.waitUntil = wait
                    pyfile.setStatus("waiting")
                    while time() < wait:
                        sleep(1)
                        if pyfile.abort:
                            break

                    if pyfile.abort:
                        self.m.log.info(
                            _("Download aborted: %s") % pyfile.name)
                        pyfile.setStatus("aborted")

                        self.clean(pyfile)
                    else:
                        self.queue.put(pyfile)

                    continue

                else:
                    pyfile.setStatus("failed")
                    self.m.log.error("pycurl error %s: %s" % (code, msg))
                    if self.m.core.debug:
                        print_exc()
                        self.writeDebugReport(pyfile)

                    hook_manager.downloadFailed(pyfile)

                self.clean(pyfile)
                continue

            except SkipDownload as e:
                pyfile.setStatus("skipped")

                self.m.log.info(
                    _("Download skipped: %(name)s due to %(plugin)s") % {
                        "name": pyfile.name,
                        "plugin": e.message
                    })

                self.clean(pyfile)

                self.m.core.files.checkPackageFinished(pyfile)

                self.active = False
                self.m.core.files.save()

                continue

            except Exception as e:
                pyfile.setStatus("failed")
                self.m.log.warning(
                    _("Download failed: %(name)s | %(msg)s") % {
                        "name": pyfile.name,
                        "msg": str(e)
                    })
                pyfile.error = str(e)

                if self.m.core.debug:
                    print_exc()
                    self.writeDebugReport(pyfile)

                hook_manager.downloadFailed(pyfile)
                self.clean(pyfile)
                continue

            finally:
                self.m.core.files.save()
                pyfile.checkIfProcessed()
                try:
                    sys.exc_clear()
                except Exception:
                    pass

            #pyfile.plugin.req.clean()

            self.active = False
            pyfile.finishIfDone()
            self.m.core.files.save()
Beispiel #26
0
    def tryReconnect(self):
        """checks if reconnect needed"""

        if not (self.core.config["reconnect"]["activated"]
                and self.core.api.isTimeReconnect()):
            return False

        active = [
            x.active.plugin.wantReconnect and x.active.plugin.waiting
            for x in self.threads if x.active
        ]

        if not (0 < active.count(True) == len(active)):
            return False

        if not exists(self.core.config['reconnect']['method']):
            if exists(join(pypath, self.core.config['reconnect']['method'])):
                self.core.config['reconnect']['method'] = join(
                    pypath, self.core.config['reconnect']['method'])
            else:
                self.core.config["reconnect"]["activated"] = False
                self.log.warning(_("Reconnect script not found!"))
                return

        self.reconnecting.set()

        # Do reconnect
        self.log.info(_("Starting reconnect"))

        while [x.active.plugin.waiting
               for x in self.threads if x.active].count(True) != 0:
            sleep(0.25)

        ip = self.getIP()

        hook_manager = get_hook_manager()

        hook_manager.beforeReconnecting(ip)

        self.log.debug("Old IP: %s" % ip)

        try:
            reconn = Popen(self.core.config['reconnect']['method'],
                           bufsize=-1,
                           shell=True)  #, stdout=subprocess.PIPE)
        except:
            self.log.warning(_("Failed executing reconnect script!"))
            self.core.config["reconnect"]["activated"] = False
            self.reconnecting.clear()
            if self.core.debug:
                print_exc()
            return

        reconn.wait()
        sleep(1)
        ip = self.getIP()
        hook_manager.afterReconnecting(ip)

        self.log.info(_("Reconnected, new IP: %s") % ip)

        self.reconnecting.clear()
Beispiel #27
0
    def download(self,
                 url,
                 get={},
                 post={},
                 ref=True,
                 cookies=True,
                 disposition=True,
                 resume=None,
                 chunks=None,
                 fixurl=True):
        """
        Downloads the content at url to download folder

        :param url:
        :param get:
        :param post:
        :param ref:
        :param cookies:
        :param disposition: if True and server provides content-disposition header\
        the filename will be changed if needed
        :return: The location where the file was saved
        """
        self.check_status()

        if self.pyload.debug:
            self.log_debug(
                "DOWNLOAD URL " + url, *[
                    "%s=%s" % (key, value) for key, value in locals().items()
                    if key not in ("self", "url", "_[1]")
                ])

        dl_url = self.fixurl(url) if fixurl else url
        dl_basename = parse_name(self.pyfile.name)

        self.pyfile.name = dl_basename

        self.check_duplicates()

        self.pyfile.setStatus("downloading")

        dl_folder = self.pyload.config.get('general', 'download_folder')
        dl_dirname = safejoin(dl_folder, self.pyfile.package().folder)
        dl_filename = safejoin(dl_dirname, dl_basename)

        dl_dir = encode(dl_dirname)
        dl_file = encode(dl_filename)

        if not exists(dl_dir):
            try:
                os.makedirs(dl_dir)

            except Exception as e:
                self.fail(e.message)

        self.set_permissions(dl_dir)

        get_hook_manager().dispatchEvent("download_start", self.pyfile, dl_url,
                                         dl_filename)
        self.check_status()

        newname = self._download(dl_url, dl_filename, get, post, ref, cookies,
                                 disposition, resume, chunks)

        #@TODO: Recheck in 0.4.10
        if disposition and newname:
            safename = parse_name(newname.split(' filename*=')[0])

            if safename != newname:
                try:
                    old_file = fsjoin(dl_dirname, newname)
                    new_file = fsjoin(dl_dirname, safename)
                    os.rename(old_file, new_file)

                except OSError as e:
                    self.log_warning(
                        _("Error renaming `%s` to `%s`") % (newname, safename),
                        e)
                    safename = newname

                self.log_info(
                    _("`%s` saved as `%s`") % (self.pyfile.name, safename))

            self.pyfile.name = safename

            dl_filename = os.path.join(dl_dirname, safename)
            dl_file = encode(dl_filename)

        self.set_permissions(dl_file)

        self.last_download = dl_filename

        return dl_filename