Example #1
0
        # Preparation steps
        raw_output_format = self.options.output_format
        default_output_format = "default"
        if actions:
            default_output_format = "action_cron" if self.options.cron else "action"
        self.validate_output_format(default_output_format)
        sort_key = self.validate_sort_fields()
        matcher = matching.ConditionParser(engine.FieldDefinition.lookup, "name").parse(self.args)
        self.LOG.debug("Matcher is: %s" % matcher)

        # Detach to background?
        # This MUST happen before the next step, when we connect to the torrent client
        if self.options.detach:
            config.engine.load_config()
            osmagic.daemonize(logfile=config.log_execute)
            time.sleep(.05) # let things settle a little

        # View handling
        if self.options.modify_view:
            if self.options.from_view or self.options.to_view:
                self.fatal("You cannot combine --modify-view with --from-view or --to-view")
            self.options.from_view = self.options.to_view = self.options.modify_view

        # Find matching torrents
        # TODO: this could get speedier quite a bit when we pre-select
        # a subset of all items in rtorrent itself, via a dynamic view!
        # Or sort them just the right way, and then abort after we cannot
        # possibly find more matches.
        #
        view = config.engine.view(self.options.from_view, matcher)
Example #2
0
        default_output_format = "default"
        if actions:
            default_output_format = "action_cron" if self.options.cron else "action"
        self.validate_output_format(default_output_format)
        sort_key = self.validate_sort_fields()
        matcher = matching.ConditionParser(engine.FieldDefinition.lookup,
                                           "name").parse(self.args)
        self.LOG.debug("Matcher is: %s" % matcher)

        # Detach to background?
        # This MUST happen before the next step, when we connect to the torrent client
        if self.options.detach:
            config.engine.load_config()
            daemon_log = os.path.join(config.config_dir, "log",
                                      "rtcontrol.log")
            osmagic.daemonize(logfile=daemon_log if os.path.
                              exists(os.path.dirname(daemon_log)) else None)
            time.sleep(.05)  # let things settle a little

        # View handling
        if self.options.append_view and self.options.alter_view:
            self.fatal("You cannot combine --append-view with --alter-view")

        if self.options.modify_view:
            if self.options.from_view or self.options.to_view:
                self.fatal(
                    "You cannot combine --modify-view with --from-view or --to-view"
                )
            self.options.from_view = self.options.to_view = self.options.modify_view

        # Find matching torrents
        view = config.engine.view(self.options.from_view, matcher)
Example #3
0
    def mainloop(self):
        """ The main loop.
        """
        self._validate_config()
        config.engine.load_config()

        # Defaults for process control paths
        if not self.options.no_fork and not self.options.guard_file:
            self.options.guard_file = os.path.join(config.config_dir,
                                                   "run/pyrotorque")
        if not self.options.pid_file:
            self.options.pid_file = os.path.join(config.config_dir,
                                                 "run/pyrotorque.pid")

        # Process control
        if self.options.status or self.options.stop or self.options.restart:
            if self.options.pid_file and os.path.exists(self.options.pid_file):
                running, pid = osmagic.check_process(self.options.pid_file)
            else:
                running, pid = False, 0

            if self.options.stop or self.options.restart:
                if running:
                    os.kill(pid, signal.SIGTERM)

                    # Wait for termination (max. 10 secs)
                    for _ in range(100):
                        running, _ = osmagic.check_process(
                            self.options.pid_file)
                        if not running:
                            break
                        time.sleep(.1)

                    self.LOG.info("Process #%d stopped." % (pid))
                elif pid:
                    self.LOG.info("Process #%d NOT running anymore." % (pid))
                else:
                    self.LOG.info("No pid file '%s'" %
                                  (self.options.pid_file or "<N/A>"))
            else:
                self.LOG.info("Process #%d %s running." %
                              (pid, "UP and" if running else "NOT"))

            if self.options.restart:
                if self.options.pid_file:
                    running, pid = osmagic.check_process(self.options.pid_file)
                    if running:
                        self.return_code = error.EX_TEMPFAIL
                        return
            else:
                self.return_code = error.EX_OK if running else error.EX_UNAVAILABLE
                return

        # Check for guard file and running daemon, abort if not OK
        try:
            osmagic.guard(self.options.pid_file, self.options.guard_file)
        except EnvironmentError as exc:
            self.LOG.debug(str(exc))
            self.return_code = error.EX_TEMPFAIL
            return

        # Detach, if not disabled via option
        if not self.options.no_fork:  # or getattr(sys.stdin, "isatty", lambda: False)():
            osmagic.daemonize(pidfile=self.options.pid_file,
                              logfile=logutil.get_logfile())
            time.sleep(.05)  # let things settle a little
        signal.signal(signal.SIGTERM, _raise_interrupt)

        # Set up services
        from apscheduler.scheduler import Scheduler
        self.sched = Scheduler(config.torque)

        self._init_wsgi_server()

        # Run services
        self.sched.start()
        try:
            self._add_jobs()
            # TODO: daemonize here, or before the scheduler starts?
            self._run_forever()
        finally:
            self.sched.shutdown()
            if self.wsgi_server:
                self.wsgi_server.task_dispatcher.shutdown()
                self.wsgi_server = None

            if self.options.pid_file:
                try:
                    os.remove(self.options.pid_file)
                except EnvironmentError as exc:
                    self.LOG.warn("Failed to remove pid file '%s' (%s)" %
                                  (self.options.pid_file, exc))
                    self.return_code = error.EX_IOERR