From 0dde856e3e6c9fa4740b75dcf30d6716e6e44ecb Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 17 Mar 2018 19:47:44 +0100 Subject: [PATCH] Spawner/olc mechanism working --- evennia/commands/default/building.py | 28 +++++++++++++++++++++---- evennia/utils/spawner.py | 31 ++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index 3730cc934e..9ea9707498 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -14,7 +14,8 @@ from evennia.utils.utils import inherits_from, class_from_module from evennia.utils.eveditor import EvEditor from evennia.utils.evmore import EvMore from evennia.utils.spawner import (spawn, search_prototype, list_prototypes, - store_prototype, build_metaproto, validate_prototype) + store_prototype, build_metaproto, validate_prototype, + delete_prototype, PermissionError) from evennia.utils.ansi import raw COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) @@ -2777,9 +2778,6 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS): locks = "cmd:perm(spawn) or perm(Builder)" help_category = "Building" - def parser(self): - super(CmdSpawn, self).parser() - def func(self): """Implements the spawner""" @@ -2867,7 +2865,28 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS): tags=self.lhslist)), exit_on_lastpage=True) return + if 'delete' in self.switches: + # remove db-based prototype + matchstring = _search_show_prototype(self.args) + if matchstring: + question = "\nDo you want to continue deleting? [Y]/N" + string = "|rDeleting prototype:|n\n{}".format(matchstring) + answer = yield(string + question) + if answer.lower() in ["n", "no"]: + caller.msg("|rDeletion cancelled.|n") + return + try: + success = delete_prototype(caller, self.args) + except PermissionError as err: + caller.msg("|rError deleting:|R {}|n".format(err)) + caller.msg("Deletion {}.".format( + 'successful' if success else 'failed (does the prototype exist?)')) + return + else: + caller.msg("Could not find prototype '{}'".format(key)) + if 'save' in self.switches: + # store a prototype to the database store if not self.args or not self.rhs: caller.msg( "Usage: @spawn/save [;desc[;tag,tag[,...][;lockstring]]] = ") @@ -2902,6 +2921,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS): # check for existing prototype, old_matchstring = _search_show_prototype(key) + if old_matchstring: string += "\n|yExisting saved prototype found:|n\n{}".format(old_matchstring) question = "\n|yDo you want to replace the existing prototype?|n [Y]/N" diff --git a/evennia/utils/spawner.py b/evennia/utils/spawner.py index 92f1261f7e..2a003069a4 100644 --- a/evennia/utils/spawner.py +++ b/evennia/utils/spawner.py @@ -122,6 +122,9 @@ _READONLY_PROTOTYPES = {} _READONLY_PROTOTYPE_MODULES = {} +class PermissionError(RuntimeError): + pass + # storage of meta info about the prototype MetaProto = namedtuple('MetaProto', ['key', 'desc', 'locks', 'tags', 'prototype']) @@ -199,14 +202,16 @@ def store_prototype(caller, key, prototype, desc="", tags=None, locks="", delete stored_prototype = PersistentPrototype.objects.filter(db_key=key) if stored_prototype: + # edit existing prototype stored_prototype = stored_prototype[0] if not stored_prototype.access(caller, 'edit'): raise PermissionError("{} does not have permission to " - "edit prototype {}".format(caller, key)) + "edit prototype {}.".format(caller, key)) if delete: + # delete prototype stored_prototype.delete() - return + return True if desc: stored_prototype.desc = desc @@ -216,13 +221,33 @@ def store_prototype(caller, key, prototype, desc="", tags=None, locks="", delete stored_prototype.locks.add(locks) if prototype: stored_prototype.attributes.add("prototype", prototype) + elif delete: + # didn't find what to delete + return False else: + # create a new prototype stored_prototype = create_script( PersistentPrototype, key=key, desc=desc, persistent=True, locks=locks, tags=tags, attributes=[("prototype", prototype)]) return stored_prototype +def delete_prototype(caller, key): + """ + Delete a stored prototype + + Args: + caller (Account or Object): Caller aiming to delete a prototype. + key (str): The persistent prototype to delete. + Returns: + success (bool): If deletion worked or not. + Raises: + PermissionError: If 'edit' lock was not passed. + + """ + return store_prototype(caller, key, None, delete=True) + + def search_persistent_prototype(key=None, tags=None, return_metaprotos=False): """ Find persistent (database-stored) prototypes based on key and/or tags. @@ -550,8 +575,6 @@ def spawn(*prototypes, **kwargs): # get available protparents protparents = get_protparents() - print("protparents: {}".format(protparents)) - # overload module's protparents with specifically given protparents protparents.update(kwargs.get("prototype_parents", {})) for key, prototype in protparents.items():