class ScriptBase(with_metaclass(TypeclassBase, ScriptDB)): """ Base class for scripts. Don't inherit from this, inherit from the class `DefaultScript` below instead. """ objects = ScriptManager()
class ScriptBase(ScriptDB): """ Base class for scripts. Don't inherit from this, inherit from the class `DefaultScript` below instead. """ __metaclass__ = TypeclassBase objects = ScriptManager()
class ScriptBase(ScriptDB, metaclass=TypeclassBase): """ Base class for scripts. Don't inherit from this, inherit from the class `DefaultScript` below instead. """ objects = ScriptManager() def __str__(self): return "<{cls} {key}>".format(cls=self.__class__.__name__, key=self.key) def __repr__(self): return str(self) def _start_task(self): """ Start task runner. """ if not self.ndb._task: self.ndb._task = ExtendedLoopingCall(self._step_task) if self.db._paused_time: # the script was paused; restarting callcount = self.db._paused_callcount or 0 self.ndb._task.start(self.db_interval, now=False, start_delay=self.db._paused_time, count_start=callcount) del self.db._paused_time del self.db._paused_repeats elif not self.ndb._task.running: # starting script anew self.ndb._task.start(self.db_interval, now=not self.db_start_delay) def _stop_task(self): """ Stop task runner """ task = self.ndb._task if task and task.running: task.stop() self.ndb._task = None def _step_errback(self, e): """ Callback for runner errors """ cname = self.__class__.__name__ estring = _( "Script %(key)s(#%(dbid)s) of type '%(cname)s': at_repeat() error '%(err)s'." ) % { "key": self.key, "dbid": self.dbid, "cname": cname, "err": e.getErrorMessage() } try: self.db_obj.msg(estring) except Exception: # we must not crash inside the errback, even if db_obj is None. pass logger.log_err(estring) def _step_callback(self): """ Step task runner. No try..except needed due to defer wrap. """ if not self.is_valid(): self.stop() return # call hook self.at_repeat() # check repeats callcount = self.ndb._task.callcount maxcount = self.db_repeats if maxcount > 0 and maxcount <= callcount: self.stop() def _step_task(self): """ Step task. This groups error handling. """ try: return maybeDeferred(self._step_callback).addErrback( self._step_errback) except Exception: logger.log_trace() return None def at_script_creation(self): """ Should be overridden in child. """ pass def at_first_save(self, **kwargs): """ This is called after very first time this object is saved. Generally, you don't need to overload this, but only the hooks called by this method. Args: **kwargs (dict): Arbitrary, optional arguments for users overriding the call (unused by default). """ self.at_script_creation() if hasattr(self, "_createdict"): # this will only be set if the utils.create_script # function was used to create the object. We want # the create call's kwargs to override the values # set by hooks. cdict = self._createdict updates = [] if not cdict.get("key"): if not self.db_key: self.db_key = "#%i" % self.dbid updates.append("db_key") elif self.db_key != cdict["key"]: self.db_key = cdict["key"] updates.append("db_key") if cdict.get("interval") and self.interval != cdict["interval"]: self.db_interval = max(0, cdict["interval"]) updates.append("db_interval") if cdict.get("start_delay" ) and self.start_delay != cdict["start_delay"]: self.db_start_delay = cdict["start_delay"] updates.append("db_start_delay") if cdict.get("repeats") and self.repeats != cdict["repeats"]: self.db_repeats = max(0, cdict["repeats"]) updates.append("db_repeats") if cdict.get( "persistent") and self.persistent != cdict["persistent"]: self.db_persistent = cdict["persistent"] updates.append("db_persistent") if cdict.get("desc") and self.desc != cdict["desc"]: self.db_desc = cdict["desc"] updates.append("db_desc") if updates: self.save(update_fields=updates) if cdict.get("permissions"): self.permissions.batch_add(*cdict["permissions"]) if cdict.get("locks"): self.locks.add(cdict["locks"]) if cdict.get("tags"): # this should be a list of tags, tuples (key, category) or (key, category, data) self.tags.batch_add(*cdict["tags"]) if cdict.get("attributes"): # this should be tuples (key, val, ...) self.attributes.batch_add(*cdict["attributes"]) if cdict.get("nattributes"): # this should be a dict of nattrname:value for key, value in cdict["nattributes"]: self.nattributes.add(key, value) if not cdict.get("autostart"): # don't auto-start the script return # auto-start script (default) self.start()