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

@ -65,15 +65,15 @@ for inum in range(len(commands)):
print "leaving run ..."
"""
_PROCPOOL_BATCHCODE_SOURCE = """
from src.commands.default.batchprocess import batch_cmd_exec, step_pointer, BatchSafeCmdSet
caller.ndb.batch_stack = commands
from src.commands.default.batchprocess import batch_code_exec, step_pointer, BatchSafeCmdSet
caller.ndb.batch_stack = codes
caller.ndb.batch_stackptr = 0
caller.ndb.batch_batchmode = "batch_commands"
caller.ndb.batch_batchmode = "batch_code"
caller.cmdset.add(BatchSafeCmdSet)
for inum in range(len(commands)):
print "command:", inum
for inum in range(len(codes)):
print "code:", inum
caller.cmdset.add(BatchSafeCmdSet)
if not batch_cmd_exec(caller):
if not batch_code_exec(caller):
break
step_pointer(caller, 1)
print "leaving run ..."
@ -272,7 +272,14 @@ class CmdBatchCommands(MuxCommand):
else:
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
def callback(r):
caller.msg(" {GBatchfile '%s' applied." % python_path)
@ -366,7 +373,13 @@ class CmdBatchCode(MuxCommand):
else:
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
def callback(r):
caller.msg(" {GBatchfile '%s' applied." % python_path)
@ -374,10 +387,10 @@ class CmdBatchCode(MuxCommand):
def errback(e):
caller.msg(" {RError from processor: '%s'" % e)
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:
# un in-process (will block)
for inum in range(len(commands)):
for inum in range(len(codes)):
# loop through the batch file
if not batch_cmd_exec(caller):
return

View file

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

View file

@ -1,6 +1,8 @@
"""
Custom manager for Objects.
"""
try: import cPickle as pickle
except ImportError: import pickle
from django.db.models import Q
from django.conf import settings
#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 returns_typeclass, returns_typeclass_list
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",)
_GA = object.__getattribute__
_DUMPS = lambda inp: to_unicode(pickle.dumps(inp))
# 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.
"""
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))
return [attr.db_obj for attr in attrs if attribute_value == attr.value]
if type(attribute_value) in (basestring, int, float):
# 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
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
"""
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:
return self.filter(cand_restriction).exclude(Q(property_name=None))
except exceptions.FieldError:
@ -151,7 +159,7 @@ class ObjectManager(TypedObjectManager):
if isinstance(property_value, basestring):
property_value = to_unicode(property_value)
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:
return self.filter(cand_restriction & Q(property_name=property_value))
except exceptions.FieldError:
@ -178,7 +186,7 @@ class ObjectManager(TypedObjectManager):
candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
cand_restriction = candidates and Q(pk__in=candidates_id) or Q()
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:
if candidates:
# fuzzy matching - only check the candidates
@ -196,7 +204,7 @@ class ObjectManager(TypedObjectManager):
return []
else:
# 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)
matches = string_partial_matching(key_candidates, ostring, reg_index=False)
if matches:
@ -209,7 +217,6 @@ class ObjectManager(TypedObjectManager):
@returns_typeclass_list
def object_search(self, ostring, caller=None,
global_search=False,
attribute_name=None,
candidates=None,
exact=True):
@ -241,16 +248,16 @@ class ObjectManager(TypedObjectManager):
"""
def _searcher(ostring, exact=False):
"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:
# attribute/property search (always exact).
matches = self.get_objs_with_db_property_value(attribute_name, ostring, candidates=candidates)
if not matches:
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:
# normal key/alias search
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)
# 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
db_lock_storage = models.CharField('locks', max_length=512, blank=True)
# 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)])
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
_TO_DBOBJ = lambda o: (hasattr(o, "dbobj") and o.dbobj) or o