Updated commands to use the new objectdb.search API.

This commit is contained in:
Griatch 2013-05-11 23:22:02 +02:00
parent 218e4a149c
commit 78e7346962
11 changed files with 97 additions and 84 deletions

View file

@ -7,7 +7,6 @@ Admin commands
import time, re
from django.conf import settings
from django.contrib.auth.models import User
from src.players.models import PlayerDB
from src.server.sessionhandler import SESSIONS
from src.server.models import ServerConfig
from src.utils import utils, prettytable, search
@ -92,7 +91,6 @@ class CmdBoot(MuxCommand):
feedback += "\nReason given: %s" % reason
for session in boot_list:
name = session.uname
session.msg(feedback)
pobj.disconnect_session_from_player(session.sessid)
@ -287,12 +285,7 @@ class CmdDelPlayer(MuxCommand):
# We use player_search since we want to be sure to find also players
# that lack characters.
players = caller.search("*%s" % args)
if not players:
try:
players = PlayerDB.objects.filter(id=args)
except ValueError:
pass
players = caller.search_player(args, quiet=True)
if not players:
# try to find a user instead of a Player
@ -337,7 +330,6 @@ class CmdDelPlayer(MuxCommand):
player = players
user = player.user
character = player.character
if not player.access(caller, 'delete'):
string = "You don't have the permissions to delete that player."
@ -346,17 +338,14 @@ class CmdDelPlayer(MuxCommand):
uname = user.username
# boot the player then delete
if character and character.has_player:
self.msg("Booting and informing player ...")
string = "\nYour account '%s' is being *permanently* deleted.\n" % uname
if reason:
string += " Reason given:\n '%s'" % reason
character.msg(string)
# we have a bootable object with a connected player
sessions = SESSIONS.sessions_from_player(character.player)
for session in sessions:
session.msg(string)
session.disconnect()
self.msg("Informing and disconnecting player ...")
string = "\nYour account '%s' is being *permanently* deleted.\n" % uname
if reason:
string += " Reason given:\n '%s'" % reason
player.unpuppet_all()
for session in SESSIONS.sessions_from_player(player):
player.msg(string, sessid=session.sessid)
player.disconnect_session_from_player(session.sessid)
user.delete()
player.delete()
self.msg("Player %s was successfully deleted." % uname)
@ -466,7 +455,7 @@ class CmdNewPassword(MuxCommand):
return
# the player search also matches 'me' etc.
player = caller.search("*%s" % self.lhs, global_search=True, player=True)
player = caller.search_player(self.lhs)
if not player:
return
player.user.set_password(self.rhs)
@ -510,8 +499,10 @@ class CmdPerm(MuxCommand):
playermode = 'player' in self.switches or lhs.startswith('*')
# locate the object
obj = caller.search(lhs, global_search=True, player=playermode)
if playermode:
obj = caller.search_player(lhs)
else:
obj = caller.search(lhs, global_search=True)
if not obj:
return

View file

@ -499,9 +499,9 @@ class CmdDestroy(MuxCommand):
def delobj(objname, byref=False):
# helper function for deleting a single object
string = ""
obj = caller.search(objname, global_dbref=byref)
obj = caller.search(objname)
if not obj:
self.caller.msg(" (Objects to destroy must either be local or specified with a unique dbref.)")
self.caller.msg(" (Objects to destroy must either be local or specified with a unique #dbref.)")
return ""
if not "override" in self.switches and obj.dbid == int(settings.CHARACTER_DEFAULT_HOME.lstrip("#")):
return "\nYou are trying to delete CHARACTER_DEFAULT_HOME. If you want to do this, use the /override switch."
@ -1018,7 +1018,7 @@ class CmdOpen(ObjManipCommand):
# check if this exit object already exists at the location.
# we need to ignore errors (so no automatic feedback)since we
# have to know the result of the search to decide what to do.
exit_obj = caller.search(exit_name, location=location, ignore_errors=True)
exit_obj = caller.search(exit_name, location=location, quiet=True)
if len(exit_obj) > 1:
# give error message and return
caller.search(exit_name, location=location)
@ -1681,8 +1681,10 @@ class CmdExamine(ObjManipCommand):
self.player_mode = "player" in self.switches or obj_name.startswith('*')
obj = caller.search(obj_name, player=self.player_mode, global_dbref=True)
if self.player_mode:
obj = self.search_player(obj_name)
else:
obj = caller.search(obj_name)
if not obj:
continue

View file

@ -271,7 +271,7 @@ class CmdDrop(MuxCommand):
# Because the DROP command by definition looks for items
# in inventory, call the search function using location = caller
results = caller.search(self.args, location=caller, ignore_errors=True)
results = caller.search(self.args, location=caller, quiet=True)
# now we send it into the error handler (this will output consistent
# error messages if there are problems).

View file

@ -182,7 +182,6 @@ class CmdSetHelp(MuxCommand):
def func(self):
"Implement the function"
caller = self.caller
switches = self.switches
lhslist = self.lhslist

View file

@ -390,7 +390,7 @@ class CmdWho(MuxPlayerCommand):
plr_pobject = plr_pobject or session.get_player()
table.add_row([utils.crop(plr_pobject.name, width=25),
utils.time.format(delta_conn, 0),
utils,time_format(delta_cmd, 1)])
utils.time_format(delta_cmd, 1)])
string = "{wPlayers:{n\n%s\n%s unique accounts logged in." % (table, nplayers==1 and "One player" or nplayers)
self.msg(string)
@ -561,8 +561,6 @@ class CmdColorTest(MuxPlayerCommand):
def func(self):
"Show color tables"
player = self.caller
if self.args.startswith("a"):
# show ansi 16-color table
from src.utils import ansi

View file

@ -7,7 +7,6 @@ System commands
import traceback
import os, datetime, time
from time import time as timemeasure
from sys import getsizeof
import sys
import django, twisted

View file

@ -212,7 +212,7 @@ class ObjectManager(TypedObjectManager):
# main search methods and helper functions
@returns_typeclass_list
def object_search(self, ostring=None,
def object_search(self, ostring,
attribute_name=None,
typeclass=None,
candidates=None,
@ -268,7 +268,7 @@ class ObjectManager(TypedObjectManager):
if candidates:
# Convenience check to make sure candidates are really dbobjs
candidates = [cand.dbobj for cand in make_iter(candidates) if _GA(cand, "_hasattr")(cand, "dbobj")]
candidates = [cand.dbobj for cand in make_iter(candidates) if cand]
if typeclass:
candidates = [cand for cand in candidates if _GA(cand, "db_typeclass_path") in typeclass]

View file

@ -25,6 +25,7 @@ from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache
from src.typeclasses.typeclass import TypeClass
from src.players.models import PlayerNick
from src.objects.manager import ObjectManager
from src.players.models import PlayerDB
from src.commands.cmdsethandler import CmdSetHandler
from src.commands import cmdhandler
from src.scripts.scripthandler import ScriptHandler
@ -569,8 +570,8 @@ class ObjectDB(TypedObject):
<num>-<string> - can be used to differentiate between multiple same-named matches
global_search (bool): Search all objects globally. This is overruled by "location" keyword.
use_nicks (bool): Use nickname-replace (nicktype "object") on the search string
typeclass (str or Typeclass): Limit search only to Objects with this typeclass. May be a list of typeclasses
for a broader search.
typeclass (str or Typeclass, or list of either): Limit search only to Objects with this typeclass. May
be a list of typeclasses for a broader search.
location (Object): Specify a location to search, if different from the self's given location
plus its contents. This can also be a list of locations.
attribute_name (str): Use this named Attribute to match ostring against, instead of object.key.
@ -598,7 +599,7 @@ class ObjectDB(TypedObject):
# handle some common self-references:
if ostring == _HERE:
return self.location
if ostring in (_ME, _SELF, '*' + _ME, '*' + _SELF):
if ostring in (_ME, _SELF):
return self
if use_nicks:
@ -633,15 +634,25 @@ class ObjectDB(TypedObject):
# db manager expects database objects
candidates = [obj.dbobj for obj in candidates]
results = ObjectDB.objects.object_search(ostring=ostring,
typeclass=typeclass,
results = ObjectDB.objects.object_search(ostring,
attribute_name=attribute_name,
typeclass=typeclass,
candidates=candidates,
exact=exact)
if quiet:
return results
return _AT_SEARCH_RESULT(self, ostring, results, global_search)
def search_player(self, ostring, quiet=False):
"""
Simple wrapper of the player search also handling me, self
"""
if ostring in (_ME, _SELF) and _GA(self, "db_player"):
return _GA(self, "db_player")
results = PlayerDB.objects.player_search(ostring)
if quiet:
return results
return _AT_SEARCH_RESULT(self, ostring, results, True)
#
# Execution/action methods

View file

@ -143,58 +143,63 @@ class Object(TypeClass):
def search(self, ostring,
global_search=False,
global_dbref=False,
attribute_name=None,
use_nicks=False,
typeclass=None,
location=None,
ignore_errors=False,
player=False):
attribute_name=None,
quiet=False,
exact=False):
"""
Returns the typeclass of an Object matching a search string/condition
Perform a standard object search in the database, handling
multiple results and lack thereof gracefully.
multiple results and lack thereof gracefully. By default, only
objects in self's current location or inventory is searched.
Note: to find Players, use eg. ev.player_search.
ostring: (str) The string to match object names against.
Obs - To find a player, append * to the
start of ostring.
global_search(bool): Search all objects, not just the current
location/inventory
attribute_name (string) Which attribute to match
(if None, uses default 'name')
use_nicks (bool) : Use nickname replace (off by default)
location (Object): If None, use caller's current location
ignore_errors (bool): Don't display any error messages even
if there are none/multiple matches -
just return the result as a list.
player (Objectt): Don't search for an Object but a Player.
This will also find players that don't
currently have a character.
Inputs:
Returns - a unique Object/Player match or None. All error
messages are handled by system-commands and the parser-handlers
specified in settings.
ostring (str): Primary search criterion. Will be matched against object.key (with object.aliases second)
unless the keyword attribute_name specifies otherwise. Special strings:
#<num> - search by unique dbref. This is always a global search.
me,self - self-reference to this object
<num>-<string> - can be used to differentiate between multiple same-named matches
global_search (bool): Search all objects globally. This is overruled by "location" keyword.
use_nicks (bool): Use nickname-replace (nicktype "object") on the search string
typeclass (str or Typeclass): Limit search only to Objects with this typeclass. May be a list of typeclasses
for a broader search.
location (Object): Specify a location to search, if different from the self's given location
plus its contents. This can also be a list of locations.
attribute_name (str): Use this named Attribute to match ostring against, instead of object.key.
quiet (bool) - don't display default error messages - return multiple matches as a list and
no matches as None. If not set (default), will echo error messages and return None.
exact (bool) - if unset (default) - prefers to match to beginning of string rather than not matching
at all. If set, requires exact mathing of entire string.
Use *<string> to search for objects controlled by a specific
player. Note that the object controlled by the player will be
returned, not the player object itself. This also means that
this will not find Players without a character. Use the keyword
player=True to find player objects.
Returns:
quiet=False (default):
no match or multimatch:
auto-echoes errors to self.msg, then returns None
(results are handled by modules set by settings.SEARCH_AT_RESULT
and settings.SEARCH_AT_MULTIMATCH_INPUT)
match:
a unique object match
quiet=True:
no match or multimatch:
returns None or list of multi-matches
match:
a unique object match
Note - for multiple matches, the engine accepts a number
linked to the key in order to separate the matches from
each other without showing the dbref explicitly. Default
syntax for this is 'N-searchword'. So for example, if there
are three objects in the room all named 'ball', you could
address the individual ball as '1-ball', '2-ball', '3-ball'
etc.
"""
return self.dbobj.search(ostring,
global_search=global_search,
global_dbref=global_dbref,
attribute_name=attribute_name,
use_nicks=use_nicks,
location=location,
ignore_errors=ignore_errors,
player=player)
global_search=global_search,
use_nicks=use_nicks,
typeclass=typeclass,
location=location,
attribute_name=attribute_name,
quiet=quiet,
exact=quiet)
def execute_cmd(self, raw_string, sessid=None):
"""

View file

@ -160,7 +160,6 @@ class PlayerManager(TypedObjectManager):
ostring = a string or database id.
"""
ostring = ostring.lstrip("*")
dbref = self.dbref(ostring)
if dbref or dbref == 0:
matches = self.filter(id=dbref)

View file

@ -39,8 +39,13 @@ from src.commands import cmdhandler
from src.utils import logger, utils
from src.utils.utils import inherits_from, make_iter
from django.utils.translation import ugettext as _
__all__ = ("PlayerAttribute", "PlayerNick", "PlayerDB")
_ME = _("me")
_SELF = _("self")
_SESSIONS = None
_AT_SEARCH_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
_MULTISESSION_MODE = settings.MULTISESSION_MODE
@ -556,6 +561,10 @@ class PlayerDB(TypedObject):
Extra keywords are ignored, but are allowed in call in order to make API more consistent
with objects.models.TypedObject.search.
"""
# handle me, self
if ostring in (_ME, _SELF, '*' + _ME, '*' + _SELF):
return self
matches = _GA(self, "__class__").objects.player_search(ostring)
matches = _AT_SEARCH_RESULT(self, ostring, matches, global_search=True)
if matches and return_character: