示例#1
0
class ScriptBase(with_metaclass(TypeclassBase, ScriptDB)):
    """
    Base class for scripts. Don't inherit from this, inherit from the
    class `DefaultScript` below instead.

    """
    objects = ScriptManager()
示例#2
0
文件: scripts.py 项目: time-/evennia
class ScriptBase(ScriptDB):
    """
    Base class for scripts. Don't inherit from this, inherit from the
    class `DefaultScript` below instead.

    """
    __metaclass__ = TypeclassBase
    objects = ScriptManager()
示例#3
0
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()