Merging mainline changes.
This commit is contained in:
commit
fe54326d5f
10 changed files with 525 additions and 366 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
109
src/objects/migrations/0012_index_objattr_values.py
Normal file
109
src/objects/migrations/0012_index_objattr_values.py
Normal 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']
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue