def on_startup(self): """ Set up the bot instance. """ self.trace("on_startup") # Fail early and predictably. for required in REQUIRED_PARAMS: if not required in self.params: raise KeyError(required) # NOT ATOMIC # REDFLAG: LATER: RTFM python ATOMIC file locking. if os.path.exists(self.parent.get_path(self, 'pid')): self.warn("on_startup -- lock file exists!: %s" % self.parent.get_path(self, 'pid')) raise IOError("Already running or previous instance crashed.") pid_file = open(self.parent.get_path(self, 'pid'), 'wb') try: pid_file.write("%i\n" % os.getpid()) self.trace("on_startup -- pid[%i], created lock file: %s" % (os.getpid(), self.parent.get_path(self, 'pid'))) finally: pid_file.close() self.ctx = WikiBotContext(self) self.ctx.setup_dbs(self.params) # Can't push this up into the FMSBotRunner because it # requires a particular fms_id. # DCI: how does this get reconnected? when server drops self.trust = TrustCache(self.parent.nntp_server, self.params['FMS_TRUST_CACHE_SECS']) # Mercurial stuff. self.ui_ = WikiBotUI(None, self) self.repo = hg.repository(self.ui_, self.params['REPO_DIR']) self.trace("Loaded hg repo from: %s" % self.params['REPO_DIR']) self.applier = ForkingSubmissionHandler() self.applier.ui_ = self.ui_ self.applier.repo = self.repo self.applier.logger = self self.applier.base_dir = os.path.join(self.repo.root, self.params['WIKI_ROOT']) print "BASE_DIR:", self.applier.base_dir # 2qt? self.applier.notify_needs_commit = ( lambda: self.ctx.set_timeout('COMMIT_COALESCE_SECS')) self.applier.notify_committed = self.ctx.committed self._send_status_notification('STARTED')
class WikiBot(FMSBot, RequestQueue): """ An FMSBot implementation to run a wiki over freenet. """ def __init__(self, name, params, request_runner): FMSBot.__init__(self, name) RequestQueue.__init__(self, request_runner) self.ctx = None self.applier = None self.params = params.copy() self.ui_ = None self.repo = None self.trust = None self.update_sm = None # Why doesn't the base class ctr do this? request_runner.add_queue(self) def trace(self, msg): """ Write a log message at trace level. """ self.log("T:" + msg) def debug(self, msg): """ Write a log message at debug level. """ self.log("D:" + msg) def warn(self, msg): """ Write a log message at warn level. """ self.log("W:" + msg) #----------------------------------------------------------# # FMSBot implementation. def on_startup(self): """ Set up the bot instance. """ self.trace("on_startup") # Fail early and predictably. for required in REQUIRED_PARAMS: if not required in self.params: raise KeyError(required) # NOT ATOMIC # REDFLAG: LATER: RTFM python ATOMIC file locking. if os.path.exists(self.parent.get_path(self, 'pid')): self.warn("on_startup -- lock file exists!: %s" % self.parent.get_path(self, 'pid')) raise IOError("Already running or previous instance crashed.") pid_file = open(self.parent.get_path(self, 'pid'), 'wb') try: pid_file.write("%i\n" % os.getpid()) self.trace("on_startup -- pid[%i], created lock file: %s" % (os.getpid(), self.parent.get_path(self, 'pid'))) finally: pid_file.close() self.ctx = WikiBotContext(self) self.ctx.setup_dbs(self.params) # Can't push this up into the FMSBotRunner because it # requires a particular fms_id. # DCI: how does this get reconnected? when server drops self.trust = TrustCache(self.parent.nntp_server, self.params['FMS_TRUST_CACHE_SECS']) # Mercurial stuff. self.ui_ = WikiBotUI(None, self) self.repo = hg.repository(self.ui_, self.params['REPO_DIR']) self.trace("Loaded hg repo from: %s" % self.params['REPO_DIR']) self.applier = ForkingSubmissionHandler() self.applier.ui_ = self.ui_ self.applier.repo = self.repo self.applier.logger = self self.applier.base_dir = os.path.join(self.repo.root, self.params['WIKI_ROOT']) print "BASE_DIR:", self.applier.base_dir # 2qt? self.applier.notify_needs_commit = ( lambda: self.ctx.set_timeout('COMMIT_COALESCE_SECS')) self.applier.notify_committed = self.ctx.committed self._send_status_notification('STARTED') def on_shutdown(self, why): """ Shut down the bot instance. """ self.trace("on_shutdown -- %s" % why) self.ctx.close_dbs() self._cleanup_temp_files() if os.path.exists(self.parent.get_path(self, 'pid')): try: os.remove(self.parent.get_path(self, 'pid')) self.trace("on_shutdown -- removed lock file: %s" % self.parent.get_path(self, 'pid')) except IOError, err: self.warn("on_shutdown -- err: %s" % str(err)) self._send_status_notification('STOPPED')