Merging mainline changes.

This commit is contained in:
lagos 2012-09-27 23:27:45 -07:00
commit fe54326d5f
10 changed files with 525 additions and 366 deletions

View file

@ -226,7 +226,7 @@ class Enemy(Mob):
# analyze result. # analyze result.
if target.db.health <= 0: if target.db.health <= 0:
# we reduced enemy to 0 health. Whisp them off to the prison room. # we reduced enemy to 0 health. Whisp them off to the prison room.
tloc = search_object(self.db.defeat_location, global_search=True) tloc = search_object(self.db.defeat_location)
tstring = self.db.defeat_text tstring = self.db.defeat_text
if not tstring: if not tstring:
tstring = "You feel your conciousness slip away ... you fall to the ground as " tstring = "You feel your conciousness slip away ... you fall to the ground as "

View file

@ -365,7 +365,7 @@ class TeleportRoom(TutorialRoom):
# passed the puzzle # passed the puzzle
teleport_to = self.db.success_teleport_to # this is a room name teleport_to = self.db.success_teleport_to # this is a room name
results = search_object(teleport_to, global_search=True) results = search_object(teleport_to)
if not results or len(results) > 1: if not results or len(results) > 1:
# we cannot move anywhere since no valid target was found. # we cannot move anywhere since no valid target was found.
print "no valid teleport target for %s was found." % teleport_to print "no valid teleport target for %s was found." % teleport_to

1
ev.py
View file

@ -236,3 +236,4 @@ class SystemCmds(object):
del cmdhandler del cmdhandler
syscmdkeys = SystemCmds() syscmdkeys = SystemCmds()
del SystemCmds del SystemCmds

View file

@ -65,15 +65,15 @@ for inum in range(len(commands)):
print "leaving run ..." print "leaving run ..."
""" """
_PROCPOOL_BATCHCODE_SOURCE = """ _PROCPOOL_BATCHCODE_SOURCE = """
from src.commands.default.batchprocess import batch_cmd_exec, step_pointer, BatchSafeCmdSet from src.commands.default.batchprocess import batch_code_exec, step_pointer, BatchSafeCmdSet
caller.ndb.batch_stack = commands caller.ndb.batch_stack = codes
caller.ndb.batch_stackptr = 0 caller.ndb.batch_stackptr = 0
caller.ndb.batch_batchmode = "batch_commands" caller.ndb.batch_batchmode = "batch_code"
caller.cmdset.add(BatchSafeCmdSet) caller.cmdset.add(BatchSafeCmdSet)
for inum in range(len(commands)): for inum in range(len(codes)):
print "command:", inum print "code:", inum
caller.cmdset.add(BatchSafeCmdSet) caller.cmdset.add(BatchSafeCmdSet)
if not batch_cmd_exec(caller): if not batch_code_exec(caller):
break break
step_pointer(caller, 1) step_pointer(caller, 1)
print "leaving run ..." print "leaving run ..."
@ -272,7 +272,14 @@ class CmdBatchCommands(MuxCommand):
else: else:
caller.msg("Running Batch-command processor - Automatic mode for %s (this might take some time) ..." % python_path) caller.msg("Running Batch-command processor - Automatic mode for %s (this might take some time) ..." % python_path)
if False:#TODO - need to add a procpool solution. settings.PROCPOOL_ENABLED: procpool = False
if "PythonProcPool" in utils.server_services():
if utils.uses_database("sqlite3"):
caller.msg("Batchprocessor disabled ProcPool under SQLite3.")
else:
procpool=True
if procpool:
# run in parallel process # run in parallel process
def callback(r): def callback(r):
caller.msg(" {GBatchfile '%s' applied." % python_path) caller.msg(" {GBatchfile '%s' applied." % python_path)
@ -366,7 +373,13 @@ class CmdBatchCode(MuxCommand):
else: else:
caller.msg("Running Batch-code processor - Automatic mode for %s ..." % python_path) caller.msg("Running Batch-code processor - Automatic mode for %s ..." % python_path)
if False: #TODO Add procpool solution. settings.PROCPOOL_ENABLED: procpool = False
if "PythonProcPool" in utils.server_services():
if utils.uses_database("sqlite3"):
caller.msg("Batchprocessor disabled ProcPool under SQLite3.")
else:
procpool=True
if procpool:
# run in parallel process # run in parallel process
def callback(r): def callback(r):
caller.msg(" {GBatchfile '%s' applied." % python_path) caller.msg(" {GBatchfile '%s' applied." % python_path)
@ -374,10 +387,10 @@ class CmdBatchCode(MuxCommand):
def errback(e): def errback(e):
caller.msg(" {RError from processor: '%s'" % e) caller.msg(" {RError from processor: '%s'" % e)
purge_processor(caller) purge_processor(caller)
utils.run_async(_PROCPOOL_BATCHCODE_SOURCE, commands=commands, caller=caller, at_return=callback, at_err=errback) utils.run_async(_PROCPOOL_BATCHCODE_SOURCE, codes=codes, caller=caller, at_return=callback, at_err=errback)
else: else:
# un in-process (will block) # un in-process (will block)
for inum in range(len(commands)): for inum in range(len(codes)):
# loop through the batch file # loop through the batch file
if not batch_cmd_exec(caller): if not batch_cmd_exec(caller):
return return

View file

@ -118,7 +118,7 @@ class CmdSetObjAlias(MuxCommand):
objname = self.lhs objname = self.lhs
# Find the object to receive aliases # Find the object to receive aliases
obj = caller.search(objname, global_search=True) obj = caller.search(objname)
if not obj: if not obj:
return return
if self.rhs == None: if self.rhs == None:
@ -1232,7 +1232,7 @@ class CmdSetAttribute(ObjManipCommand):
# Use literal_eval to parse python structure exactly. # Use literal_eval to parse python structure exactly.
try: try:
return _LITERAL_EVAL(strobj) return _LITERAL_EVAL(strobj)
except ValueError: except (SyntaxError, ValueError):
# treat as string # treat as string
string = "{RNote: Value was converted to string. If you don't want this, " string = "{RNote: Value was converted to string. If you don't want this, "
string += "use proper Python syntax, like enclosing strings in quotes.{n" string += "use proper Python syntax, like enclosing strings in quotes.{n"

View file

@ -1,6 +1,8 @@
""" """
Custom manager for Objects. Custom manager for Objects.
""" """
try: import cPickle as pickle
except ImportError: import pickle
from django.db.models import Q from django.db.models import Q
from django.conf import settings from django.conf import settings
#from django.contrib.auth.models import User #from django.contrib.auth.models import User
@ -8,10 +10,11 @@ from django.db.models.fields import exceptions
from src.typeclasses.managers import TypedObjectManager from src.typeclasses.managers import TypedObjectManager
from src.typeclasses.managers import returns_typeclass, returns_typeclass_list from src.typeclasses.managers import returns_typeclass, returns_typeclass_list
from src.utils import utils from src.utils import utils
from src.utils.utils import to_unicode, make_iter, string_partial_matching from src.utils.utils import to_unicode, make_iter, string_partial_matching, to_str
__all__ = ("ObjectManager",) __all__ = ("ObjectManager",)
_GA = object.__getattribute__ _GA = object.__getattribute__
_DUMPS = lambda inp: to_unicode(pickle.dumps(inp))
# Try to use a custom way to parse id-tagged multimatches. # Try to use a custom way to parse id-tagged multimatches.
@ -126,8 +129,13 @@ class ObjectManager(TypedObjectManager):
not make sense to offer an "exact" type matching for this. not make sense to offer an "exact" type matching for this.
""" """
cand_restriction = candidates and Q(db_obj__pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q() cand_restriction = candidates and Q(db_obj__pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
attrs= self.model.objattribute_set.related.model.objects.select_related("db_obj").filter(cand_restriction & Q(db_key=attribute_name)) if type(attribute_value) in (basestring, int, float):
return [attr.db_obj for attr in attrs if attribute_value == attr.value] # simple attribute_value - do direct lookup
return self.model.objattribute_set.related.model.objects.select_related("db_obj").filter(cand_restriction & Q(db_key=attribute_name) & Q(db_value=_DUMPS(("simple", attribute_value))))
else:
# go via attribute conversion
attrs= self.model.objattribute_set.related.model.objects.select_related("db_obj").filter(cand_restriction & Q(db_key=attribute_name))
return [attr.db_obj for attr in attrs if attribute_value == attr.value]
@returns_typeclass_list @returns_typeclass_list
def get_objs_with_db_property(self, property_name, candidates=None): def get_objs_with_db_property(self, property_name, candidates=None):
@ -137,7 +145,7 @@ class ObjectManager(TypedObjectManager):
candidates - list of candidate objects to search candidates - list of candidate objects to search
""" """
property_name = "db_%s" % property_name.lstrip('db_') property_name = "db_%s" % property_name.lstrip('db_')
cand_restriction = candidates and Q(pk__in=[_GA(obj, "in") for obj in make_iter(candidates) if obj]) or Q() cand_restriction = candidates and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
try: try:
return self.filter(cand_restriction).exclude(Q(property_name=None)) return self.filter(cand_restriction).exclude(Q(property_name=None))
except exceptions.FieldError: except exceptions.FieldError:
@ -151,7 +159,7 @@ class ObjectManager(TypedObjectManager):
if isinstance(property_value, basestring): if isinstance(property_value, basestring):
property_value = to_unicode(property_value) property_value = to_unicode(property_value)
property_name = "db_%s" % property_name.lstrip('db_') property_name = "db_%s" % property_name.lstrip('db_')
cand_restriction = candidates and Q(pk__in=[_GA(obj, "in") for obj in make_iter(candidates) if obj]) or Q() cand_restriction = candidates and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
try: try:
return self.filter(cand_restriction & Q(property_name=property_value)) return self.filter(cand_restriction & Q(property_name=property_value))
except exceptions.FieldError: except exceptions.FieldError:
@ -178,7 +186,7 @@ class ObjectManager(TypedObjectManager):
candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj] candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
cand_restriction = candidates and Q(pk__in=candidates_id) or Q() cand_restriction = candidates and Q(pk__in=candidates_id) or Q()
if exact: if exact:
return self.filter(cand_restriction & (Q(db_key__iexact=ostring) | Q(alias__db_key__iexact=ostring))) return self.filter(cand_restriction & (Q(db_key__iexact=ostring) | Q(alias__db_key__iexact=ostring))).distinct()
else: else:
if candidates: if candidates:
# fuzzy matching - only check the candidates # fuzzy matching - only check the candidates
@ -196,7 +204,7 @@ class ObjectManager(TypedObjectManager):
return [] return []
else: else:
# fuzzy matching - first check with keys, then with aliases # fuzzy matching - first check with keys, then with aliases
key_candidates = self.filter(Q(db_key__istartswith=ostring) | Q(alias__db_key__istartswith=ostring)) key_candidates = self.filter(Q(db_key__istartswith=ostring) | Q(alias__db_key__istartswith=ostring)).distinct()
key_strings = key_candidates.values_list("db_key", flat=True) key_strings = key_candidates.values_list("db_key", flat=True)
matches = string_partial_matching(key_candidates, ostring, reg_index=False) matches = string_partial_matching(key_candidates, ostring, reg_index=False)
if matches: if matches:
@ -209,7 +217,6 @@ class ObjectManager(TypedObjectManager):
@returns_typeclass_list @returns_typeclass_list
def object_search(self, ostring, caller=None, def object_search(self, ostring, caller=None,
global_search=False,
attribute_name=None, attribute_name=None,
candidates=None, candidates=None,
exact=True): exact=True):
@ -241,16 +248,16 @@ class ObjectManager(TypedObjectManager):
""" """
def _searcher(ostring, exact=False): def _searcher(ostring, exact=False):
"Helper method for searching objects" "Helper method for searching objects"
if ostring.startswith("*"):
# Player search - try to find obj by its player's name
player_match = self.get_object_with_player(ostring, candidates=candidates)
if player_match is not None:
return [player_match]
if attribute_name: if attribute_name:
# attribute/property search (always exact). # attribute/property search (always exact).
matches = self.get_objs_with_db_property_value(attribute_name, ostring, candidates=candidates) matches = self.get_objs_with_db_property_value(attribute_name, ostring, candidates=candidates)
if not matches: if not matches:
return self.get_objs_with_attr_value(attribute_name, ostring, candidates=candidates) return self.get_objs_with_attr_value(attribute_name, ostring, candidates=candidates)
if ostring.startswith("*"):
# Player search - try to find obj by its player's name
player_match = self.get_object_with_player(ostring, candidates=candidates)
if player_match is not None:
return [player_match]
else: else:
# normal key/alias search # normal key/alias search
return self.get_objs_with_key_or_alias(ostring, exact=exact, candidates=candidates) return self.get_objs_with_key_or_alias(ostring, exact=exact, candidates=candidates)

View file

@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding index on 'ObjAttribute', fields ['db_value']
db.create_index('objects_objattribute', ['db_value'])
def backwards(self, orm):
# Removing index on 'ObjAttribute', fields ['db_value']
db.delete_index('objects_objattribute', ['db_value'])
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'objects.alias': {
'Meta': {'object_name': 'Alias'},
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'objects.objattribute': {
'Meta': {'object_name': 'ObjAttribute'},
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
'db_value': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'objects.objectdb': {
'Meta': {'object_name': 'ObjectDB'},
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'objects.objectnick': {
'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'ObjectNick'},
'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
'db_real': ('django.db.models.fields.TextField', [], {}),
'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'players.playerdb': {
'Meta': {'object_name': 'PlayerDB'},
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']", 'null': 'True', 'blank': 'True'}),
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
}
}
complete_apps = ['objects']

View file

@ -268,7 +268,7 @@ class Attribute(SharedMemoryModel):
db_key = models.CharField('key', max_length=255, db_index=True) db_key = models.CharField('key', max_length=255, db_index=True)
# access through the value property # access through the value property
db_value = models.TextField('value', blank=True, null=True) db_value = models.TextField('value', blank=True, null=True, db_index=True)
# Lock storage # Lock storage
db_lock_storage = models.CharField('locks', max_length=512, blank=True) db_lock_storage = models.CharField('locks', max_length=512, blank=True)
# references the object the attribute is linked to (this is set # references the object the attribute is linked to (this is set

View file

@ -461,6 +461,35 @@ def format_table(table, extra_space=1):
for icol, col in enumerate(table)]) for icol, col in enumerate(table)])
return ftable return ftable
def server_services():
"""
Lists all services active on the Server. Observe that
since services are launced in memory, this function will
only return any results if called from inside the game.
"""
from src.server.sessionhandler import SESSIONS
if hasattr(SESSIONS, "server") and hasattr(SESSIONS.server, "services"):
server = SESSIONS.server.services.namedServices
else:
print "This function must be called from inside the evennia process."
server = {}
del SESSIONS
return server
def uses_database(name="sqlite3"):
"""
Checks if the game is currently using a given database. This is a
shortcut to having to use the full backend name
name - one of 'sqlite3', 'mysql', 'postgresql_psycopg2' or 'oracle'
"""
try:
engine = settings.DATABASES["default"]["ENGINE"]
except KeyError:
engine = settings.DATABASE_ENGINE
return engine == "django.db.backends.%s" % name
_FROM_MODEL_MAP = None _FROM_MODEL_MAP = None
_TO_DBOBJ = lambda o: (hasattr(o, "dbobj") and o.dbobj) or o _TO_DBOBJ = lambda o: (hasattr(o, "dbobj") and o.dbobj) or o