Changed erroneous DateField to DateTimeField in ObjectDB, so you might have to resync your database. Fixed lots of formatting issues in the info and list commands. Resolved issue105.

This commit is contained in:
Griatch 2010-09-05 14:42:09 +00:00
parent 76624cd6f3
commit a2291953f2
8 changed files with 232 additions and 137 deletions

View file

@ -820,7 +820,7 @@ class CmdPage(MuxCommand):
received = []
for pobj in recobjs:
pobj.msg("%s %s" % (header, message))
if not pobj.has_player:
if hasattr(pobj, 'has_player') and not pobj.has_player:
received.append("{C%s{n" % pobj.name)
caller.msg("%s is offline. They will see your message if they list their pages later." % received[-1])
else:

View file

@ -29,7 +29,7 @@ class CmdVersion(MuxCommand):
"Show the version"
version = utils.get_evennia_version()
string = "-"*50 +"\n\r"
string += " Evennia %s\n\r" % version
string += " {cEvennia{n %s\n\r" % version
string += " (Django %s, " % (django.get_version())
string += " Twisted %s)\n\r" % (twisted.version.short())
string += "-"*50
@ -52,21 +52,23 @@ class CmdTime(MuxCommand):
def func(self):
"Show times."
string1 = "\nCurrent server uptime: "
string1 = "\nCurrent server uptime: \t"
string1 += "{w%s{n" % (utils.time_format(gametime.uptime(format=False), 2))
string2 = "\nTotal server running time: "
string2 = "\nTotal server running time: \t"
string2 += "{w%s{n" % (utils.time_format(gametime.runtime(format=False), 2))
string3 = "\nTotal in-game time (realtime x %g): " % (gametime.TIMEFACTOR)
string3 = "\nTotal in-game time (realtime x %g):\t" % (gametime.TIMEFACTOR)
string3 += "{w%s{n" % (utils.time_format(gametime.gametime(format=False), 2))
string4 = "\nServer time stamp: {w%s{n" % (str(datetime.datetime.now()))
string4 = "\nServer time stamp: \t"
string4 += "{w%s{n" % (str(datetime.datetime.now()))
string5 = ""
if not utils.host_os_is('nt'):
# os.getloadavg() is not available on Windows.
loadavg = os.getloadavg()
string5 += "\nServer load (per minute): {w%g%%{n" % (100 * loadavg[0])
string5 += "\nServer load (per minute): \t"
string5 += "{w%g%%{n" % (100 * loadavg[0])
string = "%s%s%s%s%s" % (string1, string2, string3, string4, string5)
self.caller.msg(string)
@ -75,10 +77,16 @@ class CmdList(MuxCommand):
@list - list info
Usage:
@list commands | process
@list <option>
Options:
process - list processes
objects - list objects
scripts - list scripts
perms - list permission keys and groups
Shows game related information depending
on which argument is given.
on which argument is given.
"""
key = "@list"
permissions = "cmd:list"
@ -89,43 +97,98 @@ class CmdList(MuxCommand):
caller = self.caller
if not self.args:
caller.msg("Usage: @list commands|process")
caller.msg("Usage: @list process|objects|scripts|perms")
return
string = ""
if self.arglist[0] in ["com", "command", "commands"]:
string = "Command sets currently in cache:"
for cmdset in cmdsethandler.get_cached_cmdsets():
string += "\n %s" % cmdset
elif self.arglist[0] in ["proc","process"]:
if self.arglist[0] in ["proc","process"]:
# display active processes
if utils.host_os_is('nt'):
string = "Feature not available on Windows."
else:
import resource
loadavg = os.getloadavg()
string = "\n Server load (1 min) : %.2f " % loadavg[0]
loadavg = os.getloadavg()
psize = resource.getpagesize()
rusage = resource.getrusage(resource.RUSAGE_SELF)
string += "\n Process ID: %10d" % os.getpid()
string += "\n Bytes per page: %10d" % psize
string += "\n Time used: %10d, user: %g" % (rusage[0], rusage[1])
string += "\n Integral mem: %10d shared, %10d, private, %10d stack " % \
(rusage[3], rusage[4], rusage[5])
string += "\n Max res mem: %10d pages %10d bytes" % \
(rusage[2],rusage[2] * psize)
string += "\n Page faults: %10d hard %10d soft %10d swapouts " % \
(rusage[7], rusage[6], rusage[8])
string += "\n Disk I/O: %10d reads %10d writes " % \
(rusage[9], rusage[10])
string += "\n Network I/O: %10d in %10d out " % \
(rusage[12], rusage[11])
string += "\n Context swi: %10d vol %10d forced %10d sigs " % \
(rusage[14], rusage[15], rusage[13])
table = [["Server load (1 min):",
"Process ID:",
"Bytes per page:",
"Time used:",
"Integral memory:",
"Max res memory:",
"Page faults:",
"Disk I/O:",
"Network I/O",
"Context switching:"
],
["%g%%" % (100 * loadavg[0]),
"%10d" % os.getpid(),
"%10d " % psize,
"%10d" % rusage[0],
"%10d shared" % rusage[3],
"%10d pages" % rusage[2],
"%10d hard" % rusage[7],
"%10d reads" % rusage[9],
"%10d in" % rusage[12],
"%10d vol" % rusage[14]
],
["", "", "",
"(user: %g)" % rusage[1],
"%10d private" % rusage[4],
"%10d bytes" % (rusage[2] * psize),
"%10d soft" % rusage[6],
"%10d writes" % rusage[10],
"%10d out" % rusage[11],
"%10d forced" % rusage[15]
],
["", "", "", "",
"%10d stack" % rusage[5],
"",
"%10d swapouts" % rusage[8],
"", "",
"%10d sigs" % rusage[13]
]
]
stable = []
for col in table:
stable.append([str(val).strip() for val in col])
ftable = utils.format_table(stable, 5)
string = ""
for row in ftable:
string += "\n " + "{w%s{n" % row[0] + "".join(row[1:])
# string = "\n Server load (1 min) : %.2f " % loadavg[0]
# string += "\n Process ID: %10d" % os.getpid()
# string += "\n Bytes per page: %10d" % psize
# string += "\n Time used: %10d, user: %g" % (rusage[0], rusage[1])
# string += "\n Integral mem: %10d shared, %10d, private, %10d stack " % \
# (rusage[3], rusage[4], rusage[5])
# string += "\n Max res mem: %10d pages %10d bytes" % \
# (rusage[2],rusage[2] * psize)
# string += "\n Page faults: %10d hard %10d soft %10d swapouts " % \
# (rusage[7], rusage[6], rusage[8])
# string += "\n Disk I/O: %10d reads %10d writes " % \
# (rusage[9], rusage[10])
# string += "\n Network I/O: %10d in %10d out " % \
# (rusage[12], rusage[11])
# string += "\n Context swi: %10d vol %10d forced %10d sigs " % \
# (rusage[14], rusage[15], rusage[13])
elif self.arglist[0] in ["obj","objects"]:
caller.execute_cmd("@objects")
elif self.arglist[0] in ["scr","scripts"]:
caller.execute_cmd("@scripts")
elif self.arglist[0] in ["perm","perms","permissions"]:
caller.execute_cmd("@perm/list")
else:
string = "Not a valid option."
string = "'%s' is not a valid option." % self.arglist[0]
# send info
caller.msg(string)
#TODO - expand @ps as we add irc/imc2 support.
class CmdPs(MuxCommand):
"""
@ps - list processes
@ -190,11 +253,9 @@ class CmdStats(MuxCommand):
# get all players
stats_users = User.objects.all().count()
string = "-"*60
string += "\n Number of users: %i" % stats_users
string += "\n Total number of objects: %i" % stats_allobj
string += "\n Number of rooms (location==None): %i" % stats_room
string += "\n Object type statistics:"
for path, num in stats_dict.items():
string += "\n %i - %s" % (num, path)
string = "\n{wNumber of users:{n %i" % stats_users
string += "\n{wTotal number of objects:{n %i" % stats_allobj
string += "\n{wNumber of rooms (location==None):{n %i" % stats_room
string += "\n (Use @objects for detailed info)"
self.caller.msg(string)

View file

@ -11,7 +11,6 @@ from src.players.models import PlayerDB
from src.scripts.models import ScriptDB
from src.objects.models import ObjectDB
from src.permissions.models import PermissionGroup
from src.scripts.scripthandler import format_script_list
from src.utils import reloads, create, logger, utils
from src.permissions.permissions import has_perm
from game.gamesrc.commands.default.muxcommand import MuxCommand
@ -117,7 +116,7 @@ class CmdPy(MuxCommand):
class CmdListScripts(MuxCommand):
"""
List all scripts.
Operate on scripts.
Usage:
@scripts[/switches] [<obj or scriptid>]
@ -137,6 +136,51 @@ class CmdListScripts(MuxCommand):
permissions = "cmd:listscripts"
help_category = "Admin"
def format_script_list(self, scripts):
"Takes a list of scripts and formats the output."
if not scripts:
return "<No scripts>"
table = [["id"], ["obj"], ["key"],["intval"],["next"],["rept"], ["db"],["typeclass"],["desc"]]
for script in scripts:
table[0].append(script.id)
if not hasattr(script, 'obj') or not script.obj:
table[1].append("<Global>")
else:
table[1].append(script.obj.key)
table[2].append(script.key)
if not hasattr(script, 'interval') or not script.interval:
table[3].append("--")
else:
table[3].append("%ss" % script.interval)
if not hasattr(script, 'next_repeat') or not script.next_repeat:
table[5].append("--")
else:
table[5].append("%ss" % script.next_repeat)
if not hasattr(script, 'repeats') or not script.repeats:
table[4].append("--")
else:
table[4].append("%ss" % script.repeats)
if script.persistent:
table[6].append("Y")
else:
table[6].append("N")
typeclass_path = script.typeclass_path.rsplit('.', 1)
table[7].append("%s" % typeclass_path[-1])
table[8].append(script.desc)
ftable = utils.format_table(table)
string = ""
for irow, row in enumerate(ftable):
if irow == 0:
srow = "\n" + "".join(row)
srow = "{w%s{n" % srow.rstrip()
else:
srow = "\n" + "{w%s{n" % row[0] + "".join(row[1:])
string += srow.rstrip()
return string.strip()
def func(self):
"implement method"
@ -145,13 +189,14 @@ class CmdListScripts(MuxCommand):
string = ""
if args:
# test first if this is an script match
# test first if this is a script match
scripts = ScriptDB.objects.get_all_scripts(key=args)
if not scripts:
# try to find an object instead.
objects = ObjectDB.objects.pobject_search(caller,
args,
global_search=True)
objects = ObjectDB.objects.object_search(caller,
args,
global_search=True)
if objects:
scripts = []
for obj in objects:
@ -160,9 +205,11 @@ class CmdListScripts(MuxCommand):
else:
# we want all scripts.
scripts = ScriptDB.objects.get_all_scripts()
if not scripts:
return
#caller.msg(scripts)
string = "No scripts found with a key '%s', or on an object named '%s'." % (args, args)
caller.msg(string)
return
if self.switches and self.switches[0] in ('stop', 'del', 'delete'):
# we want to delete something
@ -177,17 +224,16 @@ class CmdListScripts(MuxCommand):
else:
# multiple matches.
string = "Multiple script matches. Please refine your search:\n"
string += ", ".join([str(script.key) for script in scripts])
string += self.format_script_list(scripts)
elif self.switches and self.switches[0] in ("validate", "valid", "val"):
# run validation on all found scripts
nr_started, nr_stopped = ScriptDB.objects.validate(scripts=scripts)
string = "Validated %s scripts. " % ScriptDB.objects.all().count()
string += "Started %s and stopped %s scripts." % (nr_started,
nr_stopped)
string += "Started %s and stopped %s scripts." % (nr_started, nr_stopped)
else:
# No stopping or validation. We just want to view things.
string = format_script_list(scripts)
string = self.format_script_list(scripts)
print string
caller.msg(string)
@ -219,16 +265,17 @@ class CmdListCmdSets(MuxCommand):
class CmdListObjects(MuxCommand):
"""
List all objects in database
Give a summary of object types in database
Usage:
@listobjects [nr]
@objects [<nr>]
Gives a list of nr latest objects in database ang give
statistics. If not given, nr defaults to 10.
Gives statictics on objects in database as well as
a list of <nr> latest objects in database. If not
given, <nr> defaults to 10.
"""
key = "@listobjects"
aliases = ["@listobj", "@listobjs"]
key = "@objects"
aliases = ["@listobjects", "@listobjs"]
permissions = "cmd:listobjects"
help_category = "Building"
@ -243,18 +290,36 @@ class CmdListObjects(MuxCommand):
nlim = 10
dbtotals = ObjectDB.objects.object_totals()
#print dbtotals
string = "\nObjects in database:\n"
string += "Count\tTypeclass"
string = "\n{wDatase Object totals:{n"
table = [["Count"], ["Typeclass"]]
for path, count in dbtotals.items():
string += "\n %s\t%s" % (count, path)
string += "\nLast %s Objects created:" % nlim
objs = list(ObjectDB.objects.all())
table[0].append(count)
table[1].append(path)
ftable = utils.format_table(table, 3)
for irow, row in enumerate(ftable):
srow = "\n" + "".join(row)
srow = srow.rstrip()
if irow == 0:
srow = "{w%s{n" % srow
string += srow
string += "\n\n{wLast %s Objects created:{n" % nlim
objs = list(ObjectDB.objects.all())[:nlim]
table = [["Created"], ["dbref"], ["name"], ["typeclass"]]
for i, obj in enumerate(objs):
if i <= nlim:
string += "\n %s\t%s(#%i) (%s)" % \
(obj.date_created, obj.name, obj.id, str(obj.typeclass))
else:
break
table[0].append(utils.datetime_format(obj.date_created))
table[1].append(obj.dbref)
table[2].append(obj.key)
table[3].append(str(obj.typeclass))
ftable = utils.format_table(table, 5)
for irow, row in enumerate(ftable):
srow = "\n" + "".join(row)
srow = srow.rstrip()
if irow == 0:
srow = "{w%s{n" % srow
string += srow
caller.msg(string)
class CmdBoot(MuxCommand):

View file

@ -89,7 +89,7 @@ def import_cmdset(python_path, cmdsetobj, emit_to_obj=None, no_logging=False):
try:
try:
wanted_cache_key = python_path
print "inport cmdsets: cache=", CACHED_CMDSETS
cmdsetclass = CACHED_CMDSETS.get(wanted_cache_key, None)
errstring = ""
if not cmdsetclass:
@ -125,14 +125,6 @@ def import_cmdset(python_path, cmdsetobj, emit_to_obj=None, no_logging=False):
emit_to_obj.msg(errstring)
raise
def get_cached_cmdsets():
"""
Get the currently live cache from outside this module.
Calling a routine avoids update-problems when importing
the variable from an external module.
"""
return CACHED_CMDSETS
# classes
class CmdSetHandler(object):

View file

@ -212,8 +212,7 @@ class Msg(SharedMemoryModel):
#@date_sent.setter
def date_sent_set(self, value):
"Setter. Allows for self.date_sent = value"
self.db_date_sent = value
self.save()
raise Exception("You cannot edit date_sent!")
#@date_sent.deleter
def date_sent_del(self):
"Deleter. Allows for del self.date_sent"

View file

@ -9,54 +9,6 @@ from src.scripts.models import ScriptDB
from src.utils import create
from src.utils import logger
def format_script_list(scripts):
"Takes a list of scripts and format the output."
if not scripts:
return "<No scripts>"
string = "id obj\t\tkey\t\tinterval\trepeats\tnext\tpersistent"
for script in scripts:
obj = None
interval = None
repeats = None
try:
obj = script.obj
except AttributeError:
pass
try:
interval = script.interval
except AttributeError:
pass
try:
repeats = script.repeats
except AttributeError:
pass
try:
next_repeat = script.time_until_next_repeat()
except:
pass
if not obj:
obj = "<Global>"
if not interval:
interval = "N/A"
else:
interval = "%ss" % interval
if not repeats:
repeats = "N/A"
else:
repeats = "%ss" % repeats
if not next_repeat:
next_repeat = "N/A"
else:
next_repeat = "%ss" % next_repeat
string += "\n %s %s\t\t%s\t%s\t%s\t%s\t%s\n %s (%s)" % \
(script.id, obj, script.key, interval,
repeats, next_repeat, script.persistent,
script.typeclass_path, script.desc)
return string
class ScriptHandler(object):
"""
Implements the handler. This sits on each game object.

View file

@ -99,7 +99,7 @@ class Attribute(SharedMemoryModel):
# by each child class to this abstact class)
db_obj = None # models.ForeignKey("RefencedObject")
# time stamp
db_date_created = models.DateField(editable=False, auto_now_add=True)
db_date_created = models.DateTimeField(editable=False, auto_now_add=True)
# Database manager
objects = managers.AttributeManager()
@ -197,8 +197,7 @@ class Attribute(SharedMemoryModel):
#@date_created.setter
def date_created_set(self, value):
"Setter. Allows for self.date_created = value"
self.db_date_created = value
self.save()
raise Exception("Cannot edit date_created!")
#@date_created.deleter
def date_created_del(self):
"Deleter. Allows for del self.date_created"
@ -360,7 +359,7 @@ class TypedObject(SharedMemoryModel):
# (the type class is what defines what kind of Object this is)
db_typeclass_path = models.CharField(max_length=255, null=True)
# Creation date
db_date_created = models.DateField(editable=False, auto_now_add=True)
db_date_created = models.DateTimeField(editable=False, auto_now_add=True)
# Permissions (access these through the 'permissions' property)
db_permissions = models.CharField(max_length=512, blank=True)
@ -441,8 +440,7 @@ class TypedObject(SharedMemoryModel):
#@date_created.setter
def date_created_set(self, value):
"Setter. Allows for self.date_created = value"
self.db_date_created = value
self.save()
raise Exception("Cannot change date_created!")
#@date_created.deleter
def date_created_del(self):
"Deleter. Allows for del self.date_created"

View file

@ -8,7 +8,7 @@ import os
import textwrap
import datetime
from django.conf import settings
from src.utils import ansi
def is_iter(iterable):
"""
@ -145,7 +145,8 @@ def datetime_format(dtobj):
Takes a datetime object instance (e.g. from django's DateTimeField)
and returns a string.
"""
year, month, day = dtobj.year, dtobj.date, dtobj.day
year, month, day = dtobj.year, dtobj.month, dtobj.day
hour, minute, second = dtobj.hour, dtobj.minute, dtobj.second
now = datetime.datetime.now()
@ -307,3 +308,30 @@ def inherits_from(obj, parent):
else:
parent_path = "%s.%s" % (parent.__class__.__module__, parent.__class__.__name__)
return any(True for obj_path in obj_paths if obj_path == parent_path)
def format_table(table, extra_space=1):
"""
Takes a table of collumns: [[val,val,val,...], [val,val,val,...], ...]
where each val will be placed on a separate row in the column. All
collumns must have the same number of rows (some positions may be
empty though).
The function formats the columns to be as wide as the wides member
of each column.
extra_space defines how much extra padding should minimum be left between
collumns.
first_row_ansi defines an evential colour string for the first row.
"""
if not table:
return [[]]
max_widths = [max([len(str(val))
for val in col]) for col in table]
ftable = []
for irow in range(len(table[0])):
ftable.append([str(col[irow]).ljust(max_widths[icol]) + " " * extra_space
for icol, col in enumerate(table)])
return ftable