# 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)
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)
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