Migration needed. Refactored the config.configValue model into server.ServerConfig (that's what the config model were used for anyway). The new model can handle arbitrary data structures through pickle. Run ./manage.py migrate to sync your database with the new setup.

Moved Connect screens (the text screen first seen when connecting) away from the database and into a module in gamesrc/world. This module allows for conveniently adding new connect screens on the fly. More than one screen in the given module will mean a random screen is used.
This commit is contained in:
Griatch 2011-04-12 21:43:57 +00:00
parent f1404356ea
commit 7f9f21f45e
21 changed files with 162 additions and 257 deletions

View file

@ -219,14 +219,6 @@ class CmdInventory(MuxCommand):
string += "\n %s" % item.name
self.caller.msg(string)
## money = int(caller.MONEY)
## if money == 1:
## money_name = ConfigValue.objects.get_configvalue("MONEY_NAME_SINGULAR")
## else:
## money_name = ConfigValue.objects.get_configvalue("MONEY_NAME_PLURAL")
##caller.msg("You have %d %s." % (money, money_name))
class CmdGet(MuxCommand):
"""
get

View file

@ -14,7 +14,7 @@ from src.server.sessionhandler import SESSIONS
from src.scripts.models import ScriptDB
from src.objects.models import ObjectDB
from src.players.models import PlayerDB
from src.config.models import ConfigValue
from src.server.models import ServerConfig
from src.utils import reloads, create, logger, utils, gametime
from src.commands.default.muxcommand import MuxCommand
@ -57,7 +57,7 @@ class CmdPy(MuxCommand):
'config': dummy conf instance
'ObjectDB' : ObjectDB class
'ScriptDB' : ScriptDB class
'ConfigValue' ConfigValue class
'ServerConfig' ServerConfig class
only two
variables are defined: 'self'/'me' which refers to one's
own object, and 'here' which refers to self's current
@ -83,7 +83,7 @@ class CmdPy(MuxCommand):
key = 'testscript')
obj = create.create_object("src.objects.objects.Object",
key='testobject')
conf = ConfigValue() # used to access conf values
conf = ServerConfig() # used to access conf values
available_vars = {'self':caller,
'me':caller,
@ -93,7 +93,7 @@ class CmdPy(MuxCommand):
'config':conf,
'ObjectDB':ObjectDB,
'ScriptDB':ScriptDB,
'ConfigValue':ConfigValue}
'ServerConfig':ServerConfig}
caller.msg(">>> %s" % pycode)
try:

View file

@ -22,7 +22,7 @@ from django.conf import settings
from src.utils import create, ansi
from src.server import session, sessionhandler
from src.locks.lockhandler import LockHandler
from src.config.models import ConfigValue
from src.server.models import ServerConfig
#------------------------------------------------------------
# Command testing
@ -77,7 +77,7 @@ class CommandTest(TestCase):
"""
def setUp(self):
"sets up the testing environment"
c = ConfigValue(db_key="default_home", db_value="2")
c = ServerConfig.objects.conf("default_home", 2)
c.save()
self.room1 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room1")

View file

@ -7,7 +7,7 @@ from django.contrib.auth.models import User
from src.server import sessionhandler
from src.players.models import PlayerDB
from src.objects.models import ObjectDB
from src.config.models import ConfigValue
from src.server.models import ServerConfig
from src.comms.models import Channel
from src.utils import create, logger, utils, ansi
@ -67,7 +67,7 @@ class CmdConnect(MuxCommand):
# Create a new character object to tie the player to. This should
# usually not be needed unless the old character object was manually
# deleted.
default_home_id = ConfigValue.objects.conf(db_key="default_home")
default_home_id = ServerConfig.objects.conf("default_home")
default_home = ObjectDB.objects.get_id(default_home_id)
typeclass = settings.BASE_CHARACTER_TYPECLASS
character = create.create_object(typeclass=typeclass,
@ -185,7 +185,7 @@ class CmdCreate(MuxCommand):
else:
# everything's ok. Create the new player account
try:
default_home_id = ConfigValue.objects.conf(db_key="default_home")
default_home_id = ServerConfig.objects.conf("default_home")
default_home = ObjectDB.objects.get_id(default_home_id)
typeclass = settings.BASE_CHARACTER_TYPECLASS

View file

@ -1,27 +0,0 @@
#
# This sets up how models are displayed
# in the web admin interface.
#
from src.config.models import ConfigValue, ConnectScreen
from django.contrib import admin
class ConfigValueAdmin(admin.ModelAdmin):
list_display = ('id', 'db_key')
list_display_links = ("id", 'db_key')
ordering = ['id', 'db_key']
search_fields = ['db_key']
save_as = True
save_on_top = True
list_select_related = True
admin.site.register(ConfigValue, ConfigValueAdmin)
class ConnectScreenAdmin(admin.ModelAdmin):
list_display = ('id', 'db_key', 'db_text', 'db_is_active')
list_display_links = ('id', 'db_key')
ordering = ['id', 'db_key']
search_fields = ['^db_key']
save_as = True
save_on_top = True
list_select_related = True
admin.site.register(ConnectScreen, ConnectScreenAdmin)

View file

@ -1,67 +0,0 @@
"""
Custom manager for ConfigValue objects.
"""
from django.db import models
from django.contrib.contenttypes.models import ContentType
class ConfigValueManager(models.Manager):
"""
This gives some access methods to search and edit
the configvalue database.
"""
def set_configvalue(self, db_key, db_value):
"Set new/overwrite old config value"
db_objs = self.filter(db_key=db_key)
if db_objs:
# Overwrite old config value
db_obj = db_objs[0]
db_obj.db_value = db_value
db_obj.save()
else:
# No old conf found. Create a new one.
ConfigValue = ContentType.objects.get(app_label="config",
model="configvalue").model_class()
new_conf = ConfigValue()
new_conf.db_key = db_key
new_conf.db_value = db_value
new_conf.save()
def get_configvalue(self, config_key, default=None):
"""
Retrieve a configuration value.
config_key - the name of the configuration option
"""
try:
return self.get(db_key__iexact=config_key).db_value
except self.model.DoesNotExist:
return default
# a simple wrapper for consistent naming in utils.search
def config_search(self, ostring):
"""
Retrieve a configuration value.
ostring - a (unique) configuration key
"""
return self.get_configvalue(ostring)
def conf(self, db_key=None, db_value=None, delete=False, default=None):
"""
Wrapper to access the Config database.
This will act as a get/setter, lister or deleter
depending on how many arguments are supplied.
Due to its design, you cannot set conf to a value of
None using this method, use objects.set_configvalue
instead.
"""
if not db_key:
return self.all()
elif delete == True:
conf = self.get_configvalue(db_key)
if conf:
conf.delete()
elif db_value != None:
self.set_configvalue(db_key, db_value)
else:
return self.get_configvalue(db_key, default=default)

View file

@ -1,54 +0,0 @@
# encoding: 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 model 'ConfigValue'
db.create_table('config_configvalue', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('db_key', self.gf('django.db.models.fields.CharField')(max_length=100)),
('db_value', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal('config', ['ConfigValue'])
# Adding model 'ConnectScreen'
db.create_table('config_connectscreen', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('db_text', self.gf('django.db.models.fields.TextField')()),
('db_is_active', self.gf('django.db.models.fields.BooleanField')(default=True)),
))
db.send_create_signal('config', ['ConnectScreen'])
def backwards(self, orm):
# Deleting model 'ConfigValue'
db.delete_table('config_configvalue')
# Deleting model 'ConnectScreen'
db.delete_table('config_connectscreen')
models = {
'config.configvalue': {
'Meta': {'object_name': 'ConfigValue'},
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'db_value': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'config.connectscreen': {
'Meta': {'object_name': 'ConnectScreen'},
'db_is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'db_text': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['config']

View file

@ -1,35 +0,0 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from src.utils import utils
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting model 'ConnectScreen'
db.delete_table('config_connectscreen')
def backwards(self, orm):
# Adding model 'ConnectScreen'
db.create_table('config_connectscreen', (
('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('db_is_active', self.gf('django.db.models.fields.BooleanField')(default=True)),
('db_text', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal('config', ['ConnectScreen'])
models = {
'config.configvalue': {
'Meta': {'object_name': 'ConfigValue'},
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'db_value': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['config']

View file

@ -21,7 +21,7 @@ from src.utils.idmapper.models import SharedMemoryModel
from src.typeclasses.models import Attribute, TypedObject
from src.typeclasses.typeclass import TypeClass
from src.objects.manager import ObjectManager
from src.config.models import ConfigValue
from src.server.models import ServerConfig
from src.commands.cmdsethandler import CmdSetHandler
from src.scripts.scripthandler import ScriptHandler
from src.utils import logger
@ -666,7 +666,7 @@ class ObjectDB(TypedObject):
if self.home:
source_location = self.home
else:
default_home_id = ConfigValue.objects.conf(db_key="default_home")
default_home_id = ServerConfig.objects.conf("default_home")
default_home = ObjectDB.objects.get_id(default_home_id)
source_location = default_home
@ -743,7 +743,7 @@ class ObjectDB(TypedObject):
"""
# Gather up everything that thinks this is its location.
objs = ObjectDB.objects.filter(db_location=self)
default_home_id = int(ConfigValue.objects.conf('default_home'))
default_home_id = int(ServerConfig.objects.conf('default_home'))
try:
default_home = ObjectDB.objects.get(id=default_home_id)
except Exception:

18
src/server/admin.py Normal file
View file

@ -0,0 +1,18 @@
#
# This sets up how models are displayed
# in the web admin interface.
#
from django.contrib import admin
from src.config.models import ServerConfig
class ServerConfigAdmin(admin.ModelAdmin):
"Custom admin for server configs"
list_display = ('db_key', 'db_value')
list_display_links = ('db_key')
ordering = ['db_key', 'db_value']
search_fields = ['db_key']
save_as = True
save_on_top = True
list_select_related = True
admin.site.register(ServerConfig, ServerConfigAdmin)

View file

@ -9,17 +9,17 @@ Everything starts at handle_setup()
from django.contrib.auth.models import User
from django.core import management
from django.conf import settings
from src.config.models import ConfigValue
from src.server.models import ServerConfig
from src.help.models import HelpEntry
from src.utils import create
def create_config_values():
"""
Creates the initial config values.
"""
ConfigValue.objects.conf("default_home", "2")
ConfigValue.objects.conf("site_name", settings.SERVERNAME)
ConfigValue.objects.conf("idle_timeout", settings.IDLE_TIMEOUT)
"""
ServerConfig.objects.conf("default_home", "2")
ServerConfig.objects.conf("site_name", settings.SERVERNAME)
ServerConfig.objects.conf("idle_timeout", settings.IDLE_TIMEOUT)
def get_god_user():
"""
@ -196,7 +196,7 @@ def handle_setup(last_step):
if not settings.IMPORT_MUX_HELP:
# skip importing of the MUX helpfiles, they are
# not interesting except for developers.
del setup_queue[5]
del setup_queue[4]
#print " Initial setup: %s steps." % (len(setup_queue))
@ -228,7 +228,7 @@ def handle_setup(last_step):
raise
ConfigValue.objects.conf("last_initial_setup_step", last_step + num + 1)
ServerConfig.objects.conf("last_initial_setup_step", last_step + num + 1)
# We got through the entire list. Set last_step to -1 so we don't
# have to run this again.
ConfigValue.objects.conf("last_initial_setup_step", -1)
ServerConfig.objects.conf("last_initial_setup_step", -1)

31
src/server/manager.py Normal file
View file

@ -0,0 +1,31 @@
"""
Custom manager for ServerConfig objects.
"""
from django.db import models
class ServerConfigManager(models.Manager):
"""
This gives some access methods to search and edit
the configvalue database.
If no match is found, return default.
"""
def conf(self, key=None, value=None, delete=False, default=None):
"""
Access and manipulate config values
"""
if not key:
return self.all()
elif delete == True:
for conf in self.filter(db_key=key):
conf.delete()
elif value != None:
conf = self.filter(db_key=key)
if not conf:
conf = self.model(db_key=key)
conf.value = value # this will pickle
else:
conf = self.filter(db_key=key)
if not conf:
return default
return conf[0].value

View file

@ -0,0 +1,46 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models, utils
import pickle
class Migration(SchemaMigration):
def forwards(self, orm):
try:
db.rename_table("config_configvalue", "server_serverconfig")
for conf in orm.ServerConfig.objects.all():
conf.db_value = pickle.dumps(conf.db_value)
conf.save()
except utils.DatabaseError:
# this will happen if we start db from scratch (the config
# app will then already be gone and no data is to be transferred)
# So instead of renaming the old we instead have to manually create the new model.
# Adding model 'ServerConfig'
db.create_table('server_serverconfig', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('db_key', self.gf('django.db.models.fields.CharField')(unique=True, max_length=64)),
('db_value', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('server', ['ServerConfig'])
def backwards(self, orm):
raise RuntimeError("This migration cannot be reversed.")
models = {
'config.configvalue': {
'Meta': {'object_name': 'ConfigValue'},
'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
'db_value': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'server.serverconfig': {
'Meta': {'object_name': 'ServerConfig'},
'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
'db_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['config', 'server']

View file

56
src/config/models.py → src/server/models.py Executable file → Normal file
View file

@ -1,45 +1,52 @@
"""
Configuration model - storing global flags on the fly, as
opposed to what is set once and for all
in the settings file.
ConnectScreen model - cycling connect screens
Server Configuration flags
This holds persistent server configuration flags.
Config values should usually be set through the
manager's conf() method.
"""
try:
import cPickle as pickle
except ImportError:
import pickle
from django.db import models
from src.utils.idmapper.models import SharedMemoryModel
from src.config.manager import ConfigValueManager
from src.utils import logger, utils
from src.server.manager import ServerConfigManager
#------------------------------------------------------------
#
# ConfigValue
# ServerConfig
#
#------------------------------------------------------------
class ConfigValue(SharedMemoryModel):
class ServerConfig(SharedMemoryModel):
"""
On-the fly storage of global settings.
Properties defined on ConfigValue:
Properties defined on ServerConfig:
key - main identifier
value - value stored in key
value - value stored in key. This is a pickled storage.
"""
#
# ConfigValue database model setup
# ServerConfig database model setup
#
#
# These database fields are all set using their corresponding properties,
# named same as the field, but withtout the db_* prefix.
# main name of the database entry
db_key = models.CharField(max_length=100)
db_key = models.CharField(max_length=64, unique=True)
# config value
db_value = models.TextField()
db_value = models.TextField(blank=True)
# Database manager
objects = ConfigValueManager()
objects = ServerConfigManager()
# Wrapper properties to easily set database fields. These are
# @property decorators that allows to access these fields using
@ -69,15 +76,19 @@ class ConfigValue(SharedMemoryModel):
#@property
def value_get(self):
"Getter. Allows for value = self.value"
return self.db_value
return pickle.loads(str(self.db_value))
#@value.setter
def value_set(self, value):
"Setter. Allows for self.value = value"
self.db_value = value
if utils.has_parent('django.db.models.base.Model', value):
# we have to protect against storing db objects.
logger.log_errmsg("ServerConfig cannot store db objects! (%s)" % value)
return
self.db_value = pickle.dumps(value)
self.save()
#@value.deleter
def value_del(self):
"Deleter. Allows for del self.value. Deletes entry."
"Deleter. Allows for del self.value. Deletes entry."
self.delete()
value = property(value_get, value_set, value_del)
@ -87,8 +98,15 @@ class ConfigValue(SharedMemoryModel):
verbose_name_plural = "Server Config values"
#
# ConfigValue other methods
# ServerConfig other methods
#
def __unicode__(self):
return "%s" % self.key
return "%s : %s" % (self.key, self.value)
def store(key, value):
"""
Wrap the storage (handles pickling)
"""
self.key = key
self.value = value

View file

@ -21,7 +21,7 @@ from twisted.web import server, static
from django.db import connection
from django.conf import settings
from src.utils import reloads
from src.config.models import ConfigValue
from src.server.models import ServerConfig
from src.server.sessionhandler import SESSIONS
from src.server import initial_setup
@ -123,7 +123,7 @@ class Evennia(object):
This attempts to run the initial_setup script of the server.
It returns if this is not the first time the server starts.
"""
last_initial_setup_step = ConfigValue.objects.conf('last_initial_setup_step')
last_initial_setup_step = ServerConfig.objects.conf('last_initial_setup_step')
if not last_initial_setup_step:
# None is only returned if the config does not exist,
# i.e. this is an empty DB that needs populating.

View file

@ -17,7 +17,7 @@ registering themselves with this module.
"""
from django.conf import settings
from django.contrib.auth.models import User
from src.config.models import ConfigValue
from src.server.models import ServerConfig
ALLOW_MULTISESSION = settings.ALLOW_MULTISESSION
@ -144,15 +144,15 @@ class SessionHandler(object):
"""
if num == None:
# show the current value. This also syncs it.
return int(ConfigValue.objects.conf('nr_sessions', default=0))
return int(ServerConfig.objects.conf('nr_sessions', default=0))
elif num == 0:
# reset value to 0
ConfigValue.objects.conf('nr_sessions', 0)
ServerConfig.objects.conf('nr_sessions', 0)
else:
# add/remove session count from value
add = int(ConfigValue.objects.conf('nr_sessions', default=0))
add = int(ServerConfig.objects.conf('nr_sessions', default=0))
num = max(0, num + add)
ConfigValue.objects.conf('nr_sessions', str(num))
ServerConfig.objects.conf('nr_sessions', str(num))
def player_count(self):
"""

View file

@ -412,7 +412,7 @@ INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.flatpages',
'src.config',
'src.server',
'src.players',
'src.objects',
'src.comms',

View file

@ -32,7 +32,6 @@ from src.players.models import PlayerDB
from src.scripts.models import ScriptDB
from src.comms.models import Msg, Channel
from src.help.models import HelpEntry
from src.config.models import ConfigValue
#
# Search objects as a character
@ -134,19 +133,3 @@ channels = Channel.objects.channel_search
# """
helpentries = HelpEntry.objects.search_help
#
# Get a configuration value
#
# OBS - this returns a unique value (or None),
# not a list!
#
# def config_search(self, ostring):
# """
# Retrieve a configuration value.
# ostring - a (unique) configuration key
# """
configvalue = ConfigValue.objects.config_search

View file

@ -11,7 +11,7 @@ from django.template import RequestContext
from django.contrib.auth.models import User
from django.conf import settings
from src.config.models import ConfigValue
from src.server.models import ServerConfig
from src.objects.models import ObjectDB
from src.typeclasses.models import TypedObject
from src.players.models import PlayerDB
@ -38,7 +38,7 @@ def page_index(request):
"page_title": "Front Page",
"news_entries": news_entries,
"players_connected_recent": recent_users,
"num_players_connected": ConfigValue.objects.conf('nr_sessions'),#len(PlayerDB.objects.get_connected_players()),
"num_players_connected": ServerConfig.objects.conf('nr_sessions'),#len(PlayerDB.objects.get_connected_players()),
"num_players_registered": PlayerDB.objects.num_total_players(),
"num_players_connected_recent": len(PlayerDB.objects.get_recently_connected_players()),
"num_players_registered_recent": len(PlayerDB.objects.get_recently_created_players()),