OBS: run migrations! This changes the Msg model to work with ManyToManyFields rather than with custom string representations for storing multiple receivers or channels. It also expands the Msg object with a "title" field and various filter options. This should make it easier to implement mail-like operations using the comms system.

This commit is contained in:
Griatch 2012-08-30 00:05:00 +02:00
parent 7995c91eee
commit dcc7f29a91
8 changed files with 656 additions and 381 deletions

View file

@ -651,23 +651,20 @@ class CmdPage(MuxCommandOOC):
# this is a MuxCommandOOC, which means caller will be a Player. # this is a MuxCommandOOC, which means caller will be a Player.
caller = self.caller caller = self.caller
character = self.character
# get the messages we've sent # get the messages we've sent (not to channels)
messages_we_sent = list(Msg.objects.get_messages_by_sender(caller)) pages_we_sent = Msg.objects.get_messages_by_sender(caller, exclude_channel_messages=True)
pages_we_sent = [msg for msg in messages_we_sent if msg.receivers]
# get last messages we've got # get last messages we've got
pages_we_got = list(Msg.objects.get_messages_by_receiver(caller)) pages_we_got = Msg.objects.get_messages_by_receiver(caller)
if 'last' in self.switches: if 'last' in self.switches:
if pages_we_sent: if pages_we_sent:
string = "You last paged {c%s{n." % (", ".join([obj.name recv = ",".join(obj.key for obj in pages_we_sent[-1].receivers)
for obj in pages_we_sent[-1].receivers])) caller.msg("You last paged {c%s{n:%s" % (recv, pages_we_sent[-1].message))
caller.msg(string)
return return
else: else:
string = "You haven't paged anyone yet." caller.msg("You haven't paged anyone yet.")
caller.msg(string)
return return
if not self.args or not self.rhs: if not self.args or not self.rhs:
@ -687,11 +684,11 @@ class CmdPage(MuxCommandOOC):
else: else:
lastpages = pages lastpages = pages
lastpages = "\n ".join(["{w%s{n {c%s{n to {c%s{n: %s" % (utils.datetime_format(page.date_sent), lastpages = "\n ".join("{w%s{n {c%s{n to {c%s{n: %s" % (utils.datetime_format(page.date_sent),
page.sender.name, ",".join(obj.key for obj in page.senders),
"{n,{c ".join([obj.name for obj in page.receivers]), "{n,{c ".join([obj.name for obj in page.receivers]),
page.message) page.message)
for page in lastpages]) for page in lastpages)
if lastpages: if lastpages:
string = "Your latest pages:\n %s" % lastpages string = "Your latest pages:\n %s" % lastpages
@ -705,7 +702,7 @@ class CmdPage(MuxCommandOOC):
if not self.lhs: if not self.lhs:
# If there are no targets, then set the targets # If there are no targets, then set the targets
# to the last person they paged. # to the last person we paged.
if pages_we_sent: if pages_we_sent:
receivers = pages_we_sent[-1].receivers receivers = pages_we_sent[-1].receivers
else: else:
@ -723,9 +720,10 @@ class CmdPage(MuxCommandOOC):
else: else:
caller.msg("Who do you want to page?") caller.msg("Who do you want to page?")
return return
recobjs.append(pobj) if pobj:
recobjs.append(pobj)
if not recobjs: if not recobjs:
caller.msg("No players matching your target were found.") caller.msg("Noone found to page.")
return return
header = "{wPlayer{n {c%s{n {wpages:{n" % caller.key header = "{wPlayer{n {c%s{n {wpages:{n" % caller.key
@ -736,8 +734,8 @@ class CmdPage(MuxCommandOOC):
message = "%s %s" % (caller.key, message.strip(':').strip()) message = "%s %s" % (caller.key, message.strip(':').strip())
# create the persistent message object # create the persistent message object
msg = create.create_message(caller, message, create.create_message(caller, message,
receivers=recobjs) receivers=recobjs)
# tell the players they got a message. # tell the players they got a message.
received = [] received = []

View file

@ -85,8 +85,9 @@ class ChannelCommand(command.Command):
except AttributeError: except AttributeError:
# this could happen if a player is calling directly. # this could happen if a player is calling directly.
sender = caller.dbobj sender = caller.dbobj
msgobj = Msg(db_sender=sender, db_message=msg) msgobj = Msg(db_message=msg)
msgobj.save() msgobj.save()
msgobj.senders = sender
msgobj.channels = channel msgobj.channels = channel
# send new message object to channel # send new message object to channel
channel.msg(msgobj, from_obj=sender) channel.msg(msgobj, from_obj=sender)

View file

@ -4,14 +4,70 @@ These managers handles the
import itertools import itertools
from django.db import models from django.db import models
from django.db.models import Q
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from src.utils.utils import is_iter
_PlayerDB = None
_ObjectDB = None
_Channel = None
_ExternalConnection = None
_User = None
# error class
class CommError(Exception): class CommError(Exception):
"Raise by comm system, to allow feedback to player when caught." "Raise by comm system, to allow feedback to player when caught."
pass pass
# helper function #
# helper functions
#
def dbref(dbref):
"""
Valid forms of dbref (database reference number)
are either a string '#N' or an integer N.
Output is the integer part.
"""
if isinstance(dbref, basestring):
dbref = dbref.lstrip('#')
try:
if int(dbref) < 0:
return None
except Exception:
return None
return dbref
def identify_object(inp):
"identify if an object is a player or an object; return its database model"
# load global stores
global _PlayerDB, _ObjectDB, _Channel, _ExternalConnection, _User
if not _PlayerDB:
from src.players.models import PlayerDB as _PlayerDB
if not _ObjectDB:
from src.objects.models import ObjectDB as _ObjectDB
if not _Channel:
from src.comms.models import Channel as _Channel
if not _ExternalConnection:
from src.comms.models import ExternalChannelConnection as _ExternalConnection
if not _User:
from django.contrib.auth.models import User as _User
if not inp:
return inp, None
# try to identify the type
try:
obj = inp.dbobj # this works for all typeclassed entities
except AttributeError:
obj = inp
typ = type(obj)
if typ == _PlayerDB: return obj, "player"
if typ == _User: return obj.get_profile(), "player"
elif typ == _ObjectDB: return obj, "object"
elif typ == _Channel: return obj, "channel"
elif dbref(obj): return dbref(obj), "dbref"
elif typ == basestring: return obj, "string"
elif typ == _ExternalConnection: return obj, "external"
return obj, None # Something else
def to_object(inp, objtype='player'): def to_object(inp, objtype='player'):
""" """
@ -21,34 +77,31 @@ def to_object(inp, objtype='player'):
inp - the input object/string inp - the input object/string
objtype - 'player' or 'channel' objtype - 'player' or 'channel'
""" """
from src.players.models import PlayerDB obj, typ = identify_object(inp)
if typ == objtype:
return obj
if objtype == 'player': if objtype == 'player':
if type(inp) == PlayerDB: if typ == 'object': return obj.player
return inp if typ == 'string': return _PlayerDB.objects.get(user_username__iexact=obj)
if hasattr(inp, 'player'): if typ == 'dbref': return _PlayerDB.objects.get(id=obj)
return inp.player print objtype, inp, obj, typ, type(inp)
else: raise CommError()
umatch = PlayerDB.objects.filter(user__username__iexact=inp) elif objtype == 'object':
if umatch: if typ == 'player': return obj.obj
return umatch[0] if typ == 'string': return _ObjectDB.objects.get(db_key__iexact=obj)
if typ == 'dbref': return _ObjectDB.objects.get(id=obj)
print objtype, inp, obj, typ, type(inp)
raise CommError()
elif objtype == 'channel':
if typ == 'string': return _Channel.objects.get(db_key__iexact=obj)
if typ == 'dbref': return _Channel.objects.get(id=obj)
print objtype, inp, obj, typ, type(inp)
raise CommError()
elif objtype == 'external': elif objtype == 'external':
from src.comms.models import ExternalChannelConnection if typ == 'string': return _ExternalConnection.objects.get(db_key=inp)
if type (inp) == ExternalChannelConnection: if typ == 'dbref': return _ExternalConnection.objects.get(id=obj)
return inp print objtype, inp, obj, typ, type(inp)
umatch = ExternalChannelConnection.objects.filter(db_key=inp) raise CommError()
if umatch:
return umatch[0]
else:
# have to import this way to avoid circular imports
from src.comms.models import Channel
#= ContentType.objects.get(app_label="comms",
# model="channel").model_class()
if type(inp) == Channel:
return inp
cmatch = Channel.objects.filter(db_key__iexact=inp)
if cmatch:
return cmatch[0]
return None
# #
# Msg manager # Msg manager
@ -76,106 +129,68 @@ class MsgManager(models.Manager):
message_search (equivalent to ev.search_messages) message_search (equivalent to ev.search_messages)
""" """
def identify_object(self, obj):
"method version for easy access"
return identify_object(obj)
def get_message_by_id(self, idnum): def get_message_by_id(self, idnum):
"Retrieve message by its id." "Retrieve message by its id."
try: try:
idnum = int(idnum) return self.get(id=self.dbref(idnum))
return self.get(id=idnum)
except Exception: except Exception:
return None return None
def get_messages_by_sender(self, player): def get_messages_by_sender(self, obj, exclude_channel_messages=False):
""" """
Get all messages sent by one player Get all messages sent by one entity - this could be either a player or an object
"""
player = to_object(player, objtype='player')
if not player:
return None
return self.filter(db_sender=player).exclude(db_hide_from_sender=True)
def get_messages_by_receiver(self, receiver): only_non_channel: only return messages -not- aimed at a channel (e.g. private tells)
""" """
Get all messages sent to one player obj, typ = identify_object(obj)
if exclude_channel_messages:
# explicitly exclude channel recipients
if typ == 'player':
return list(self.filter(db_sender_players=obj, db_receivers_channels__isnull=True).exclude(db_hide_from_players=obj))
elif typ == 'object':
return list(self.filter(db_sender_objects=obj, db_receivers_channels__isnull=True).exclude(db_hide_from_objects=obj))
else:
raise CommError
else:
# get everything, channel or not
if typ == 'player':
return list(self.filter(db_sender_players=obj).exclude(db_hide_from_players=obj))
elif typ == 'object':
return list(self.filter(db_sender_objects=obj).exclude(db_hide_from_objects=obj))
else:
raise CommError
def get_messages_by_receiver(self, obj):
""" """
receiver = to_object(receiver) Get all messages sent to one give recipient
if not receiver: """
return None obj, typ = identify_object(obj)
return [msg for msg in self.all() if typ == 'player':
if receiver in msg.receivers return list(self.filter(db_receivers_players=obj).exclude(db_hide_from_players=obj))
and receiver not in msg.hide_from_receivers] elif typ == 'object':
return list(self.filter(db_receivers_objects=obj).exclude(db_hide_from_objects=obj))
elif typ == 'channel':
return list(self.filter(db_receivers_channels=obj).exclude(db_hide_from_channels=obj))
else:
raise CommError
def get_messages_by_channel(self, channel): def get_messages_by_channel(self, channel):
""" """
Get all messages sent to one channel Get all messages sent to one channel
""" """
channel = to_object(channel, objtype='channel') return self.filter(db_receivers_channels=channel).exclude(db_hide_from_channels=channel)
if not channel:
return None
return [msg for msg in self.all()
if channel in msg.channels
and channel not in msg.hide_from_channels]
#TODO add search limited by send_times def message_search(self, sender=None, receiver=None, freetext=None, dbref=None):
def text_search(self, searchstring, filterdict=None):
"""
Returns all messages that contain the matching
search string. To avoid too many results, and also
since this can be a very computing-
heavy operation, it's recommended to be filtered
by at least channel or sender/receiver.
searchstring - string to search for
filterdict -
{'channels':[list],
'senders':[list],
'receivers':[list]}
lists can contain either the name/keys of the
objects or the actual objects to filter by.
"""
if filterdict:
# obtain valid objects for all filters
channels = [chan for chan in
[to_object(chan, objtype='channel')
for chan in filterdict.get('channels',[])]
if chan]
senders = [sender for sender in
[to_object(sender)
for sender in filterdict.get('senders',[])]
if sender]
receivers = [receiver for receiver in
[to_object(receiver)
for receiver in filterdict.get('receivers',[])]
if receiver]
# filter the messages lazily using the filter objects
msgs = []
for sender in senders:
msgs = list(sender.message_set.filter(
db_message__icontains=searchstring))
for receiver in receivers:
rec_msgs = receiver.message_set.filter(
db_message__icontains=searchstring)
if msgs:
msgs = [msg for msg in rec_msgs if msg in msgs]
else:
msgs = rec_msgs
for channel in channels:
chan_msgs = list(channel.message_set.filter(
db_message__icontains=searchstring))
if msgs:
msgs = [msg for msg in chan_msgs if msg in msgs]
else:
msgs = chan_msgs
return list(set(msgs))
return list(self.all().filter(db_message__icontains=searchstring))
def message_search(self, sender=None, receiver=None, channel=None, freetext=None, dbref=None):
""" """
Search the message database for particular messages. At least one Search the message database for particular messages. At least one
of the arguments must be given to do a search. of the arguments must be given to do a search.
sender - get messages sent by a particular player sender - get messages sent by a particular player or object
receiver - get messages received by a certain player or players receiver - get messages received by a certain player,object or channel
channel - get messages sent to a particular channel or channels
freetext - Search for a text string in a message. freetext - Search for a text string in a message.
NOTE: This can potentially be slow, so make sure to supply NOTE: This can potentially be slow, so make sure to supply
one of the other arguments to limit the search. one of the other arguments to limit the search.
@ -183,35 +198,41 @@ class MsgManager(models.Manager):
all other search crieteria since it's unique and all other search crieteria since it's unique and
always gives a list with only one match. always gives a list with only one match.
""" """
# unique msg id
if dbref: if dbref:
return self.filter(id=dbref) msg = self.objects.filter(id=dbref)
if msg:
return msg[0]
# We use Q objects to gradually build up the query - this way we only need to do one
# database lookup at the end rather than gradually refining with multiple filter:s.
# Django Note: Q objects can be combined with & and | (=AND,OR). ~ negates the queryset
# filter by sender
sender, styp = identify_object(sender)
if styp == 'player':
sender_restrict = Q(db_sender_players=sender) & ~Q(db_hide_from_players=sender)
elif styp == 'object':
sender_restrict = Q(db_sender_objects=sender) & ~Q(db_hide_from_objects=sender)
else:
sender_restrict = Q()
# filter by receiver
receiver, rtyp = identify_object(receiver)
if rtyp == 'player':
receiver_restrict = Q(db_receivers_players=receiver) & ~Q(db_hide_from_players=receiver)
elif rtyp == 'object':
receiver_restrict = Q(db_receivers_objects=receiver) & ~Q(db_hide_from_objects=receiver)
elif rtyp == 'channel':
receiver_restrict = Q(db_receivers_channels=receiver) & ~Q(db_hide_from_channels=receiver)
else:
receiver_restrict = Q()
# filter by full text
if freetext: if freetext:
if sender: fulltext_restrict = Q(db_title__icontains=freetext) | Q(db_message__icontains=freetext)
sender = [sender] else:
if receiver and not is_iter(receiver): fulltext_restrict = Q()
receiver = [receiver] # execute the query
if channel and not is_iter(channel): return list(self.filter(sender_restrict & receiver_restrict & fulltext_restrict))
channel = [channel]
filterdict = {"senders":sender,
"receivers":receiver,
"channels":channel}
return self.textsearch(freetext, filterdict)
msgs = []
if sender:
msgs = self.get_messages_by_sender(sender)
if receiver:
rec_msgs = self.get_messages_by_receiver(receiver)
if msgs:
msgs = [msg for msg in rec_msgs if msg in msgs]
else:
msgs = rec_msgs
if channel:
chan_msgs = self.get_messaqge_by_channel(channel)
if msgs:
msgs = [msg for msg in chan_msgs if msg in msgs]
else:
msgs = chan_msgs
return msgs
# #
# Channel manager # Channel manager
@ -339,10 +360,8 @@ class PlayerChannelConnectionManager(models.Manager):
player = to_object(player) player = to_object(player)
return self.filter(db_player=player) return self.filter(db_player=player)
def has_connection(self, player, channel): def has_player_connection(self, player, channel):
"Checks so a connection exists player<->channel" "Checks so a connection exists player<->channel"
player = to_object(player)
channel = to_object(channel, objtype="channel")
if player and channel: if player and channel:
return self.filter(db_player=player).filter(db_channel=channel).count() > 0 return self.filter(db_player=player).filter(db_channel=channel).count() > 0
return False return False

View file

@ -0,0 +1,283 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from south import orm
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting field 'Msg.db_hide_from_channels'
db.delete_column('comms_msg', 'db_hide_from_channels')
# Deleting field 'Msg.db_hide_from_receivers'
db.delete_column('comms_msg', 'db_hide_from_receivers')
# Deleting field 'Msg.db_receivers'
db.delete_column('comms_msg', 'db_receivers')
# Deleting field 'Msg.db_channels'
db.delete_column('comms_msg', 'db_channels')
# Deleting field 'Msg.db_hide_from_sender'
db.delete_column('comms_msg', 'db_hide_from_sender')
# Deleting field 'Msg.db_sender'
db.delete_column('comms_msg', 'db_sender_id')
# Adding field 'Msg.db_title'
db.add_column('comms_msg', 'db_title',
self.gf('django.db.models.fields.CharField')(db_index=True, max_length=512, null=True, blank=True),
keep_default=False)
# Adding M2M table for field db_sender_players on 'Msg'
db.create_table('comms_msg_db_sender_players', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('playerdb', models.ForeignKey(orm['players.playerdb'], null=False))
))
db.create_unique('comms_msg_db_sender_players', ['msg_id', 'playerdb_id'])
# Adding M2M table for field db_sender_objects on 'Msg'
db.create_table('comms_msg_db_sender_objects', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('objectdb', models.ForeignKey(orm['objects.objectdb'], null=False))
))
db.create_unique('comms_msg_db_sender_objects', ['msg_id', 'objectdb_id'])
# Adding M2M table for field db_receivers_players on 'Msg'
db.create_table('comms_msg_db_receivers_players', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('playerdb', models.ForeignKey(orm['players.playerdb'], null=False))
))
db.create_unique('comms_msg_db_receivers_players', ['msg_id', 'playerdb_id'])
# Adding M2M table for field db_receivers_objects on 'Msg'
db.create_table('comms_msg_db_receivers_objects', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('objectdb', models.ForeignKey(orm['objects.objectdb'], null=False))
))
db.create_unique('comms_msg_db_receivers_objects', ['msg_id', 'objectdb_id'])
# Adding M2M table for field db_receivers_channels on 'Msg'
db.create_table('comms_msg_db_receivers_channels', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('channel', models.ForeignKey(orm['comms.channel'], null=False))
))
db.create_unique('comms_msg_db_receivers_channels', ['msg_id', 'channel_id'])
# Adding M2M table for field db_hide_from_players on 'Msg'
db.create_table('comms_msg_db_hide_from_players', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('playerdb', models.ForeignKey(orm['players.playerdb'], null=False))
))
db.create_unique('comms_msg_db_hide_from_players', ['msg_id', 'playerdb_id'])
# Adding M2M table for field db_hide_from_objects on 'Msg'
db.create_table('comms_msg_db_hide_from_objects', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('objectdb', models.ForeignKey(orm['objects.objectdb'], null=False))
))
db.create_unique('comms_msg_db_hide_from_objects', ['msg_id', 'objectdb_id'])
# Adding M2M table for field db_hide_from_channles on 'Msg'
db.create_table('comms_msg_db_hide_from_channles', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('msg', models.ForeignKey(orm['comms.msg'], null=False)),
('channel', models.ForeignKey(orm['comms.channel'], null=False))
))
db.create_unique('comms_msg_db_hide_from_channles', ['msg_id', 'channel_id'])
# Adding index on 'Msg', fields ['db_date_sent']
db.create_index('comms_msg', ['db_date_sent'])
# Adding index on 'Msg', fields ['db_sender_external']
db.create_index('comms_msg', ['db_sender_external'])
# moving data to new fields
if not db.dry_run:
if orm["comms.Msg"].objects.count():
print "deleting old Msgs before migrating ..."
for msg in orm["comms.Msg"].objects.all():
msg.delete()
def backwards(self, orm):
# Removing index on 'Msg', fields ['db_sender_external']
db.delete_index('comms_msg', ['db_sender_external'])
# Removing index on 'Msg', fields ['db_date_sent']
db.delete_index('comms_msg', ['db_date_sent'])
# Adding field 'Msg.db_hide_from_channels'
db.add_column('comms_msg', 'db_hide_from_channels',
self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
keep_default=False)
# Adding field 'Msg.db_hide_from_receivers'
db.add_column('comms_msg', 'db_hide_from_receivers',
self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
keep_default=False)
# Adding field 'Msg.db_receivers'
db.add_column('comms_msg', 'db_receivers',
self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
keep_default=False)
# Adding field 'Msg.db_channels'
db.add_column('comms_msg', 'db_channels',
self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
keep_default=False)
# Adding field 'Msg.db_hide_from_sender'
db.add_column('comms_msg', 'db_hide_from_sender',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
# Adding field 'Msg.db_sender'
db.add_column('comms_msg', 'db_sender',
self.gf('django.db.models.fields.related.ForeignKey')(related_name='sender_set', null=True, to=orm['players.PlayerDB']),
keep_default=False)
# Deleting field 'Msg.db_title'
db.delete_column('comms_msg', 'db_title')
# Removing M2M table for field db_sender_players on 'Msg'
db.delete_table('comms_msg_db_sender_players')
# Removing M2M table for field db_sender_objects on 'Msg'
db.delete_table('comms_msg_db_sender_objects')
# Removing M2M table for field db_receivers_players on 'Msg'
db.delete_table('comms_msg_db_receivers_players')
# Removing M2M table for field db_receivers_objects on 'Msg'
db.delete_table('comms_msg_db_receivers_objects')
# Removing M2M table for field db_receivers_channels on 'Msg'
db.delete_table('comms_msg_db_receivers_channels')
# Removing M2M table for field db_hide_from_players on 'Msg'
db.delete_table('comms_msg_db_hide_from_players')
# Removing M2M table for field db_hide_from_objects on 'Msg'
db.delete_table('comms_msg_db_hide_from_objects')
# Removing M2M table for field db_hide_from_channles on 'Msg'
db.delete_table('comms_msg_db_hide_from_channles')
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'})
},
'comms.channel': {
'Meta': {'object_name': 'Channel'},
'db_aliases': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'db_desc': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
'db_keep_log': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'comms.externalchannelconnection': {
'Meta': {'object_name': 'ExternalChannelConnection'},
'db_channel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['comms.Channel']"}),
'db_external_config': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_external_key': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'db_external_send_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_is_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'comms.msg': {
'Meta': {'object_name': 'Msg'},
'db_date_sent': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'db_hide_from_channles': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_channels_set'", 'null': 'True', 'to': "orm['comms.Channel']"}),
'db_hide_from_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_objects_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
'db_hide_from_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_players_set'", 'null': 'True', 'to': "orm['players.PlayerDB']"}),
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
'db_message': ('django.db.models.fields.TextField', [], {}),
'db_receivers_channels': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'channel_set'", 'null': 'True', 'to': "orm['comms.Channel']"}),
'db_receivers_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'receiver_object_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
'db_receivers_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'receiver_player_set'", 'null': 'True', 'to': "orm['players.PlayerDB']"}),
'db_sender_external': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
'db_sender_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'sender_object_set'", 'null': 'True', 'db_index': 'True', 'to': "orm['objects.ObjectDB']"}),
'db_sender_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'sender_player_set'", 'null': 'True', 'db_index': 'True', 'to': "orm['players.PlayerDB']"}),
'db_title': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '512', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'comms.playerchannelconnection': {
'Meta': {'object_name': 'PlayerChannelConnection'},
'db_channel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['comms.Channel']"}),
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'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.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'})
},
'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_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 = ['comms']

View file

@ -1,7 +1,12 @@
""" """
Models for the comsystem. Models for the comsystem. The Commsystem is intended to be
used by Players (thematic IC communication is probably
best handled by custom commands instead).
The comsystem's main component is the Message, which The comm system could take the form of channels, but can also
be adopted for storing tells or in-game mail.
The comsystem's main component is the Message (Msg), which
carries the actual information between two parties. carries the actual information between two parties.
Msgs are stored in the database and usually not Msgs are stored in the database and usually not
deleted. deleted.
@ -17,46 +22,12 @@ be able to delete connections on the fly).
from django.db import models from django.db import models
from src.utils.idmapper.models import SharedMemoryModel from src.utils.idmapper.models import SharedMemoryModel
from src.comms import managers from src.comms import managers
from src.comms.managers import identify_object
from src.locks.lockhandler import LockHandler from src.locks.lockhandler import LockHandler
from src.utils import logger from src.utils import logger
from src.utils.utils import is_iter, to_str from src.utils.utils import is_iter, to_str, crop
from src.utils.utils import dbref as is_dbref
__all__ = ("Msg", "TempMsg", "Channel", "PlayerChannelConnection", "ExternalChannelConnection") __all__ = ("Msg", "TempMsg", "Channel", "PlayerChannelConnection", "ExternalChannelConnection")
#------------------------------------------------------------
#
# Utils
#
#------------------------------------------------------------
def _obj_to_id(inp):
"""
Converts input object to an id string.
"""
dbref = is_dbref(inp)
if dbref:
return str(dbref)
if hasattr(inp, 'id'):
return str(inp.id)
if hasattr(inp, 'dbobj') and hasattr(inp.dbobj, 'id'):
return str(inp.dbobj.id)
return str(inp)
def _id_to_obj(dbref, db_model='PlayerDB'):
"""
loads from dbref to object. Uses the db_model to search
for the id.
"""
if db_model == 'PlayerDB':
from src.players.models import PlayerDB as db_model
else:
db_model = Channel
try:
dbref = int(dbref.strip())
return db_model.objects.get(id=dbref)
except Exception:
return None
#------------------------------------------------------------ #------------------------------------------------------------
# #
# Msg # Msg
@ -87,37 +58,50 @@ class Msg(SharedMemoryModel):
# These databse fields are all set using their corresponding properties, # These databse fields are all set using their corresponding properties,
# named same as the field, but withtout the db_* prefix. # named same as the field, but withtout the db_* prefix.
# There must always be one sender of the message. # Sender is either a player, an object or an external sender, like an IRC channel
db_sender = models.ForeignKey("players.PlayerDB", related_name='sender_set', null=True, verbose_name='sender') # normally there is only one, but if co-modification of a message is allowed, there
# in the case of external senders, no Player object might be available # may be more than one "author"
db_sender_external = models.CharField('external sender', max_length=255, null=True, blank=True, db_sender_players = models.ManyToManyField("players.PlayerDB", related_name='sender_player_set', null=True, verbose_name='sender(player)', db_index=True)
db_sender_objects = models.ManyToManyField("objects.ObjectDB", related_name='sender_object_set', null=True, verbose_name='sender(object)', db_index=True)
db_sender_external = models.CharField('external sender', max_length=255, null=True, db_index=True,
help_text="identifier for external sender, for example a sender over an IRC connection (i.e. someone who doesn't have an exixtence in-game).") help_text="identifier for external sender, for example a sender over an IRC connection (i.e. someone who doesn't have an exixtence in-game).")
# The destination objects of this message. Stored as a # The destination objects of this message. Stored as a
# comma-separated string of object dbrefs. Can be defined along # comma-separated string of object dbrefs. Can be defined along
# with channels below. # with channels below.
db_receivers = models.CharField('receivers', max_length=255, null=True, blank=True, db_receivers_players = models.ManyToManyField('players.PlayerDB', related_name='receiver_player_set', null=True, help_text="player receivers")
help_text='comma-separated list of object dbrefs this message is aimed at.') db_receivers_objects = models.ManyToManyField('objects.ObjectDB', related_name='receiver_object_set', null=True, help_text="object receivers")
# The channels this message was sent to. Stored as a db_receivers_channels = models.ManyToManyField("Channel", related_name='channel_set', null=True, help_text="channel recievers")
# comma-separated string of channel dbrefs. A message can both
# have channel targets and destination objects.
db_channels = models.CharField('channels', max_length=255, null=True, blank=True,
help_text='comma-separated list of channel dbrefs this message is aimed at.')
# The actual message and a timestamp. The message field # The actual message and a timestamp. The message field
# should itself handle eventual headers etc. # should itself handle eventual headers etc.
db_title = models.CharField('title', max_length=512, null=True, blank=True, db_index=True)
db_message = models.TextField('messsage') db_message = models.TextField('messsage')
db_date_sent = models.DateTimeField('date sent', editable=False, auto_now_add=True) db_date_sent = models.DateTimeField('date sent', editable=False, auto_now_add=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,
help_text='access locks on this message.') help_text='access locks on this message.')
# These are settable by senders/receivers/channels respectively.
# Stored as a comma-separated string of dbrefs. Can be used by the # these can be used to filter/hide a given message from supplied objects/players/channels
# game to mask out messages from being visible in the archive (no db_hide_from_players = models.ManyToManyField("players.PlayerDB", related_name='hide_from_players_set', null=True)
# messages are actually deleted) db_hide_from_objects = models.ManyToManyField("objects.ObjectDB", related_name='hide_from_objects_set', null=True)
db_hide_from_sender = models.BooleanField(default=False) db_hide_from_channles = models.ManyToManyField("Channel", related_name='hide_from_channels_set', null=True)
db_hide_from_receivers = models.CharField(max_length=255, null=True, blank=True)
db_hide_from_channels = models.CharField(max_length=255, null=True, blank=True) ## These are settable by senders/receivers/channels respectively.
# Storage of lock strings ## Stored as a comma-separated string of dbrefs. Can be used by the
#db_lock_storage = models.TextField(null=True) ## game to mask out messages from being visible in the archive (no
## messages are actually deleted)
#db_hide_from_sender = models.BooleanField(default=False)
#db_hide_from_receivers = models.CharField(max_length=255, null=True, blank=True)
#db_hide_from_channels = models.CharField(max_length=255, null=True, blank=True)
## Storage of lock strings
##db_receivers = models.CharField('receivers', max_length=255, null=True, blank=True,
## help_text='comma-separated list of object dbrefs this message is aimed at.')
### The channels this message was sent to. Stored as a
### comma-separated string of channel dbrefs. A message can both
### have channel targets and destination objects.
##db_channels = models.CharField('channels', max_length=255, null=True, blank=True,
## help_text='comma-separated list of channel dbrefs this message is aimed at.')
# Database manager # Database manager
objects = managers.MsgManager() objects = managers.MsgManager()
@ -138,80 +122,120 @@ class Msg(SharedMemoryModel):
# value = self.attr and del self.attr respectively (where self # value = self.attr and del self.attr respectively (where self
# is the object in question). # is the object in question).
# sender property (wraps db_sender) # sender property (wraps db_sender_*)
#@property #@property
def __sender_get(self): def __senders_get(self):
"Getter. Allows for value = self.sender" "Getter. Allows for value = self.sender"
return self.db_sender return list(self.db_sender_players.all()) + list(self.db_sender_objects.all())
#@sender.setter #@sender.setter
def __sender_set(self, value): def __senders_set(self, value):
"Setter. Allows for self.sender = value" "Setter. Allows for self.sender = value"
self.db_sender = value obj, typ = identify_object(value)
if typ == 'player':
self.db_sender_players.add(obj)
elif typ == 'object':
self.db_sender_objects.add(obj)
elif isinstance(typ, basestring):
self.db_sender_external = obj
elif not obj:
return
else:
raise ValueError
self.save() self.save()
#@sender.deleter #@sender.deleter
def __sender_del(self): def __senders_del(self):
"Deleter. Allows for del self.sender" "Deleter. Clears all senders"
raise Exception("You cannot delete the sender of a message!") self.db_sender_players.clear()
sender = property(__sender_get, __sender_set, __sender_del) self.db_sender_objects.clear()
self.db_sender_external = ""
# sender_external property (wraps db_sender_external) self.save()
#@property senders = property(__senders_get, __senders_set, __senders_del)
def __sender_external_get(self):
"Getter. Allows for value = self.sender_external" def remove_sender(self, obj):
return self.db_sender_external "Remove a single sender"
#@sender_external.setter obj, typ = identify_object(obj)
def __sender_external_set(self, value): if typ == 'player':
"Setter. Allows for self.sender_external = value" self.db_sender_players.remove(obj)
self.db_sender_external = value elif typ == 'object':
self.db_sender_objects.remove(obj)
elif isinstance(obj, basestring) and self.db_sender_external == obj:
self.db_sender_external = ""
else:
raise ValueError
self.save() self.save()
#@sender_external.deleter
def __sender_external_del(self):
"Deleter. Allows for del self.sender_external"
raise Exception("You cannot delete the sender_external of a message!")
sender_external = property(__sender_external_get, __sender_external_set, __sender_external_del)
# receivers property # receivers property
#@property #@property
def __receivers_get(self): def __receivers_get(self):
"Getter. Allows for value = self.receivers. Returns a list of receivers." "Getter. Allows for value = self.receivers. Returns three lists of receivers: players, objects and channels."
if self.db_receivers: return list(self.db_receivers_players.all()) + list(self.db_receivers_objects.all())
return [_id_to_obj(dbref) for dbref in self.db_receivers.split(',')]
return []
#@receivers.setter #@receivers.setter
def __receivers_set(self, value): def __receivers_set(self, value):
"Setter. Allows for self.receivers = value. Stores as a comma-separated string." "Setter. Allows for self.receivers = value. This appends a new receiver to the message."
if is_iter(value): obj, typ = identify_object(value)
value = ",".join([_obj_to_id(val) for val in value]) if typ == 'player':
self.db_receivers = _obj_to_id(value) self.db_receivers_players.add(obj)
elif typ == 'object':
self.db_receivers_objects.add(obj)
elif not obj:
return
else:
raise ValueError
self.save() self.save()
#@receivers.deleter #@receivers.deleter
def __receivers_del(self): def __receivers_del(self):
"Deleter. Allows for del self.receivers" "Deleter. Clears all receivers"
self.db_receivers = "" self.db_receivers_players.clear()
self.db_receivers_objects.clear()
self.save() self.save()
receivers = property(__receivers_get, __receivers_set, __receivers_del) receivers = property(__receivers_get, __receivers_set, __receivers_del)
def remove_receiver(self, obj):
"Remove a single recevier"
obj, typ = identify_object(obj)
if typ == 'player':
self.db_receivers_players.remove(obj)
elif typ == 'object':
self.db_receivers_objects.remove(obj)
else:
raise ValueError
self.save()
# channels property # channels property
#@property #@property
def __channels_get(self): def __channels_get(self):
"Getter. Allows for value = self.channels. Returns a list of channels." "Getter. Allows for value = self.channels. Returns a list of channels."
if self.db_channels: return self.db_receivers_channels.all()
return [_id_to_obj(dbref, 'Channel') for dbref in self.db_channels.split(',')]
return []
#@channels.setter #@channels.setter
def __channels_set(self, value): def __channels_set(self, value):
"Setter. Allows for self.channels = value. Stores as a comma-separated string." "Setter. Allows for self.channels = value. Requires a channel to be added."
if is_iter(value): if value:
value = ",".join([_obj_to_id(val) for val in value]) self.db_receivers_channels.add(value)
self.db_channels = _obj_to_id(value)
self.save()
#@channels.deleter #@channels.deleter
def __channels_del(self): def __channels_del(self):
"Deleter. Allows for del self.channels" "Deleter. Allows for del self.channels"
self.db_channels = "" self.db_receivers_channels.clear()
self.save() self.save()
channels = property(__channels_get, __channels_set, __channels_del) channels = property(__channels_get, __channels_set, __channels_del)
# title property (wraps db_title)
#@property
def __title_get(self):
"Getter. Allows for value = self.message"
return self.db_title
#@message.setter
def __title_set(self, value):
"Setter. Allows for self.message = value"
if value:
self.db_title = value
self.save()
#@message.deleter
def __title_del(self):
"Deleter. Allows for del self.message"
self.db_title = ""
self.save()
title = property(__title_get, __title_set, __title_del)
# message property (wraps db_message) # message property (wraps db_message)
#@property #@property
def __message_get(self): def __message_get(self):
@ -244,64 +268,32 @@ class Msg(SharedMemoryModel):
raise Exception("You cannot delete the date_sent property!") raise Exception("You cannot delete the date_sent property!")
date_sent = property(__date_sent_get, __date_sent_set, __date_sent_del) date_sent = property(__date_sent_get, __date_sent_set, __date_sent_del)
# hide_from_sender property # hide_from property
#@property #@property
def __hide_from_sender_get(self): def __hide_from_get(self):
"Getter. Allows for value = self.hide_from_sender." "Getter. Allows for value = self.hide_from. Returns 3 lists of players, objects and channels"
return self.db_hide_from_sender return self.db_hide_from_players.all(), self.db_hide_from_objects.all(), self.db_hide_from_channels.all()
#@hide_from_sender.setter #@hide_from_sender.setter
def __hide_from_sender_set(self, value): def __hide_from_set(self, value):
"Setter. Allows for self.hide_from_senders = value." "Setter. Allows for self.hide_from = value. Will append to hiders"
self.db_hide_from_sender = value obj, typ = identify_object(value)
if typ == "player":
self.db_hide_from_players.add(obj)
elif typ == "object":
self.db_hide_from_objects.add(obj)
elif typ == "channel":
self.db_hide_from_channels.add(obj)
else:
raise ValueError
self.save() self.save()
#@hide_from_sender.deleter #@hide_from_sender.deleter
def __hide_from_sender_del(self): def __hide_from_del(self):
"Deleter. Allows for del self.hide_from_senders" "Deleter. Allows for del self.hide_from_senders"
self.db_hide_from_sender = False self.db_hide_from_players.clear()
self.db_hide_from_objects.clear()
self.db_hide_from_channels.clear()
self.save() self.save()
hide_from_sender = property(__hide_from_sender_get, __hide_from_sender_set, __hide_from_sender_del) hide_from = property(__hide_from_get, __hide_from_set, __hide_from_del)
# hide_from_receivers property
#@property
def __hide_from_receivers_get(self):
"Getter. Allows for value = self.hide_from_receivers. Returns a list of hide_from_receivers."
if self.db_hide_from_receivers:
return [_id_to_obj(dbref) for dbref in self.db_hide_from_receivers.split(',')]
return []
#@hide_from_receivers.setter
def __hide_from_receivers_set(self, value):
"Setter. Allows for self.hide_from_receivers = value. Stores as a comma-separated string."
if is_iter(value):
value = ",".join([_obj_to_id(val) for val in value])
self.db_hide_from_receivers = _obj_to_id(value)
self.save()
#@hide_from_receivers.deleter
def __hide_from_receivers_del(self):
"Deleter. Allows for del self.hide_from_receivers"
self.db_hide_from_receivers = ""
self.save()
hide_from_receivers = property(__hide_from_receivers_get, __hide_from_receivers_set, __hide_from_receivers_del)
# hide_from_channels property
#@property
def __hide_from_channels_get(self):
"Getter. Allows for value = self.hide_from_channels. Returns a list of hide_from_channels."
if self.db_hide_from_channels:
return [_id_to_obj(dbref) for dbref in self.db_hide_from_channels.split(',')]
return []
#@hide_from_channels.setter
def __hide_from_channels_set(self, value):
"Setter. Allows for self.hide_from_channels = value. Stores as a comma-separated string."
if is_iter(value):
value = ",".join([_obj_to_id(val) for val in value])
self.db_hide_from_channels = _obj_to_id(value)
self.save()
#@hide_from_channels.deleter
def __hide_from_channels_del(self):
"Deleter. Allows for del self.hide_from_channels"
self.db_hide_from_channels = ""
self.save()
hide_from_channels = property(__hide_from_channels_get, __hide_from_channels_set, __hide_from_channels_del)
# lock_storage property (wraps db_lock_storage) # lock_storage property (wraps db_lock_storage)
#@property #@property
@ -326,15 +318,11 @@ class Msg(SharedMemoryModel):
# #
def __str__(self): def __str__(self):
"Print text" "This handles what is shown when e.g. printing the message"
if self.channels: senders = ",".join(obj.key for obj in self.senders)
return "%s -> %s: %s" % (self.sender.key, receivers = ",".join(["[%s]" % obj.key for obj in self.channels] + [obj.key for obj in self.receivers])
", ".join([chan.key for chan in self.channels]), return "%s->%s::%s" % (senders, receivers, crop(self.message, width=40))
self.message)
else:
return "%s -> %s: %s" % (self.sender.key,
", ".join([rec.key for rec in self.receivers]),
self.message)
def access(self, accessing_obj, access_type='read', default=False): def access(self, accessing_obj, access_type='read', default=False):
""" """
Determines if another object has permission to access. Determines if another object has permission to access.
@ -360,13 +348,11 @@ class TempMsg(object):
""" """
def __init__(self, sender=None, receivers=[], channels=[], message="", permissions=[]): def __init__(self, sender=None, receivers=[], channels=[], message="", permissions=[]):
self.sender = sender self.senders = sender
self.receivers = receivers self.receivers = receivers
self.message = message self.message = message
self.permissions = permissions self.permissions = permissions
self.hide_from_sender = False self.hide_from = None
self.hide_from_sender = receivers = False
self.hide_from_channels = False
#------------------------------------------------------------ #------------------------------------------------------------
# #
@ -408,6 +394,7 @@ class Channel(SharedMemoryModel):
# Storage of lock definitions # Storage of lock definitions
db_lock_storage = models.CharField('locks', max_length=512, blank=True) db_lock_storage = models.CharField('locks', max_length=512, blank=True)
# Database manager # Database manager
objects = managers.ChannelManager() objects = managers.ChannelManager()
@ -533,7 +520,7 @@ class Channel(SharedMemoryModel):
Checks so this player is actually listening Checks so this player is actually listening
to this channel. to this channel.
""" """
return PlayerChannelConnection.objects.has_connection(player, self) return PlayerChannelConnection.objects.has_player_connection(player, self)
def msg(self, msgobj, from_obj=None): def msg(self, msgobj, from_obj=None):
""" """
@ -582,7 +569,7 @@ class Channel(SharedMemoryModel):
message - a Msg object or a text string. message - a Msg object or a text string.
""" """
if type(msgobj) == Msg: if type(message) == Msg:
# extract only the string # extract only the string
message = message.message message = message.message
return self.msg(message) return self.msg(message)

View file

@ -21,12 +21,12 @@ Models covered:
Channel Channel
Players Players
""" """
from twisted.internet.defer import inlineCallbacks, returnValue
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import IntegrityError from django.db import IntegrityError
from src.utils.idmapper.models import SharedMemoryModel from src.utils.idmapper.models import SharedMemoryModel
from src.utils import utils, logger from src.utils import utils, logger
from src.utils.utils import make_iter
# delayed imports # delayed imports
_User = None _User = None
@ -306,7 +306,7 @@ help_entry = create_help_entry
# #
def create_message(senderobj, message, channels=None, def create_message(senderobj, message, channels=None,
receivers=None, locks=None): receivers=None, locks=None, title=None):
""" """
Create a new communication message. Msgs are used for all Create a new communication message. Msgs are used for all
player-to-player communication, both between individual players player-to-player communication, both between individual players
@ -326,52 +326,25 @@ def create_message(senderobj, message, channels=None,
at the same time, it's up to the command definitions to limit this as at the same time, it's up to the command definitions to limit this as
desired. desired.
""" """
global _Msg, _PlayerDB, _to_object global _Msg
if not _Msg: if not _Msg:
from src.comms.models import Msg as _Msg from src.comms.models import Msg as _Msg
if not _PlayerDB:
from src.players.models import PlayerDB as _PlayerDB
if not _to_object:
from src.comms.managers import to_object as _to_object
def to_player(obj):
"Make sure the object is a player object"
if isinstance(obj, _PlayerDB):
return obj
elif hasattr(obj, 'user'):
return obj.dbobj
elif hasattr(obj, 'db_player'):
return obj.db_player
else:
return None
if not message: if not message:
# we don't allow empty messages. # we don't allow empty messages.
return return
new_message = _Msg(db_message=message)
new_message = _Msg()
new_message.sender = to_player(senderobj)
new_message.message = message
new_message.save() new_message.save()
if channels: for sender in make_iter(senderobj):
if not utils.is_iter(channels): new_message.senders = sender
channels = [channels] new_message.title = title
new_message.channels = [channel for channel in for channel in make_iter(channels):
[_to_object(channel, objtype='channel') new_message.channels = channel
for channel in channels] if channel] for receiver in make_iter(receivers):
if receivers: new_message.receivers = receiver
#print "Found receiver:", receivers
if not utils.is_iter(receivers):
receivers = [receivers]
#print "to_player: %s" % to_player(receivers[0])
new_message.receivers = [to_player(receiver) for receiver in
[_to_object(receiver) for receiver in receivers]
if receiver]
if locks: if locks:
new_message.locks.add(locks) new_message.locks.add(locks)
new_message.save() new_message.save()
return new_message return new_message
message = create_message message = create_message
def create_channel(key, aliases=None, desc=None, def create_channel(key, aliases=None, desc=None,

View file

@ -134,6 +134,15 @@ def c_creates_button(client):
'@desc %s = test red button!' % objname) '@desc %s = test red button!' % objname)
return cmd, "creates button ..." return cmd, "creates button ..."
def c_socialize(client):
"socializechats on channel"
cmd = ('ooc Hello!',
'ooc Testing ...',
'ooc Testing ... times 2',
'say Yo!',
'emote stands looking around.')
return cmd, "socializes ..."
def c_moves(client): def c_moves(client):
"moves to a previously created room, using the stored exits" "moves to a previously created room, using the stored exits"
cmd = client.exits # try all exits - finally one will work cmd = client.exits # try all exits - finally one will work
@ -151,17 +160,7 @@ def c_moves(client):
# otherwise the system will normalize them. # otherwise the system will normalize them.
# #
# "heavy" builder definition ## "normal builder" definition
ACTIONS = ( c_login,
c_logout,
(0.2, c_looks),
(0.1, c_examines),
(0.2, c_help),
(0.1, c_digs),
(0.1, c_creates_obj),
#(0.01, c_creates_button),
(0.2, c_moves))
# "normal builder" definition
#ACTIONS = ( c_login, #ACTIONS = ( c_login,
# c_logout, # c_logout,
# (0.5, c_looks), # (0.5, c_looks),
@ -171,7 +170,17 @@ ACTIONS = ( c_login,
# (0.01, c_creates_obj), # (0.01, c_creates_obj),
# #(0.1, c_creates_button), # #(0.1, c_creates_button),
# (0.3, c_moves)) # (0.3, c_moves))
# "passive player" definition ## "heavy" builder definition
#ACTIONS = ( c_login,
# c_logout,
# (0.2, c_looks),
# (0.1, c_examines),
# (0.2, c_help),
# (0.1, c_digs),
# (0.1, c_creates_obj),
# #(0.01, c_creates_button),
# (0.2, c_moves))
## "passive player" definition
#ACTIONS = ( c_login, #ACTIONS = ( c_login,
# c_logout, # c_logout,
# (0.7, c_looks), # (0.7, c_looks),
@ -181,4 +190,11 @@ ACTIONS = ( c_login,
# #(0.1, c_creates_obj), # #(0.1, c_creates_obj),
# #(0.1, c_creates_button), # #(0.1, c_creates_button),
# #(0.4, c_moves)) # #(0.4, c_moves))
## "socializing heavy builder" definition
ACTIONS = (c_login,
c_logout,
(0.3, c_socialize),
(0.1, c_looks),
(0.1, c_help),
(0.2, c_digs),
(0.3, c_moves))

View file

@ -724,7 +724,5 @@ def string_suggestions(string, vocabulary, cutoff=0.6, maxnum=3):
Returns: Returns:
list of suggestions from vocabulary (could be empty if there are no matches) list of suggestions from vocabulary (could be empty if there are no matches)
""" """
#if string in vocabulary:
# return [string]
return [tup[1] for tup in sorted([(string_similarity(string, sugg), sugg) for sugg in vocabulary], return [tup[1] for tup in sorted([(string_similarity(string, sugg), sugg) for sugg in vocabulary],
key=lambda tup: tup[0], reverse=True) if tup[0] >= cutoff][:maxnum] key=lambda tup: tup[0], reverse=True) if tup[0] >= cutoff][:maxnum]