Further cleanup of source; making class methods _private for clarity in the API.
This commit is contained in:
parent
fc156b5a54
commit
c8df141e89
18 changed files with 607 additions and 588 deletions
|
|
@ -4,7 +4,7 @@ Models for the comsystem.
|
||||||
The comsystem's main component is the Message, which
|
The comsystem's main component is the Message, 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.
|
||||||
A Msg always have one sender (a user), but can have
|
A Msg always have one sender (a user), but can have
|
||||||
any number targets, both users and channels.
|
any number targets, both users and channels.
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ 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.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
|
||||||
|
|
@ -35,18 +35,18 @@ def obj_to_id(inp):
|
||||||
"""
|
"""
|
||||||
dbref = is_dbref(inp)
|
dbref = is_dbref(inp)
|
||||||
if dbref:
|
if dbref:
|
||||||
return str(dbref)
|
return str(dbref)
|
||||||
if hasattr(inp, 'id'):
|
if hasattr(inp, 'id'):
|
||||||
return str(inp.id)
|
return str(inp.id)
|
||||||
if hasattr(inp, 'dbobj') and hasattr(inp.dbobj, 'id'):
|
if hasattr(inp, 'dbobj') and hasattr(inp.dbobj, 'id'):
|
||||||
return str(inp.dbobj.id)
|
return str(inp.dbobj.id)
|
||||||
return str(inp)
|
return str(inp)
|
||||||
|
|
||||||
def id_to_obj(dbref, db_model='PlayerDB'):
|
def id_to_obj(dbref, db_model='PlayerDB'):
|
||||||
"""
|
"""
|
||||||
loads from dbref to object. Uses the db_model to search
|
loads from dbref to object. Uses the db_model to search
|
||||||
for the id.
|
for the id.
|
||||||
"""
|
"""
|
||||||
if db_model == 'PlayerDB':
|
if db_model == 'PlayerDB':
|
||||||
from src.players.models import PlayerDB as db_model
|
from src.players.models import PlayerDB as db_model
|
||||||
else:
|
else:
|
||||||
|
|
@ -55,7 +55,7 @@ def id_to_obj(dbref, db_model='PlayerDB'):
|
||||||
dbref = int(dbref.strip())
|
dbref = int(dbref.strip())
|
||||||
return db_model.objects.get(id=dbref)
|
return db_model.objects.get(id=dbref)
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
|
|
@ -67,18 +67,18 @@ class Msg(SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
A single message. This model describes all ooc messages
|
A single message. This model describes all ooc messages
|
||||||
sent in-game, both to channels and between players.
|
sent in-game, both to channels and between players.
|
||||||
|
|
||||||
The Msg class defines the following properties:
|
The Msg class defines the following properties:
|
||||||
sender - sender of message
|
sender - sender of message
|
||||||
receivers - list of target objects for message
|
receivers - list of target objects for message
|
||||||
channels - list of channels message was sent to
|
channels - list of channels message was sent to
|
||||||
message - the text being sent
|
message - the text being sent
|
||||||
date_sent - time message was sent
|
date_sent - time message was sent
|
||||||
hide_from_sender - bool if message should be hidden from sender
|
hide_from_sender - bool if message should be hidden from sender
|
||||||
hide_from_receivers - list of receiver objects to hide message from
|
hide_from_receivers - list of receiver objects to hide message from
|
||||||
hide_from_channels - list of channels objects to hide message from
|
hide_from_channels - list of channels objects to hide message from
|
||||||
permissions - perm strings
|
permissions - perm strings
|
||||||
|
|
||||||
"""
|
"""
|
||||||
#
|
#
|
||||||
# Msg database model setup
|
# Msg database model setup
|
||||||
|
|
@ -90,24 +90,24 @@ class Msg(SharedMemoryModel):
|
||||||
# There must always be one sender of the message.
|
# There must always be one sender of the message.
|
||||||
db_sender = models.ForeignKey("players.PlayerDB", related_name='sender_set', null=True, verbose_name='sender')
|
db_sender = models.ForeignKey("players.PlayerDB", related_name='sender_set', null=True, verbose_name='sender')
|
||||||
# in the case of external senders, no Player object might be available
|
# in the case of external senders, no Player object might be available
|
||||||
db_sender_external = models.CharField('external sender', max_length=255, null=True, blank=True,
|
db_sender_external = models.CharField('external sender', max_length=255, null=True, blank=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 = models.CharField('receivers', max_length=255, null=True, blank=True,
|
||||||
help_text='comma-separated list of object dbrefs this message is aimed at.')
|
help_text='comma-separated list of object dbrefs this message is aimed at.')
|
||||||
# The channels this message was sent to. Stored as a
|
# The channels this message was sent to. Stored as a
|
||||||
# comma-separated string of channel dbrefs. A message can both
|
# comma-separated string of channel dbrefs. A message can both
|
||||||
# have channel targets and destination objects.
|
# have channel targets and destination objects.
|
||||||
db_channels = models.CharField('channels', max_length=255, null=True, blank=True,
|
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.')
|
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_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)
|
||||||
# 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.
|
# These are settable by senders/receivers/channels respectively.
|
||||||
# Stored as a comma-separated string of dbrefs. Can be used by the
|
# Stored as a comma-separated string of dbrefs. Can be used by the
|
||||||
|
|
@ -117,9 +117,9 @@ class Msg(SharedMemoryModel):
|
||||||
db_hide_from_receivers = models.CharField(max_length=255, null=True, blank=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)
|
db_hide_from_channels = models.CharField(max_length=255, null=True, blank=True)
|
||||||
# Storage of lock strings
|
# Storage of lock strings
|
||||||
#db_lock_storage = models.TextField(null=True)
|
#db_lock_storage = models.TextField(null=True)
|
||||||
|
|
||||||
# Database manager
|
# Database manager
|
||||||
objects = managers.MsgManager()
|
objects = managers.MsgManager()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
@ -134,8 +134,8 @@ class Msg(SharedMemoryModel):
|
||||||
# @property decorators that allows to access these fields using
|
# @property decorators that allows to access these fields using
|
||||||
# normal python operations (without having to remember to save()
|
# normal python operations (without having to remember to save()
|
||||||
# etc). So e.g. a property 'attr' has a get/set/del decorator
|
# etc). So e.g. a property 'attr' has a get/set/del decorator
|
||||||
# defined that allows the user to do self.attr = value,
|
# defined that allows the user to do self.attr = value,
|
||||||
# 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)
|
||||||
|
|
@ -183,7 +183,7 @@ class Msg(SharedMemoryModel):
|
||||||
if is_iter(value):
|
if is_iter(value):
|
||||||
value = ",".join([obj_to_id(val) for val in value])
|
value = ",".join([obj_to_id(val) for val in value])
|
||||||
self.db_receivers = obj_to_id(value)
|
self.db_receivers = obj_to_id(value)
|
||||||
self.save()
|
self.save()
|
||||||
#@receivers.deleter
|
#@receivers.deleter
|
||||||
def receivers_del(self):
|
def receivers_del(self):
|
||||||
"Deleter. Allows for del self.receivers"
|
"Deleter. Allows for del self.receivers"
|
||||||
|
|
@ -204,7 +204,7 @@ class Msg(SharedMemoryModel):
|
||||||
if is_iter(value):
|
if is_iter(value):
|
||||||
value = ",".join([obj_to_id(val) for val in value])
|
value = ",".join([obj_to_id(val) for val in value])
|
||||||
self.db_channels = obj_to_id(value)
|
self.db_channels = obj_to_id(value)
|
||||||
self.save()
|
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"
|
||||||
|
|
@ -253,7 +253,7 @@ class Msg(SharedMemoryModel):
|
||||||
def hide_from_sender_set(self, value):
|
def hide_from_sender_set(self, value):
|
||||||
"Setter. Allows for self.hide_from_senders = value."
|
"Setter. Allows for self.hide_from_senders = value."
|
||||||
self.db_hide_from_sender = value
|
self.db_hide_from_sender = value
|
||||||
self.save()
|
self.save()
|
||||||
#@hide_from_sender.deleter
|
#@hide_from_sender.deleter
|
||||||
def hide_from_sender_del(self):
|
def hide_from_sender_del(self):
|
||||||
"Deleter. Allows for del self.hide_from_senders"
|
"Deleter. Allows for del self.hide_from_senders"
|
||||||
|
|
@ -274,7 +274,7 @@ class Msg(SharedMemoryModel):
|
||||||
if is_iter(value):
|
if is_iter(value):
|
||||||
value = ",".join([obj_to_id(val) for val in value])
|
value = ",".join([obj_to_id(val) for val in value])
|
||||||
self.db_hide_from_receivers = obj_to_id(value)
|
self.db_hide_from_receivers = obj_to_id(value)
|
||||||
self.save()
|
self.save()
|
||||||
#@hide_from_receivers.deleter
|
#@hide_from_receivers.deleter
|
||||||
def hide_from_receivers_del(self):
|
def hide_from_receivers_del(self):
|
||||||
"Deleter. Allows for del self.hide_from_receivers"
|
"Deleter. Allows for del self.hide_from_receivers"
|
||||||
|
|
@ -286,7 +286,7 @@ class Msg(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def hide_from_channels_get(self):
|
def hide_from_channels_get(self):
|
||||||
"Getter. Allows for value = self.hide_from_channels. Returns a list of hide_from_channels."
|
"Getter. Allows for value = self.hide_from_channels. Returns a list of hide_from_channels."
|
||||||
if self.db_hide_from_channels:
|
if self.db_hide_from_channels:
|
||||||
return [id_to_obj(dbref) for dbref in self.db_hide_from_channels.split(',')]
|
return [id_to_obj(dbref) for dbref in self.db_hide_from_channels.split(',')]
|
||||||
return []
|
return []
|
||||||
#@hide_from_channels.setter
|
#@hide_from_channels.setter
|
||||||
|
|
@ -295,7 +295,7 @@ class Msg(SharedMemoryModel):
|
||||||
if is_iter(value):
|
if is_iter(value):
|
||||||
value = ",".join([obj_to_id(val) for val in value])
|
value = ",".join([obj_to_id(val) for val in value])
|
||||||
self.db_hide_from_channels = obj_to_id(value)
|
self.db_hide_from_channels = obj_to_id(value)
|
||||||
self.save()
|
self.save()
|
||||||
#@hide_from_channels.deleter
|
#@hide_from_channels.deleter
|
||||||
def hide_from_channels_del(self):
|
def hide_from_channels_del(self):
|
||||||
"Deleter. Allows for del self.hide_from_channels"
|
"Deleter. Allows for del self.hide_from_channels"
|
||||||
|
|
@ -304,7 +304,7 @@ class Msg(SharedMemoryModel):
|
||||||
hide_from_channels = property(hide_from_channels_get, hide_from_channels_set, hide_from_channels_del)
|
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
|
||||||
def lock_storage_get(self):
|
def lock_storage_get(self):
|
||||||
"Getter. Allows for value = self.lock_storage"
|
"Getter. Allows for value = self.lock_storage"
|
||||||
return self.db_lock_storage
|
return self.db_lock_storage
|
||||||
|
|
@ -321,15 +321,15 @@ class Msg(SharedMemoryModel):
|
||||||
|
|
||||||
db_model_name = "msg" # used by attributes to safely store objects
|
db_model_name = "msg" # used by attributes to safely store objects
|
||||||
|
|
||||||
#
|
#
|
||||||
# Msg class methods
|
# Msg class methods
|
||||||
#
|
#
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Print text"
|
"Print text"
|
||||||
if self.channels:
|
if self.channels:
|
||||||
return "%s -> %s: %s" % (self.sender.key,
|
return "%s -> %s: %s" % (self.sender.key,
|
||||||
", ".join([chan.key for chan in self.channels]),
|
", ".join([chan.key for chan in self.channels]),
|
||||||
self.message)
|
self.message)
|
||||||
else:
|
else:
|
||||||
return "%s -> %s: %s" % (self.sender.key,
|
return "%s -> %s: %s" % (self.sender.key,
|
||||||
|
|
@ -341,7 +341,7 @@ class Msg(SharedMemoryModel):
|
||||||
accessing_obj - object trying to access this one
|
accessing_obj - object trying to access this one
|
||||||
access_type - type of access sought
|
access_type - type of access sought
|
||||||
default - what to return if no lock of access_type was found
|
default - what to return if no lock of access_type was found
|
||||||
"""
|
"""
|
||||||
return self.locks.check(accessing_obj, access_type=access_type, default=default)
|
return self.locks.check(accessing_obj, access_type=access_type, default=default)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -353,61 +353,61 @@ class Msg(SharedMemoryModel):
|
||||||
|
|
||||||
class TempMsg(object):
|
class TempMsg(object):
|
||||||
"""
|
"""
|
||||||
This is a non-persistent object for sending
|
This is a non-persistent object for sending
|
||||||
temporary messages that will not be stored.
|
temporary messages that will not be stored.
|
||||||
It mimics the "real" Msg object, but don't require
|
It mimics the "real" Msg object, but don't require
|
||||||
sender to be given.
|
sender to be given.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, sender=None, receivers=[], channels=[], message="", permissions=[]):
|
def __init__(self, sender=None, receivers=[], channels=[], message="", permissions=[]):
|
||||||
self.sender = sender
|
self.sender = 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_sender = False
|
||||||
self.hide_from_sender = receivers = False
|
self.hide_from_sender = receivers = False
|
||||||
self.hide_from_channels = False
|
self.hide_from_channels = False
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Channel
|
# Channel
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
||||||
class Channel(SharedMemoryModel):
|
class Channel(SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
This is the basis of a comm channel, only implementing
|
This is the basis of a comm channel, only implementing
|
||||||
the very basics of distributing messages.
|
the very basics of distributing messages.
|
||||||
|
|
||||||
The Channel class defines the following properties:
|
The Channel class defines the following properties:
|
||||||
key - main name for channel
|
key - main name for channel
|
||||||
desc - optional description of channel
|
desc - optional description of channel
|
||||||
aliases - alternative names for the channel
|
aliases - alternative names for the channel
|
||||||
keep_log - bool if the channel should remember messages
|
keep_log - bool if the channel should remember messages
|
||||||
permissions - perm strings
|
permissions - perm strings
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Channel database model setup
|
# Channel database model setup
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# 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.
|
||||||
|
|
||||||
# unique identifier for this channel
|
# unique identifier for this channel
|
||||||
db_key = models.CharField('key', max_length=255, unique=True, db_index=True)
|
db_key = models.CharField('key', max_length=255, unique=True, db_index=True)
|
||||||
# optional description of channel
|
# optional description of channel
|
||||||
db_desc = models.CharField('description', max_length=80, blank=True, null=True)
|
db_desc = models.CharField('description', max_length=80, blank=True, null=True)
|
||||||
# aliases for the channel. These are searched by cmdhandler
|
# aliases for the channel. These are searched by cmdhandler
|
||||||
# as well to determine if a command is the name of a channel.
|
# as well to determine if a command is the name of a channel.
|
||||||
# Several aliases are separated by commas.
|
# Several aliases are separated by commas.
|
||||||
db_aliases = models.CharField('aliases', max_length=255)
|
db_aliases = models.CharField('aliases', max_length=255)
|
||||||
# Whether this channel should remember its past messages
|
# Whether this channel should remember its past messages
|
||||||
db_keep_log = models.BooleanField(default=True)
|
db_keep_log = models.BooleanField(default=True)
|
||||||
# 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()
|
||||||
|
|
||||||
|
|
@ -416,15 +416,15 @@ class Channel(SharedMemoryModel):
|
||||||
verbose_name = "Channel"
|
verbose_name = "Channel"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
SharedMemoryModel.__init__(self, *args, **kwargs)
|
SharedMemoryModel.__init__(self, *args, **kwargs)
|
||||||
self.locks = LockHandler(self)
|
self.locks = LockHandler(self)
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
# Wrapper properties to easily set database fields. These are
|
||||||
# @property decorators that allows to access these fields using
|
# @property decorators that allows to access these fields using
|
||||||
# normal python operations (without having to remember to save()
|
# normal python operations (without having to remember to save()
|
||||||
# etc). So e.g. a property 'attr' has a get/set/del decorator
|
# etc). So e.g. a property 'attr' has a get/set/del decorator
|
||||||
# defined that allows the user to do self.attr = value,
|
# defined that allows the user to do self.attr = value,
|
||||||
# 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).
|
||||||
|
|
||||||
# key property (wraps db_key)
|
# key property (wraps db_key)
|
||||||
|
|
@ -473,14 +473,14 @@ class Channel(SharedMemoryModel):
|
||||||
if is_iter(value):
|
if is_iter(value):
|
||||||
value = ",".join([str(val).strip().lower() for val in value])
|
value = ",".join([str(val).strip().lower() for val in value])
|
||||||
self.db_aliases = value
|
self.db_aliases = value
|
||||||
self.save()
|
self.save()
|
||||||
#@aliases_del.deleter
|
#@aliases_del.deleter
|
||||||
def aliases_del(self):
|
def aliases_del(self):
|
||||||
"Deleter. Allows for del self.aliases"
|
"Deleter. Allows for del self.aliases"
|
||||||
self.db_aliases = ""
|
self.db_aliases = ""
|
||||||
self.save()
|
self.save()
|
||||||
aliases = property(aliases_get, aliases_set, aliases_del)
|
aliases = property(aliases_get, aliases_set, aliases_del)
|
||||||
|
|
||||||
# keep_log property (wraps db_keep_log)
|
# keep_log property (wraps db_keep_log)
|
||||||
#@property
|
#@property
|
||||||
def keep_log_get(self):
|
def keep_log_get(self):
|
||||||
|
|
@ -499,7 +499,7 @@ class Channel(SharedMemoryModel):
|
||||||
keep_log = property(keep_log_get, keep_log_set, keep_log_del)
|
keep_log = property(keep_log_get, keep_log_set, keep_log_del)
|
||||||
|
|
||||||
# lock_storage property (wraps db_lock_storage)
|
# lock_storage property (wraps db_lock_storage)
|
||||||
#@property
|
#@property
|
||||||
def lock_storage_get(self):
|
def lock_storage_get(self):
|
||||||
"Getter. Allows for value = self.lock_storage"
|
"Getter. Allows for value = self.lock_storage"
|
||||||
return self.db_lock_storage
|
return self.db_lock_storage
|
||||||
|
|
@ -527,11 +527,11 @@ class Channel(SharedMemoryModel):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Channel '%s' (%s)" % (self.key, self.desc)
|
return "Channel '%s' (%s)" % (self.key, self.desc)
|
||||||
|
|
||||||
def has_connection(self, player):
|
def has_connection(self, player):
|
||||||
"""
|
"""
|
||||||
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_connection(player, self)
|
||||||
|
|
||||||
|
|
@ -539,54 +539,54 @@ class Channel(SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
Send the given message to all players connected to channel. Note that
|
Send the given message to all players connected to channel. Note that
|
||||||
no permission-checking is done here; it is assumed to have been
|
no permission-checking is done here; it is assumed to have been
|
||||||
done before calling this method.
|
done before calling this method.
|
||||||
|
|
||||||
msgobj - a Msg instance or a message string. In the latter case a Msg will be created.
|
msgobj - a Msg instance or a message string. In the latter case a Msg will be created.
|
||||||
from_obj - if msgobj is not an Msg-instance, this is used to create
|
from_obj - if msgobj is not an Msg-instance, this is used to create
|
||||||
a message on the fly. If from_obj is None, no Msg object will
|
a message on the fly. If from_obj is None, no Msg object will
|
||||||
be created and the message will be sent without being logged.
|
be created and the message will be sent without being logged.
|
||||||
"""
|
"""
|
||||||
if isinstance(msgobj, basestring):
|
if isinstance(msgobj, basestring):
|
||||||
# given msgobj is a string
|
# given msgobj is a string
|
||||||
if from_obj:
|
if from_obj:
|
||||||
if isinstance(from_obj, basestring):
|
if isinstance(from_obj, basestring):
|
||||||
msgobj = Msg(db_sender_external=from_obj, db_message=msgobj)
|
msgobj = Msg(db_sender_external=from_obj, db_message=msgobj)
|
||||||
else:
|
else:
|
||||||
msgobj = Msg(db_sender=from_obj, db_message=msgobj)
|
msgobj = Msg(db_sender=from_obj, db_message=msgobj)
|
||||||
# try to use
|
# try to use
|
||||||
msgobj.save()
|
msgobj.save()
|
||||||
msgobj.channels = [self]
|
msgobj.channels = [self]
|
||||||
msg = msgobj.message
|
msg = msgobj.message
|
||||||
else:
|
else:
|
||||||
# this just sends a message, without any sender
|
# this just sends a message, without any sender
|
||||||
# (and without storing it in a persistent Msg object)
|
# (and without storing it in a persistent Msg object)
|
||||||
msg = to_str(msgobj)
|
msg = to_str(msgobj)
|
||||||
else:
|
else:
|
||||||
msg = msgobj.message
|
msg = msgobj.message
|
||||||
|
|
||||||
# get all players connected to this channel and send to them
|
# get all players connected to this channel and send to them
|
||||||
for conn in Channel.objects.get_all_connections(self):
|
for conn in Channel.objects.get_all_connections(self):
|
||||||
try:
|
try:
|
||||||
conn.player.msg(msg, from_obj)
|
conn.player.msg(msg, from_obj)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
conn.to_external(msg, from_obj, from_channel=self)
|
conn.to_external(msg, from_obj, from_channel=self)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace("Cannot send msg to connection '%s'" % conn)
|
logger.log_trace("Cannot send msg to connection '%s'" % conn)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def tempmsg(self, message):
|
def tempmsg(self, message):
|
||||||
"""
|
"""
|
||||||
A wrapper for sending non-persistent messages. Nothing
|
A wrapper for sending non-persistent messages. Nothing
|
||||||
will be stored in the database.
|
will be stored in the database.
|
||||||
|
|
||||||
message - a Msg object or a text string.
|
message - a Msg object or a text string.
|
||||||
"""
|
"""
|
||||||
if type(msgobj) == Msg:
|
if type(msgobj) == Msg:
|
||||||
# extract only the string
|
# extract only the string
|
||||||
message = message.message
|
message = message.message
|
||||||
return self.msg(message)
|
return self.msg(message)
|
||||||
|
|
||||||
def connect_to(self, player):
|
def connect_to(self, player):
|
||||||
"Connect the user to this channel"
|
"Connect the user to this channel"
|
||||||
if not self.access(player, 'listen'):
|
if not self.access(player, 'listen'):
|
||||||
|
|
@ -594,7 +594,7 @@ class Channel(SharedMemoryModel):
|
||||||
conn = PlayerChannelConnection.objects.create_connection(player, self)
|
conn = PlayerChannelConnection.objects.create_connection(player, self)
|
||||||
if conn:
|
if conn:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def disconnect_from(self, player):
|
def disconnect_from(self, player):
|
||||||
"Disconnect user from this channel."
|
"Disconnect user from this channel."
|
||||||
|
|
@ -611,14 +611,14 @@ class Channel(SharedMemoryModel):
|
||||||
accessing_obj - object trying to access this one
|
accessing_obj - object trying to access this one
|
||||||
access_type - type of access sought
|
access_type - type of access sought
|
||||||
default - what to return if no lock of access_type was found
|
default - what to return if no lock of access_type was found
|
||||||
"""
|
"""
|
||||||
return self.locks.check(accessing_obj, access_type=access_type, default=default)
|
return self.locks.check(accessing_obj, access_type=access_type, default=default)
|
||||||
|
|
||||||
class PlayerChannelConnection(SharedMemoryModel):
|
class PlayerChannelConnection(SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
This connects a player object to a particular comm channel.
|
This connects a player object to a particular comm channel.
|
||||||
The advantage of making it like this is that one can easily
|
The advantage of making it like this is that one can easily
|
||||||
break the connection just by deleting this object.
|
break the connection just by deleting this object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Player connected to a channel
|
# Player connected to a channel
|
||||||
|
|
@ -672,19 +672,19 @@ class PlayerChannelConnection(SharedMemoryModel):
|
||||||
|
|
||||||
class ExternalChannelConnection(SharedMemoryModel):
|
class ExternalChannelConnection(SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
This defines an external protocol connecting to
|
This defines an external protocol connecting to
|
||||||
a channel, while storing some critical info about
|
a channel, while storing some critical info about
|
||||||
that connection.
|
that connection.
|
||||||
"""
|
"""
|
||||||
# evennia channel connecting to
|
# evennia channel connecting to
|
||||||
db_channel = models.ForeignKey(Channel, verbose_name='channel',
|
db_channel = models.ForeignKey(Channel, verbose_name='channel',
|
||||||
help_text='which channel this connection is tied to.')
|
help_text='which channel this connection is tied to.')
|
||||||
# external connection identifier
|
# external connection identifier
|
||||||
db_external_key = models.CharField('external key', max_length=128,
|
db_external_key = models.CharField('external key', max_length=128,
|
||||||
help_text='external connection identifier, used by calling protocol.')
|
help_text='external connection identifier, used by calling protocol.')
|
||||||
# eval-code to use when the channel tries to send a message
|
# eval-code to use when the channel tries to send a message
|
||||||
# to the external protocol.
|
# to the external protocol.
|
||||||
db_external_send_code = models.TextField('executable code', blank=True,
|
db_external_send_code = models.TextField('executable code', blank=True,
|
||||||
help_text='this is a custom snippet of Python code to connect the external protocol to the in-game channel.')
|
help_text='this is a custom snippet of Python code to connect the external protocol to the in-game channel.')
|
||||||
# custom config for the connection
|
# custom config for the connection
|
||||||
db_external_config = models.TextField('external config', blank=True,
|
db_external_config = models.TextField('external config', blank=True,
|
||||||
|
|
@ -693,10 +693,10 @@ class ExternalChannelConnection(SharedMemoryModel):
|
||||||
db_is_enabled = models.BooleanField('is enabled', default=True, help_text='turn on/off the connection.')
|
db_is_enabled = models.BooleanField('is enabled', default=True, help_text='turn on/off the connection.')
|
||||||
|
|
||||||
objects = managers.ExternalChannelConnectionManager()
|
objects = managers.ExternalChannelConnectionManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "External Channel Connection"
|
verbose_name = "External Channel Connection"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s <-> external %s" % (self.channel.key, self.db_external_key)
|
return "%s <-> external %s" % (self.channel.key, self.db_external_key)
|
||||||
|
|
||||||
|
|
@ -778,7 +778,7 @@ class ExternalChannelConnection(SharedMemoryModel):
|
||||||
self.save()
|
self.save()
|
||||||
#@is_enabled.deleter
|
#@is_enabled.deleter
|
||||||
def is_enabled_del(self):
|
def is_enabled_del(self):
|
||||||
"Deleter. Allows for del self.is_enabled. Deletes connection."
|
"Deleter. Allows for del self.is_enabled. Deletes connection."
|
||||||
self.delete()
|
self.delete()
|
||||||
is_enabled = property(is_enabled_get, is_enabled_set, is_enabled_del)
|
is_enabled = property(is_enabled_get, is_enabled_set, is_enabled_del)
|
||||||
|
|
||||||
|
|
@ -789,23 +789,22 @@ class ExternalChannelConnection(SharedMemoryModel):
|
||||||
def to_channel(self, message, from_obj=None):
|
def to_channel(self, message, from_obj=None):
|
||||||
"Send external -> channel"
|
"Send external -> channel"
|
||||||
if not from_obj:
|
if not from_obj:
|
||||||
from_obj = self.external_key
|
from_obj = self.external_key
|
||||||
self.channel.msg(message, from_obj=from_obj)
|
self.channel.msg(message, from_obj=from_obj)
|
||||||
|
|
||||||
def to_external(self, message, from_obj=None, from_channel=None):
|
def to_external(self, message, from_obj=None, from_channel=None):
|
||||||
"Send channel -> external"
|
"Send channel -> external"
|
||||||
|
|
||||||
# make sure we are not echoing back our own message to ourselves
|
# make sure we are not echoing back our own message to ourselves
|
||||||
# (this would result in a nasty infinite loop)
|
# (this would result in a nasty infinite loop)
|
||||||
if from_obj == self.external_key:
|
if from_obj == self.external_key:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# we execute the code snippet that should make it possible for the
|
# we execute the code snippet that should make it possible for the
|
||||||
# connection to contact the protocol correctly (as set by the protocol).
|
# connection to contact the protocol correctly (as set by the protocol).
|
||||||
# Note that the code block has access to the variables here, such
|
# Note that the code block has access to the variables here, such
|
||||||
# as message, from_obj and from_channel.
|
# as message, from_obj and from_channel.
|
||||||
exec(to_str(self.external_send_code))
|
exec(to_str(self.external_send_code))
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace("Channel %s could not send to External %s" % (self.channel, self.external_key))
|
logger.log_trace("Channel %s could not send to External %s" % (self.channel, self.external_key))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ Custom manager for HelpEntry objects.
|
||||||
"""
|
"""
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from src.utils import logger, utils
|
from src.utils import logger, utils
|
||||||
|
__all__ = ("HelpEntryManager",)
|
||||||
|
|
||||||
class HelpEntryManager(models.Manager):
|
class HelpEntryManager(models.Manager):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ from src.help.manager import HelpEntryManager
|
||||||
from src.utils import ansi
|
from src.utils import ansi
|
||||||
from src.locks.lockhandler import LockHandler
|
from src.locks.lockhandler import LockHandler
|
||||||
from src.utils.utils import is_iter
|
from src.utils.utils import is_iter
|
||||||
|
__all__ = ("HelpEntry",)
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
|
|
@ -32,6 +33,9 @@ class HelpEntry(SharedMemoryModel):
|
||||||
entrytext - the actual help text
|
entrytext - the actual help text
|
||||||
permissions - perm strings
|
permissions - perm strings
|
||||||
|
|
||||||
|
Method:
|
||||||
|
access
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
@ -78,88 +82,88 @@ class HelpEntry(SharedMemoryModel):
|
||||||
|
|
||||||
# key property (wraps db_key)
|
# key property (wraps db_key)
|
||||||
#@property
|
#@property
|
||||||
def key_get(self):
|
def __key_get(self):
|
||||||
"Getter. Allows for value = self.key"
|
"Getter. Allows for value = self.key"
|
||||||
return self.db_key
|
return self.db_key
|
||||||
#@key.setter
|
#@key.setter
|
||||||
def key_set(self, value):
|
def __key_set(self, value):
|
||||||
"Setter. Allows for self.key = value"
|
"Setter. Allows for self.key = value"
|
||||||
self.db_key = value
|
self.db_key = value
|
||||||
self.save()
|
self.save()
|
||||||
#@key.deleter
|
#@key.deleter
|
||||||
def key_del(self):
|
def __key_del(self):
|
||||||
"Deleter. Allows for del self.key. Deletes entry."
|
"Deleter. Allows for del self.key. Deletes entry."
|
||||||
self.delete()
|
self.delete()
|
||||||
key = property(key_get, key_set, key_del)
|
key = property(__key_get, __key_set, __key_del)
|
||||||
|
|
||||||
# help_category property (wraps db_help_category)
|
# help_category property (wraps db_help_category)
|
||||||
#@property
|
#@property
|
||||||
def help_category_get(self):
|
def __help_category_get(self):
|
||||||
"Getter. Allows for value = self.help_category"
|
"Getter. Allows for value = self.help_category"
|
||||||
return self.db_help_category
|
return self.db_help_category
|
||||||
#@help_category.setter
|
#@help_category.setter
|
||||||
def help_category_set(self, value):
|
def __help_category_set(self, value):
|
||||||
"Setter. Allows for self.help_category = value"
|
"Setter. Allows for self.help_category = value"
|
||||||
self.db_help_category = value
|
self.db_help_category = value
|
||||||
self.save()
|
self.save()
|
||||||
#@help_category.deleter
|
#@help_category.deleter
|
||||||
def help_category_del(self):
|
def __help_category_del(self):
|
||||||
"Deleter. Allows for del self.help_category"
|
"Deleter. Allows for del self.help_category"
|
||||||
self.db_help_category = "General"
|
self.db_help_category = "General"
|
||||||
self.save()
|
self.save()
|
||||||
help_category = property(help_category_get, help_category_set, help_category_del)
|
help_category = property(__help_category_get, __help_category_set, __help_category_del)
|
||||||
|
|
||||||
# entrytext property (wraps db_entrytext)
|
# entrytext property (wraps db_entrytext)
|
||||||
#@property
|
#@property
|
||||||
def entrytext_get(self):
|
def __entrytext_get(self):
|
||||||
"Getter. Allows for value = self.entrytext"
|
"Getter. Allows for value = self.entrytext"
|
||||||
return self.db_entrytext
|
return self.db_entrytext
|
||||||
#@entrytext.setter
|
#@entrytext.setter
|
||||||
def entrytext_set(self, value):
|
def __entrytext_set(self, value):
|
||||||
"Setter. Allows for self.entrytext = value"
|
"Setter. Allows for self.entrytext = value"
|
||||||
self.db_entrytext = value
|
self.db_entrytext = value
|
||||||
self.save()
|
self.save()
|
||||||
#@entrytext.deleter
|
#@entrytext.deleter
|
||||||
def entrytext_del(self):
|
def __entrytext_del(self):
|
||||||
"Deleter. Allows for del self.entrytext"
|
"Deleter. Allows for del self.entrytext"
|
||||||
self.db_entrytext = ""
|
self.db_entrytext = ""
|
||||||
self.save()
|
self.save()
|
||||||
entrytext = property(entrytext_get, entrytext_set, entrytext_del)
|
entrytext = property(__entrytext_get, __entrytext_set, __entrytext_del)
|
||||||
|
|
||||||
# permissions property
|
# permissions property
|
||||||
#@property
|
#@property
|
||||||
def permissions_get(self):
|
def __permissions_get(self):
|
||||||
"Getter. Allows for value = self.permissions. Returns a list of permissions."
|
"Getter. Allows for value = self.permissions. Returns a list of permissions."
|
||||||
return [perm.strip() for perm in self.db_permissions.split(',')]
|
return [perm.strip() for perm in self.db_permissions.split(',')]
|
||||||
#@permissions.setter
|
#@permissions.setter
|
||||||
def permissions_set(self, value):
|
def __permissions_set(self, value):
|
||||||
"Setter. Allows for self.permissions = value. Stores as a comma-separated string."
|
"Setter. Allows for self.permissions = value. Stores as a comma-separated string."
|
||||||
if is_iter(value):
|
if is_iter(value):
|
||||||
value = ",".join([str(val).strip().lower() for val in value])
|
value = ",".join([str(val).strip().lower() for val in value])
|
||||||
self.db_permissions = value
|
self.db_permissions = value
|
||||||
self.save()
|
self.save()
|
||||||
#@permissions.deleter
|
#@permissions.deleter
|
||||||
def permissions_del(self):
|
def __permissions_del(self):
|
||||||
"Deleter. Allows for del self.permissions"
|
"Deleter. Allows for del self.permissions"
|
||||||
self.db_permissions = ""
|
self.db_permissions = ""
|
||||||
self.save()
|
self.save()
|
||||||
permissions = property(permissions_get, permissions_set, permissions_del)
|
permissions = property(__permissions_get, __permissions_set, __permissions_del)
|
||||||
|
|
||||||
# lock_storage property (wraps db_lock_storage)
|
# lock_storage property (wraps db_lock_storage)
|
||||||
#@property
|
#@property
|
||||||
def lock_storage_get(self):
|
def __lock_storage_get(self):
|
||||||
"Getter. Allows for value = self.lock_storage"
|
"Getter. Allows for value = self.lock_storage"
|
||||||
return self.db_lock_storage
|
return self.db_lock_storage
|
||||||
#@nick.setter
|
#@nick.setter
|
||||||
def lock_storage_set(self, value):
|
def __lock_storage_set(self, value):
|
||||||
"""Saves the lock_storagetodate. This is usually not called directly, but through self.lock()"""
|
"""Saves the lock_storagetodate. This is usually not called directly, but through self.lock()"""
|
||||||
self.db_lock_storage = value
|
self.db_lock_storage = value
|
||||||
self.save()
|
self.save()
|
||||||
#@nick.deleter
|
#@nick.deleter
|
||||||
def lock_storage_del(self):
|
def __lock_storage_del(self):
|
||||||
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
||||||
logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
|
logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
|
||||||
lock_storage = property(lock_storage_get, lock_storage_set, lock_storage_del)
|
lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ This module provides a set of permission lock functions for use
|
||||||
with Evennia's permissions system.
|
with Evennia's permissions system.
|
||||||
|
|
||||||
To call these locks, make sure this module is included in the
|
To call these locks, make sure this module is included in the
|
||||||
settings tuple PERMISSION_FUNC_MODULES then define a lock on the form
|
settings tuple PERMISSION_FUNC_MODULES then define a lock on the form
|
||||||
'<access_type>:func(args)' and add it to the object's lockhandler.
|
'<access_type>:func(args)' and add it to the object's lockhandler.
|
||||||
Run the access() method of the handler to execute the lock check.
|
Run the access() method of the handler to execute the lock check.
|
||||||
|
|
||||||
Note that accessing_obj and accessed_obj can be any object type
|
Note that accessing_obj and accessed_obj can be any object type
|
||||||
with a lock variable/field, so be careful to not expect
|
with a lock variable/field, so be careful to not expect
|
||||||
a certain object type.
|
a certain object type.
|
||||||
|
|
||||||
|
|
||||||
Appendix: MUX locks
|
Appendix: MUX locks
|
||||||
|
|
@ -22,7 +22,7 @@ available like the MUX ones. So many of these are not available in
|
||||||
basic Evennia, but could all be implemented easily if needed for the
|
basic Evennia, but could all be implemented easily if needed for the
|
||||||
individual game.
|
individual game.
|
||||||
|
|
||||||
MUX Name: Affects: Effect:
|
MUX Name: Affects: Effect:
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
DefaultLock: Exits: controls who may traverse the exit to
|
DefaultLock: Exits: controls who may traverse the exit to
|
||||||
its destination.
|
its destination.
|
||||||
|
|
@ -34,43 +34,43 @@ DefaultLock: Exits: controls who may traverse the exit to
|
||||||
Players/Things: controls who may GET the object.
|
Players/Things: controls who may GET the object.
|
||||||
Evennia: "get:<lockfunc()"
|
Evennia: "get:<lockfunc()"
|
||||||
EnterLock: Players/Things: controls who may ENTER the object
|
EnterLock: Players/Things: controls who may ENTER the object
|
||||||
Evennia:
|
Evennia:
|
||||||
GetFromLock: All but Exits: controls who may gets things from a given
|
GetFromLock: All but Exits: controls who may gets things from a given
|
||||||
location.
|
location.
|
||||||
Evennia:
|
Evennia:
|
||||||
GiveLock: Players/Things: controls who may give the object.
|
GiveLock: Players/Things: controls who may give the object.
|
||||||
Evennia:
|
Evennia:
|
||||||
LeaveLock: Players/Things: controls who may LEAVE the object.
|
LeaveLock: Players/Things: controls who may LEAVE the object.
|
||||||
Evennia:
|
Evennia:
|
||||||
LinkLock: All but Exits: controls who may link to the location if the
|
LinkLock: All but Exits: controls who may link to the location if the
|
||||||
location is LINK_OK (for linking exits or
|
location is LINK_OK (for linking exits or
|
||||||
setting drop-tos) or ABODE (for setting
|
setting drop-tos) or ABODE (for setting
|
||||||
homes)
|
homes)
|
||||||
Evennia:
|
Evennia:
|
||||||
MailLock: Players: controls who may @mail the player.
|
MailLock: Players: controls who may @mail the player.
|
||||||
Evennia:
|
Evennia:
|
||||||
OpenLock: All but Exits: controls who may open an exit.
|
OpenLock: All but Exits: controls who may open an exit.
|
||||||
Evennia:
|
Evennia:
|
||||||
PageLock: Players: controls who may page the player.
|
PageLock: Players: controls who may page the player.
|
||||||
Evennia: "send:<lockfunc()>"
|
Evennia: "send:<lockfunc()>"
|
||||||
ParentLock: All: controls who may make @parent links to the
|
ParentLock: All: controls who may make @parent links to the
|
||||||
object.
|
object.
|
||||||
Evennia: Typeclasses and "puppet:<lockstring()>"
|
Evennia: Typeclasses and "puppet:<lockstring()>"
|
||||||
ReceiveLock: Players/Things: controls who may give things to the object.
|
ReceiveLock: Players/Things: controls who may give things to the object.
|
||||||
Evennia:
|
Evennia:
|
||||||
SpeechLock: All but Exits: controls who may speak in that location
|
SpeechLock: All but Exits: controls who may speak in that location
|
||||||
Evennia:
|
Evennia:
|
||||||
TeloutLock: All but Exits: controls who may teleport out of the
|
TeloutLock: All but Exits: controls who may teleport out of the
|
||||||
location.
|
location.
|
||||||
Evennia:
|
Evennia:
|
||||||
TportLock: Rooms/Things: controls who may teleport there
|
TportLock: Rooms/Things: controls who may teleport there
|
||||||
Evennia:
|
Evennia:
|
||||||
UseLock: All but Exits: controls who may USE the object, GIVE the
|
UseLock: All but Exits: controls who may USE the object, GIVE the
|
||||||
object money and have the PAY attributes
|
object money and have the PAY attributes
|
||||||
run, have their messages heard and possibly
|
run, have their messages heard and possibly
|
||||||
acted on by LISTEN and AxHEAR, and invoke
|
acted on by LISTEN and AxHEAR, and invoke
|
||||||
$-commands stored on the object.
|
$-commands stored on the object.
|
||||||
Evennia: Commands and Cmdsets.
|
Evennia: Commands and Cmdsets.
|
||||||
DropLock: All but rooms: controls who may drop that object.
|
DropLock: All but rooms: controls who may drop that object.
|
||||||
Evennia:
|
Evennia:
|
||||||
VisibleLock: All: Controls object visibility when the object
|
VisibleLock: All: Controls object visibility when the object
|
||||||
|
|
@ -85,7 +85,7 @@ from django.conf import settings
|
||||||
from src.utils import search
|
from src.utils import search
|
||||||
from src.utils import utils
|
from src.utils import utils
|
||||||
|
|
||||||
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
_PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||||
|
|
||||||
def _to_player(accessing_obj):
|
def _to_player(accessing_obj):
|
||||||
"Helper function. Makes sure an accessing object is a player object"
|
"Helper function. Makes sure an accessing object is a player object"
|
||||||
|
|
@ -95,85 +95,85 @@ def _to_player(accessing_obj):
|
||||||
return accessing_obj
|
return accessing_obj
|
||||||
|
|
||||||
|
|
||||||
# lock functions
|
# lock functions
|
||||||
|
|
||||||
def true(*args, **kwargs):
|
def true(*args, **kwargs):
|
||||||
"Always returns True."
|
"Always returns True."
|
||||||
return True
|
return True
|
||||||
def all(*args, **kwargs):
|
def all(*args, **kwargs):
|
||||||
return True
|
return True
|
||||||
def false(*args, **kwargs):
|
def false(*args, **kwargs):
|
||||||
"Always returns False"
|
"Always returns False"
|
||||||
return False
|
return False
|
||||||
def none(*args, **kwargs):
|
def none(*args, **kwargs):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def perm(accessing_obj, accessed_obj, *args, **kwargs):
|
def perm(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
The basic permission-checker. Ignores case.
|
The basic permission-checker. Ignores case.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
perm(<permission>)
|
perm(<permission>)
|
||||||
|
|
||||||
where <permission> is the permission accessing_obj must
|
where <permission> is the permission accessing_obj must
|
||||||
have in order to pass the lock. If the given permission
|
have in order to pass the lock. If the given permission
|
||||||
is part of PERMISSION_HIERARCHY, permission is also granted
|
is part of _PERMISSION_HIERARCHY, permission is also granted
|
||||||
to all ranks higher up in the hierarchy.
|
to all ranks higher up in the hierarchy.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
perm = args[0].lower()
|
perm = args[0].lower()
|
||||||
permissions = [p.lower() for p in accessing_obj.permissions]
|
permissions = [p.lower() for p in accessing_obj.permissions]
|
||||||
except AttributeError, IndexError:
|
except AttributeError, IndexError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if perm in permissions:
|
if perm in permissions:
|
||||||
# simplest case - we have a direct match
|
# simplest case - we have a direct match
|
||||||
return True
|
return True
|
||||||
if perm in PERMISSION_HIERARCHY:
|
if perm in _PERMISSION_HIERARCHY:
|
||||||
# check if we have a higher hierarchy position
|
# check if we have a higher hierarchy position
|
||||||
ppos = PERMISSION_HIERARCHY.index(perm)
|
ppos = _PERMISSION_HIERARCHY.index(perm)
|
||||||
return any(1 for hpos, hperm in enumerate(PERMISSION_HIERARCHY)
|
return any(1 for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
|
||||||
if hperm in permissions and hpos > ppos)
|
if hperm in permissions and hpos > ppos)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def perm_above(accessing_obj, accessed_obj, *args, **kwargs):
|
def perm_above(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Only allow objects with a permission *higher* in the permission
|
Only allow objects with a permission *higher* in the permission
|
||||||
hierarchy than the one given. If there is no such higher rank,
|
hierarchy than the one given. If there is no such higher rank,
|
||||||
it's assumed we refer to superuser. If no hierarchy is defined,
|
it's assumed we refer to superuser. If no hierarchy is defined,
|
||||||
this function has no meaning and returns False.
|
this function has no meaning and returns False.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
perm = args[0].lower()
|
perm = args[0].lower()
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if perm in PERMISSION_HIERARCHY:
|
if perm in _PERMISSION_HIERARCHY:
|
||||||
ppos = PERMISSION_HIERARCHY.index(perm)
|
ppos = _PERMISSION_HIERARCHY.index(perm)
|
||||||
return any(1 for hpos, hperm in enumerate(PERMISSION_HIERARCHY)
|
return any(1 for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
|
||||||
if hperm in [p.lower() for p in accessing_obj.permissions] and hpos > ppos)
|
if hperm in [p.lower() for p in accessing_obj.permissions] and hpos > ppos)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def pperm(accessing_obj, accessed_obj, *args, **kwargs):
|
def pperm(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
The basic permission-checker for Player objects. Ignores case.
|
The basic permission-checker for Player objects. Ignores case.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
pperm(<permission>)
|
pperm(<permission>)
|
||||||
|
|
||||||
where <permission> is the permission accessing_obj must
|
where <permission> is the permission accessing_obj must
|
||||||
have in order to pass the lock. If the given permission
|
have in order to pass the lock. If the given permission
|
||||||
is part of PERMISSION_HIERARCHY, permission is also granted
|
is part of _PERMISSION_HIERARCHY, permission is also granted
|
||||||
to all ranks higher up in the hierarchy.
|
to all ranks higher up in the hierarchy.
|
||||||
"""
|
"""
|
||||||
return perm(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
return perm(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
||||||
|
|
||||||
def pperm_above(accessing_obj, accessed_obj, *args, **kwargs):
|
def pperm_above(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Only allow Player objects with a permission *higher* in the permission
|
Only allow Player objects with a permission *higher* in the permission
|
||||||
hierarchy than the one given. If there is no such higher rank,
|
hierarchy than the one given. If there is no such higher rank,
|
||||||
it's assumed we refer to superuser. If no hierarchy is defined,
|
it's assumed we refer to superuser. If no hierarchy is defined,
|
||||||
this function has no meaning and returns False.
|
this function has no meaning and returns False.
|
||||||
"""
|
"""
|
||||||
return perm_above(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
return perm_above(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
||||||
|
|
||||||
|
|
@ -181,7 +181,7 @@ def dbref(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
dbref(3)
|
dbref(3)
|
||||||
|
|
||||||
This lock type checks if the checking object
|
This lock type checks if the checking object
|
||||||
has a particular dbref. Note that this only
|
has a particular dbref. Note that this only
|
||||||
works for checking objects that are stored
|
works for checking objects that are stored
|
||||||
|
|
@ -195,7 +195,7 @@ def dbref(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
return False
|
return False
|
||||||
if hasattr(accessing_obj, 'id'):
|
if hasattr(accessing_obj, 'id'):
|
||||||
return dbref == accessing_obj.id
|
return dbref == accessing_obj.id
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def pdbref(accessing_obj, accessed_obj, *args, **kwargs):
|
def pdbref(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
@ -212,7 +212,7 @@ def pid(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
return dbref(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
return dbref(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# this is more efficient than multiple if ... elif statments
|
# this is more efficient than multiple if ... elif statments
|
||||||
CF_MAPPING = {'eq': lambda val1, val2: val1 == val2 or int(val1) == int(val2),
|
CF_MAPPING = {'eq': lambda val1, val2: val1 == val2 or int(val1) == int(val2),
|
||||||
'gt': lambda val1, val2: int(val1) > int(val2),
|
'gt': lambda val1, val2: int(val1) > int(val2),
|
||||||
'lt': lambda val1, val2: int(val1) < int(val2),
|
'lt': lambda val1, val2: int(val1) < int(val2),
|
||||||
|
|
@ -232,7 +232,7 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
how the value should be compared with one on accessing_obj (so
|
how the value should be compared with one on accessing_obj (so
|
||||||
compare=gt means the accessing_obj must have a value greater than
|
compare=gt means the accessing_obj must have a value greater than
|
||||||
the one given).
|
the one given).
|
||||||
|
|
||||||
Searches attributes *and* properties stored on the checking
|
Searches attributes *and* properties stored on the checking
|
||||||
object. The first form works like a flag - if the
|
object. The first form works like a flag - if the
|
||||||
attribute/property exists on the object, the value is checked for
|
attribute/property exists on the object, the value is checked for
|
||||||
|
|
@ -240,17 +240,17 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
attribute/property matches. Note that all retrieved values will be
|
attribute/property matches. Note that all retrieved values will be
|
||||||
converted to strings before doing the comparison.
|
converted to strings before doing the comparison.
|
||||||
"""
|
"""
|
||||||
# deal with arguments
|
# deal with arguments
|
||||||
if not args:
|
if not args:
|
||||||
return False
|
return False
|
||||||
attrname = args[0].strip()
|
attrname = args[0].strip()
|
||||||
value = None
|
value = None
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
value = args[1].strip()
|
value = args[1].strip()
|
||||||
compare = 'eq'
|
compare = 'eq'
|
||||||
if kwargs:
|
if kwargs:
|
||||||
compare = kwargs.get('compare', 'eq')
|
compare = kwargs.get('compare', 'eq')
|
||||||
|
|
||||||
def valcompare(val1, val2, typ='eq'):
|
def valcompare(val1, val2, typ='eq'):
|
||||||
"compare based on type"
|
"compare based on type"
|
||||||
try:
|
try:
|
||||||
|
|
@ -258,20 +258,20 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
#print e
|
#print e
|
||||||
# this might happen if we try to compare two things that cannot be compared
|
# this might happen if we try to compare two things that cannot be compared
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# first, look for normal properties on the object trying to gain access
|
# first, look for normal properties on the object trying to gain access
|
||||||
if hasattr(accessing_obj, attrname):
|
if hasattr(accessing_obj, attrname):
|
||||||
if value:
|
if value:
|
||||||
return valcompare(str(getattr(accessing_obj, attrname)), value, compare)
|
return valcompare(str(getattr(accessing_obj, attrname)), value, compare)
|
||||||
return bool(getattr(accessing_obj, attrname)) # will return Fail on False value etc
|
return bool(getattr(accessing_obj, attrname)) # will return Fail on False value etc
|
||||||
# check attributes, if they exist
|
# check attributes, if they exist
|
||||||
if (hasattr(accessing_obj, 'has_attribute') and accessing_obj.has_attribute(attrname)):
|
if (hasattr(accessing_obj, 'has_attribute') and accessing_obj.has_attribute(attrname)):
|
||||||
if value:
|
if value:
|
||||||
return (hasattr(accessing_obj, 'get_attribute')
|
return (hasattr(accessing_obj, 'get_attribute')
|
||||||
and valcompare(accessing_obj.get_attribute(attrname), value, compare))
|
and valcompare(accessing_obj.get_attribute(attrname), value, compare))
|
||||||
return bool(accessing_obj.get_attribute(attrname)) # fails on False/None values
|
return bool(accessing_obj.get_attribute(attrname)) # fails on False/None values
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def objattr(accessing_obj, accessed_obj, *args, **kwargs):
|
def objattr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
@ -280,7 +280,7 @@ def objattr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
objattr(attrname, value)
|
objattr(attrname, value)
|
||||||
objattr(attrname, value, compare=type)
|
objattr(attrname, value, compare=type)
|
||||||
|
|
||||||
Works like attr, except it looks for an attribute on
|
Works like attr, except it looks for an attribute on
|
||||||
accessing_obj.obj, if such an entity exists. Suitable
|
accessing_obj.obj, if such an entity exists. Suitable
|
||||||
for commands.
|
for commands.
|
||||||
|
|
||||||
|
|
@ -295,8 +295,8 @@ def locattr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
locattr(attrname, value)
|
locattr(attrname, value)
|
||||||
locattr(attrname, value, compare=type)
|
locattr(attrname, value, compare=type)
|
||||||
|
|
||||||
Works like attr, except it looks for an attribute on
|
Works like attr, except it looks for an attribute on
|
||||||
accessing_obj.location, if such an entity exists.
|
accessing_obj.location, if such an entity exists.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if hasattr(accessing_obj, "location"):
|
if hasattr(accessing_obj, "location"):
|
||||||
|
|
@ -305,14 +305,14 @@ def locattr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
|
|
||||||
def attr_eq(accessing_obj, accessed_obj, *args, **kwargs):
|
def attr_eq(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
attr_gt(attrname, 54)
|
attr_gt(attrname, 54)
|
||||||
"""
|
"""
|
||||||
return attr(accessing_obj, accessed_obj, *args, **kwargs)
|
return attr(accessing_obj, accessed_obj, *args, **kwargs)
|
||||||
|
|
||||||
def attr_gt(accessing_obj, accessed_obj, *args, **kwargs):
|
def attr_gt(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
attr_gt(attrname, 54)
|
attr_gt(attrname, 54)
|
||||||
|
|
||||||
Only true if access_obj's attribute > the value given.
|
Only true if access_obj's attribute > the value given.
|
||||||
|
|
@ -320,7 +320,7 @@ def attr_gt(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'gt'})
|
return attr(accessing_obj, accessed_obj, *args, **{'compare':'gt'})
|
||||||
def attr_ge(accessing_obj, accessed_obj, *args, **kwargs):
|
def attr_ge(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
attr_gt(attrname, 54)
|
attr_gt(attrname, 54)
|
||||||
|
|
||||||
Only true if access_obj's attribute >= the value given.
|
Only true if access_obj's attribute >= the value given.
|
||||||
|
|
@ -328,7 +328,7 @@ def attr_ge(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'ge'})
|
return attr(accessing_obj, accessed_obj, *args, **{'compare':'ge'})
|
||||||
def attr_lt(accessing_obj, accessed_obj, *args, **kwargs):
|
def attr_lt(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
attr_gt(attrname, 54)
|
attr_gt(attrname, 54)
|
||||||
|
|
||||||
Only true if access_obj's attribute < the value given.
|
Only true if access_obj's attribute < the value given.
|
||||||
|
|
@ -336,7 +336,7 @@ def attr_lt(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'lt'})
|
return attr(accessing_obj, accessed_obj, *args, **{'compare':'lt'})
|
||||||
def attr_le(accessing_obj, accessed_obj, *args, **kwargs):
|
def attr_le(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
attr_gt(attrname, 54)
|
attr_gt(attrname, 54)
|
||||||
|
|
||||||
Only true if access_obj's attribute <= the value given.
|
Only true if access_obj's attribute <= the value given.
|
||||||
|
|
@ -344,7 +344,7 @@ def attr_le(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
return attr(accessing_obj, accessed_obj, *args, **{'compare':'le'})
|
return attr(accessing_obj, accessed_obj, *args, **{'compare':'le'})
|
||||||
def attr_ne(accessing_obj, accessed_obj, *args, **kwargs):
|
def attr_ne(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
attr_gt(attrname, 54)
|
attr_gt(attrname, 54)
|
||||||
|
|
||||||
Only true if access_obj's attribute != the value given.
|
Only true if access_obj's attribute != the value given.
|
||||||
|
|
@ -353,7 +353,7 @@ def attr_ne(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
|
|
||||||
def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
holds() # checks if accessed_obj or accessed_obj.obj is held by accessing_obj
|
holds() # checks if accessed_obj or accessed_obj.obj is held by accessing_obj
|
||||||
holds(key/dbref) # checks if accessing_obj holds an object with given key/dbref
|
holds(key/dbref) # checks if accessing_obj holds an object with given key/dbref
|
||||||
|
|
||||||
|
|
@ -364,50 +364,50 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
# commands and scripts don't have contents, so we are usually looking
|
# commands and scripts don't have contents, so we are usually looking
|
||||||
# for the contents of their .obj property instead (i.e. the object the
|
# for the contents of their .obj property instead (i.e. the object the
|
||||||
# command/script is attached to).
|
# command/script is attached to).
|
||||||
contents = accessing_obj.contents
|
contents = accessing_obj.contents
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
contents = accessing_obj.obj.contents
|
contents = accessing_obj.obj.contents
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def check_holds(objid):
|
def check_holds(objid):
|
||||||
# helper function. Compares both dbrefs and keys/aliases.
|
# helper function. Compares both dbrefs and keys/aliases.
|
||||||
objid = str(objid)
|
objid = str(objid)
|
||||||
dbref = utils.dbref(objid)
|
dbref = utils.dbref(objid)
|
||||||
if dbref and any((True for obj in contents if obj.id == dbref)):
|
if dbref and any((True for obj in contents if obj.id == dbref)):
|
||||||
return True
|
return True
|
||||||
objid = objid.lower()
|
objid = objid.lower()
|
||||||
return any((True for obj in contents
|
return any((True for obj in contents
|
||||||
if obj.key.lower() == objid or objid in [al.lower() for al in obj.aliases]))
|
if obj.key.lower() == objid or objid in [al.lower() for al in obj.aliases]))
|
||||||
|
|
||||||
if args and args[0]:
|
if args and args[0]:
|
||||||
return check_holds(args[0])
|
return check_holds(args[0])
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if check_holds(accessed_obj.id):
|
if check_holds(accessed_obj.id):
|
||||||
#print "holds: accessed_obj.id - True"
|
#print "holds: accessed_obj.id - True"
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
#print "holds: accessed_obj.obj.id -", hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
|
#print "holds: accessed_obj.obj.id -", hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
|
||||||
return hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
|
return hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
|
||||||
|
|
||||||
def superuser(*args, **kwargs):
|
def superuser(*args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Only accepts an accesing_obj that is superuser (e.g. user #1)
|
Only accepts an accesing_obj that is superuser (e.g. user #1)
|
||||||
|
|
||||||
Since a superuser would not ever reach this check (superusers
|
Since a superuser would not ever reach this check (superusers
|
||||||
bypass the lock entirely), any user who gets this far cannot be a
|
bypass the lock entirely), any user who gets this far cannot be a
|
||||||
superuser, hence we just return False. :)
|
superuser, hence we just return False. :)
|
||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
|
def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Only returns true if the Evennia settings exists, alternatively has a certain value.
|
Only returns true if the Evennia settings exists, alternatively has a certain value.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
serversetting(IRC_ENABLED)
|
serversetting(IRC_ENABLED)
|
||||||
serversetting(BASE_SCRIPT_PATH, [game.gamesrc.scripts])
|
serversetting(BASE_SCRIPT_PATH, [game.gamesrc.scripts])
|
||||||
|
|
@ -418,16 +418,16 @@ def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
return False
|
return False
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
setting = args[0]
|
setting = args[0]
|
||||||
val = "True"
|
val = "True"
|
||||||
else:
|
else:
|
||||||
setting, val = args[0], args[1]
|
setting, val = args[0], args[1]
|
||||||
# convert
|
# convert
|
||||||
if val == 'True':
|
if val == 'True':
|
||||||
val = True
|
val = True
|
||||||
elif val == 'False':
|
elif val == 'False':
|
||||||
val = False
|
val = False
|
||||||
elif val.isdigit():
|
elif val.isdigit():
|
||||||
val = int(val)
|
val = int(val)
|
||||||
if setting in settings._wrapped.__dict__:
|
if setting in settings._wrapped.__dict__:
|
||||||
return settings._wrapped.__dict__[setting] == val
|
return settings._wrapped.__dict__[setting] == val
|
||||||
return False
|
return False
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,15 @@ A lock defines access to a particular subsystem or property of
|
||||||
Evennia. For example, the "owner" property can be impmemented as a
|
Evennia. For example, the "owner" property can be impmemented as a
|
||||||
lock. Or the disability to lift an object or to ban users.
|
lock. Or the disability to lift an object or to ban users.
|
||||||
|
|
||||||
A lock consists of three parts:
|
A lock consists of three parts:
|
||||||
|
|
||||||
- access_type - this defines what kind of access this lock regulates. This
|
- access_type - this defines what kind of access this lock regulates. This
|
||||||
just a string.
|
just a string.
|
||||||
- function call - this is one or many calls to functions that will determine
|
- function call - this is one or many calls to functions that will determine
|
||||||
if the lock is passed or not.
|
if the lock is passed or not.
|
||||||
- lock function(s). These are regular python functions with a special
|
- lock function(s). These are regular python functions with a special
|
||||||
set of allowed arguments. They should always return a boolean depending
|
set of allowed arguments. They should always return a boolean depending
|
||||||
on if they allow access or not.
|
on if they allow access or not.
|
||||||
|
|
||||||
# Lock function
|
# Lock function
|
||||||
|
|
||||||
|
|
@ -26,26 +26,26 @@ take four arguments looking like this:
|
||||||
|
|
||||||
The accessing object is the object wanting to gain access.
|
The accessing object is the object wanting to gain access.
|
||||||
The accessed object is the object this lock resides on
|
The accessed object is the object this lock resides on
|
||||||
args and kwargs will hold optional arguments and/or keyword arguments
|
args and kwargs will hold optional arguments and/or keyword arguments
|
||||||
to the function as a list and a dictionary respectively.
|
to the function as a list and a dictionary respectively.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
perm(accessing_obj, accessed_obj, *args, **kwargs):
|
perm(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"Checking if the object has a particular, desired permission"
|
"Checking if the object has a particular, desired permission"
|
||||||
if args:
|
if args:
|
||||||
desired_perm = args[0]
|
desired_perm = args[0]
|
||||||
return desired_perm in accessing_obj.permissions
|
return desired_perm in accessing_obj.permissions
|
||||||
return False
|
return False
|
||||||
|
|
||||||
Lock functions should most often be pretty general and ideally possible to
|
Lock functions should most often be pretty general and ideally possible to
|
||||||
re-use and combine in various ways to build clever locks.
|
re-use and combine in various ways to build clever locks.
|
||||||
|
|
||||||
|
|
||||||
# Lock definition ("Lock string")
|
# Lock definition ("Lock string")
|
||||||
|
|
||||||
A lock definition is a string with a special syntax. It is added to
|
A lock definition is a string with a special syntax. It is added to
|
||||||
each object's lockhandler, making that lock available from then on.
|
each object's lockhandler, making that lock available from then on.
|
||||||
|
|
||||||
The lock definition looks like this:
|
The lock definition looks like this:
|
||||||
|
|
||||||
|
|
@ -54,15 +54,15 @@ The lock definition looks like this:
|
||||||
That is, the access_type, a colon followed by calls to lock functions
|
That is, the access_type, a colon followed by calls to lock functions
|
||||||
combined with AND or OR. NOT negates the result of the following call.
|
combined with AND or OR. NOT negates the result of the following call.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
We want to limit who may edit a particular object (let's call this access_type
|
We want to limit who may edit a particular object (let's call this access_type
|
||||||
for 'edit', it depends on what the command is looking for). We want this to
|
for 'edit', it depends on what the command is looking for). We want this to
|
||||||
only work for those with the Permission 'Builders'. So we use our lock
|
only work for those with the Permission 'Builders'. So we use our lock
|
||||||
function above and define it like this:
|
function above and define it like this:
|
||||||
|
|
||||||
'edit:perm(Builders)'
|
'edit:perm(Builders)'
|
||||||
|
|
||||||
Here, the lock-function perm() will be called with the string
|
Here, the lock-function perm() will be called with the string
|
||||||
'Builders' (accessing_obj and accessed_obj are added automatically,
|
'Builders' (accessing_obj and accessed_obj are added automatically,
|
||||||
you only need to add the args/kwargs, if any).
|
you only need to add the args/kwargs, if any).
|
||||||
|
|
@ -73,17 +73,17 @@ could use AND:
|
||||||
'edit:perm(Builders) AND perm(GoodGuy)'
|
'edit:perm(Builders) AND perm(GoodGuy)'
|
||||||
|
|
||||||
To allow EITHER Builders and GoodGuys, we replace AND with OR. perm() is just one example,
|
To allow EITHER Builders and GoodGuys, we replace AND with OR. perm() is just one example,
|
||||||
the lock function can do anything and compare any properties of the calling object to
|
the lock function can do anything and compare any properties of the calling object to
|
||||||
decide if the lock is passed or not.
|
decide if the lock is passed or not.
|
||||||
|
|
||||||
'lift:attrib(very_strong) AND NOT attrib(bad_back)'
|
'lift:attrib(very_strong) AND NOT attrib(bad_back)'
|
||||||
|
|
||||||
To make these work, add the string to the lockhandler of the object you want
|
To make these work, add the string to the lockhandler of the object you want
|
||||||
to apply the lock to:
|
to apply the lock to:
|
||||||
|
|
||||||
obj.lockhandler.add('edit:perm(Builders)')
|
obj.lockhandler.add('edit:perm(Builders)')
|
||||||
|
|
||||||
From then on, a command that wants to check for 'edit' access on this
|
From then on, a command that wants to check for 'edit' access on this
|
||||||
object would do something like this:
|
object would do something like this:
|
||||||
|
|
||||||
if not target_obj.lockhandler.has_perm(caller, 'edit'):
|
if not target_obj.lockhandler.has_perm(caller, 'edit'):
|
||||||
|
|
@ -93,8 +93,8 @@ All objects also has a shortcut called 'access' that is recommended to use inste
|
||||||
|
|
||||||
if not target_obj.access(caller, 'edit'):
|
if not target_obj.access(caller, 'edit'):
|
||||||
caller.msg("Sorry, you cannot edit that.")
|
caller.msg("Sorry, you cannot edit that.")
|
||||||
|
|
||||||
# Permissions
|
# Permissions
|
||||||
|
|
||||||
Permissions are just text strings stored in a comma-separated list on
|
Permissions are just text strings stored in a comma-separated list on
|
||||||
typeclassed objects. The default perm() lock function uses them,
|
typeclassed objects. The default perm() lock function uses them,
|
||||||
|
|
@ -106,8 +106,8 @@ to any other identifier you can use.
|
||||||
|
|
||||||
import re, inspect
|
import re, inspect
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from src.utils import logger, utils
|
from src.utils import logger, utils
|
||||||
|
__all__ = ("LockHandler", )
|
||||||
#
|
#
|
||||||
# Exception class
|
# Exception class
|
||||||
#
|
#
|
||||||
|
|
@ -120,17 +120,17 @@ class LockException(Exception):
|
||||||
# Cached lock functions
|
# Cached lock functions
|
||||||
#
|
#
|
||||||
|
|
||||||
LOCKFUNCS = {}
|
_LOCKFUNCS = {}
|
||||||
def cache_lockfuncs():
|
def _cache_lockfuncs():
|
||||||
"Updates the cache."
|
"Updates the cache."
|
||||||
global LOCKFUNCS
|
global _LOCKFUNCS
|
||||||
LOCKFUNCS = {}
|
_LOCKFUNCS = {}
|
||||||
for modulepath in settings.LOCK_FUNC_MODULES:
|
for modulepath in settings.LOCK_FUNC_MODULES:
|
||||||
modulepath = utils.pypath_to_realpath(modulepath)
|
modulepath = utils.pypath_to_realpath(modulepath)
|
||||||
mod = utils.mod_import(modulepath)
|
mod = utils.mod_import(modulepath)
|
||||||
if mod:
|
if mod:
|
||||||
for tup in (tup for tup in inspect.getmembers(mod) if callable(tup[1])):
|
for tup in (tup for tup in inspect.getmembers(mod) if callable(tup[1])):
|
||||||
LOCKFUNCS[tup[0]] = tup[1]
|
_LOCKFUNCS[tup[0]] = tup[1]
|
||||||
else:
|
else:
|
||||||
logger.log_errmsg("Couldn't load %s from PERMISSION_FUNC_MODULES." % modulepath)
|
logger.log_errmsg("Couldn't load %s from PERMISSION_FUNC_MODULES." % modulepath)
|
||||||
|
|
||||||
|
|
@ -138,21 +138,21 @@ def cache_lockfuncs():
|
||||||
# pre-compiled regular expressions
|
# pre-compiled regular expressions
|
||||||
#
|
#
|
||||||
|
|
||||||
RE_FUNCS = re.compile(r"\w+\([^)]*\)")
|
_RE_FUNCS = re.compile(r"\w+\([^)]*\)")
|
||||||
RE_SEPS = re.compile(r"(?<=[ )])AND(?=\s)|(?<=[ )])OR(?=\s)|(?<=[ )])NOT(?=\s)")
|
_RE_SEPS = re.compile(r"(?<=[ )])AND(?=\s)|(?<=[ )])OR(?=\s)|(?<=[ )])NOT(?=\s)")
|
||||||
RE_OK = re.compile(r"%s|and|or|not")
|
_RE_OK = re.compile(r"%s|and|or|not")
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Lock handler
|
# Lock handler
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
class LockHandler(object):
|
class LockHandler(object):
|
||||||
"""
|
"""
|
||||||
This handler should be attached to all objects implementing
|
This handler should be attached to all objects implementing
|
||||||
permission checks, under the property 'lockhandler'.
|
permission checks, under the property 'lockhandler'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
|
|
@ -160,13 +160,13 @@ class LockHandler(object):
|
||||||
Loads and pre-caches all relevant locks and their
|
Loads and pre-caches all relevant locks and their
|
||||||
functions.
|
functions.
|
||||||
"""
|
"""
|
||||||
if not LOCKFUNCS:
|
if not _LOCKFUNCS:
|
||||||
cache_lockfuncs()
|
_cache_lockfuncs()
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
self.locks = {}
|
self.locks = {}
|
||||||
self.log_obj = None
|
self.log_obj = None
|
||||||
self.no_errors = True
|
self.no_errors = True
|
||||||
self.reset_flag = False
|
self.reset_flag = False
|
||||||
|
|
||||||
self._cache_locks(self.obj.lock_storage)
|
self._cache_locks(self.obj.lock_storage)
|
||||||
|
|
||||||
|
|
@ -177,7 +177,7 @@ class LockHandler(object):
|
||||||
def _log_error(self, message):
|
def _log_error(self, message):
|
||||||
"Try to log errors back to object"
|
"Try to log errors back to object"
|
||||||
if self.log_obj and hasattr(self.log_obj, 'msg'):
|
if self.log_obj and hasattr(self.log_obj, 'msg'):
|
||||||
self.log_obj.msg(message)
|
self.log_obj.msg(message)
|
||||||
elif hasattr(self.obj, 'msg'):
|
elif hasattr(self.obj, 'msg'):
|
||||||
self.obj.msg(message)
|
self.obj.msg(message)
|
||||||
else:
|
else:
|
||||||
|
|
@ -192,12 +192,12 @@ class LockHandler(object):
|
||||||
"""
|
"""
|
||||||
locks = {}
|
locks = {}
|
||||||
if not storage_lockstring:
|
if not storage_lockstring:
|
||||||
return locks
|
return locks
|
||||||
nlocks = storage_lockstring.count(';') + 1
|
nlocks = storage_lockstring.count(';') + 1
|
||||||
duplicates = 0
|
duplicates = 0
|
||||||
elist = [] # errors
|
elist = [] # errors
|
||||||
wlist = [] # warnings
|
wlist = [] # warnings
|
||||||
for raw_lockstring in storage_lockstring.split(';'):
|
for raw_lockstring in storage_lockstring.split(';'):
|
||||||
lock_funcs = []
|
lock_funcs = []
|
||||||
try:
|
try:
|
||||||
access_type, rhs = (part.strip() for part in raw_lockstring.split(':', 1))
|
access_type, rhs = (part.strip() for part in raw_lockstring.split(':', 1))
|
||||||
|
|
@ -206,42 +206,42 @@ class LockHandler(object):
|
||||||
return locks
|
return locks
|
||||||
|
|
||||||
# parse the lock functions and separators
|
# parse the lock functions and separators
|
||||||
funclist = RE_FUNCS.findall(rhs)
|
funclist = _RE_FUNCS.findall(rhs)
|
||||||
evalstring = rhs.replace('AND','and').replace('OR','or').replace('NOT','not')
|
evalstring = rhs.replace('AND','and').replace('OR','or').replace('NOT','not')
|
||||||
nfuncs = len(funclist)
|
nfuncs = len(funclist)
|
||||||
for funcstring in funclist:
|
for funcstring in funclist:
|
||||||
funcname, rest = (part.strip().strip(')') for part in funcstring.split('(', 1))
|
funcname, rest = (part.strip().strip(')') for part in funcstring.split('(', 1))
|
||||||
func = LOCKFUNCS.get(funcname, None)
|
func = _LOCKFUNCS.get(funcname, None)
|
||||||
if not callable(func):
|
if not callable(func):
|
||||||
elist.append("Lock: function '%s' is not available." % funcstring)
|
elist.append("Lock: function '%s' is not available." % funcstring)
|
||||||
continue
|
continue
|
||||||
args = list(arg.strip() for arg in rest.split(',') if not '=' in arg)
|
args = list(arg.strip() for arg in rest.split(',') if not '=' in arg)
|
||||||
kwargs = dict([arg.split('=', 1) for arg in rest.split(',') if '=' in arg])
|
kwargs = dict([arg.split('=', 1) for arg in rest.split(',') if '=' in arg])
|
||||||
lock_funcs.append((func, args, kwargs))
|
lock_funcs.append((func, args, kwargs))
|
||||||
evalstring = evalstring.replace(funcstring, '%s')
|
evalstring = evalstring.replace(funcstring, '%s')
|
||||||
if len(lock_funcs) < nfuncs:
|
if len(lock_funcs) < nfuncs:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
# purge the eval string of any superfluos items, then test it
|
# purge the eval string of any superfluos items, then test it
|
||||||
evalstring = " ".join(RE_OK.findall(evalstring))
|
evalstring = " ".join(_RE_OK.findall(evalstring))
|
||||||
eval(evalstring % tuple(True for func in funclist))
|
eval(evalstring % tuple(True for func in funclist))
|
||||||
except Exception:
|
except Exception:
|
||||||
elist.append("Lock: definition '%s' has syntax errors." % raw_lockstring)
|
elist.append("Lock: definition '%s' has syntax errors." % raw_lockstring)
|
||||||
continue
|
continue
|
||||||
if access_type in locks:
|
if access_type in locks:
|
||||||
duplicates += 1
|
duplicates += 1
|
||||||
wlist.append("Lock: access type '%s' changed from '%s' to '%s' " % \
|
wlist.append("Lock: access type '%s' changed from '%s' to '%s' " % \
|
||||||
(access_type, locks[access_type][2], raw_lockstring))
|
(access_type, locks[access_type][2], raw_lockstring))
|
||||||
locks[access_type] = (evalstring, tuple(lock_funcs), raw_lockstring)
|
locks[access_type] = (evalstring, tuple(lock_funcs), raw_lockstring)
|
||||||
if wlist and self.log_obj:
|
if wlist and self.log_obj:
|
||||||
# a warning text was set, it's not an error, so only report if log_obj is available.
|
# a warning text was set, it's not an error, so only report if log_obj is available.
|
||||||
self._log_error("\n".join(wlist))
|
self._log_error("\n".join(wlist))
|
||||||
if elist:
|
if elist:
|
||||||
# an error text was set, raise exception.
|
# an error text was set, raise exception.
|
||||||
raise LockException("\n".join(elist))
|
raise LockException("\n".join(elist))
|
||||||
self.no_errors = False
|
self.no_errors = False
|
||||||
# return the gathered locks in an easily executable form
|
# return the gathered locks in an easily executable form
|
||||||
return locks
|
return locks
|
||||||
|
|
||||||
def _cache_locks(self, storage_lockstring):
|
def _cache_locks(self, storage_lockstring):
|
||||||
"""Store data"""
|
"""Store data"""
|
||||||
|
|
@ -253,29 +253,29 @@ class LockHandler(object):
|
||||||
|
|
||||||
def add(self, lockstring, log_obj=None):
|
def add(self, lockstring, log_obj=None):
|
||||||
"""
|
"""
|
||||||
Add a new lockstring on the form '<access_type>:<functions>'. Multiple
|
Add a new lockstring on the form '<access_type>:<functions>'. Multiple
|
||||||
access types should be separated by semicolon (;).
|
access types should be separated by semicolon (;).
|
||||||
|
|
||||||
If log_obj is given, it will be fed error information.
|
If log_obj is given, it will be fed error information.
|
||||||
"""
|
"""
|
||||||
if log_obj:
|
if log_obj:
|
||||||
self.log_obj = log_obj
|
self.log_obj = log_obj
|
||||||
self.no_errors = True
|
self.no_errors = True
|
||||||
# sanity checks
|
# sanity checks
|
||||||
for lockdef in lockstring.split(';'):
|
for lockdef in lockstring.split(';'):
|
||||||
if not ':' in lockstring:
|
if not ':' in lockstring:
|
||||||
self._log_error("Lock: '%s' contains no colon (:)." % lockdef)
|
self._log_error("Lock: '%s' contains no colon (:)." % lockdef)
|
||||||
return False
|
return False
|
||||||
access_type, rhs = [part.strip() for part in lockdef.split(':', 1)]
|
access_type, rhs = [part.strip() for part in lockdef.split(':', 1)]
|
||||||
if not access_type:
|
if not access_type:
|
||||||
self._log_error("Lock: '%s' has no access_type (left-side of colon is empty)." % lockdef)
|
self._log_error("Lock: '%s' has no access_type (left-side of colon is empty)." % lockdef)
|
||||||
return False
|
return False
|
||||||
if rhs.count('(') != rhs.count(')'):
|
if rhs.count('(') != rhs.count(')'):
|
||||||
self._log_error("Lock: '%s' has mismatched parentheses." % lockdef)
|
self._log_error("Lock: '%s' has mismatched parentheses." % lockdef)
|
||||||
return False
|
return False
|
||||||
if not RE_FUNCS.findall(rhs):
|
if not _RE_FUNCS.findall(rhs):
|
||||||
self._log_error("Lock: '%s' has no valid lock functions." % lockdef)
|
self._log_error("Lock: '%s' has no valid lock functions." % lockdef)
|
||||||
return False
|
return False
|
||||||
# get the lock string
|
# get the lock string
|
||||||
storage_lockstring = self.obj.lock_storage
|
storage_lockstring = self.obj.lock_storage
|
||||||
if storage_lockstring:
|
if storage_lockstring:
|
||||||
|
|
@ -285,8 +285,8 @@ class LockHandler(object):
|
||||||
# cache the locks will get rid of eventual doublets
|
# cache the locks will get rid of eventual doublets
|
||||||
self._cache_locks(storage_lockstring)
|
self._cache_locks(storage_lockstring)
|
||||||
self._save_locks()
|
self._save_locks()
|
||||||
self.log_obj = None
|
self.log_obj = None
|
||||||
return self.no_errors
|
return self.no_errors
|
||||||
|
|
||||||
def get(self, access_type):
|
def get(self, access_type):
|
||||||
"get the lockstring of a particular type"
|
"get the lockstring of a particular type"
|
||||||
|
|
@ -297,8 +297,8 @@ class LockHandler(object):
|
||||||
if access_type in self.locks:
|
if access_type in self.locks:
|
||||||
del self.locks[access_type]
|
del self.locks[access_type]
|
||||||
self._save_locks()
|
self._save_locks()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"Remove all locks"
|
"Remove all locks"
|
||||||
|
|
@ -307,10 +307,10 @@ class LockHandler(object):
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
Set the reset flag, so the the lock will be re-cached at next checking.
|
Set the reset flag, so the the lock will be re-cached at next checking.
|
||||||
This is usually set by @reload.
|
This is usually set by @reload.
|
||||||
"""
|
"""
|
||||||
self.reset_flag = True
|
self.reset_flag = True
|
||||||
|
|
||||||
def check(self, accessing_obj, access_type, default=False, no_superuser_bypass=False):
|
def check(self, accessing_obj, access_type, default=False, no_superuser_bypass=False):
|
||||||
"""
|
"""
|
||||||
Checks a lock of the correct type by passing execution
|
Checks a lock of the correct type by passing execution
|
||||||
|
|
@ -322,8 +322,8 @@ class LockHandler(object):
|
||||||
no_superuser_bypass - don't use this unless you really, really need to,
|
no_superuser_bypass - don't use this unless you really, really need to,
|
||||||
it makes supersusers susceptible to the lock check.
|
it makes supersusers susceptible to the lock check.
|
||||||
|
|
||||||
A lock is executed in the follwoing way:
|
A lock is executed in the follwoing way:
|
||||||
|
|
||||||
Parsing the lockstring, we (during cache) extract the valid
|
Parsing the lockstring, we (during cache) extract the valid
|
||||||
lock functions and store their function objects in the right
|
lock functions and store their function objects in the right
|
||||||
order along with their args/kwargs. These are now executed in
|
order along with their args/kwargs. These are now executed in
|
||||||
|
|
@ -340,11 +340,11 @@ class LockHandler(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.reset_flag:
|
if self.reset_flag:
|
||||||
# rebuild cache
|
# rebuild cache
|
||||||
self._cache_locks(self.obj.lock_storage)
|
self._cache_locks(self.obj.lock_storage)
|
||||||
self.reset_flag = False
|
self.reset_flag = False
|
||||||
|
|
||||||
if (not no_superuser_bypass
|
if (not no_superuser_bypass
|
||||||
and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
|
and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
|
||||||
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
|
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
|
||||||
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser)))):
|
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser)))):
|
||||||
|
|
@ -353,11 +353,11 @@ class LockHandler(object):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if access_type in self.locks:
|
if access_type in self.locks:
|
||||||
# we have a lock, test it.
|
# we have a lock, test it.
|
||||||
evalstring, func_tup, raw_string = self.locks[access_type]
|
evalstring, func_tup, raw_string = self.locks[access_type]
|
||||||
# execute all lock funcs in the correct order, producing a tuple of True/False results.
|
# execute all lock funcs in the correct order, producing a tuple of True/False results.
|
||||||
true_false = tuple(bool(tup[0](accessing_obj, self.obj, *tup[1], **tup[2])) for tup in func_tup)
|
true_false = tuple(bool(tup[0](accessing_obj, self.obj, *tup[1], **tup[2])) for tup in func_tup)
|
||||||
# the True/False tuple goes into evalstring, which combines them
|
# the True/False tuple goes into evalstring, which combines them
|
||||||
# with AND/OR/NOT in order to get the final result.
|
# with AND/OR/NOT in order to get the final result.
|
||||||
return eval(evalstring % true_false)
|
return eval(evalstring % true_false)
|
||||||
else:
|
else:
|
||||||
|
|
@ -367,22 +367,22 @@ class LockHandler(object):
|
||||||
"""
|
"""
|
||||||
Do a direct check against a lockstring ('atype:func()..'), without any
|
Do a direct check against a lockstring ('atype:func()..'), without any
|
||||||
intermediary storage on the accessed object (this can be left
|
intermediary storage on the accessed object (this can be left
|
||||||
to None if the lock functions called don't access it). atype can also be
|
to None if the lock functions called don't access it). atype can also be
|
||||||
put to a dummy value since no lock selection is made.
|
put to a dummy value since no lock selection is made.
|
||||||
"""
|
"""
|
||||||
if ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
|
if ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
|
||||||
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
|
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
|
||||||
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser))):
|
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser))):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
locks = self. _parse_lockstring(lockstring)
|
locks = self. _parse_lockstring(lockstring)
|
||||||
for access_type in locks:
|
for access_type in locks:
|
||||||
evalstring, func_tup, raw_string = locks[access_type]
|
evalstring, func_tup, raw_string = locks[access_type]
|
||||||
true_false = tuple(tup[0](accessing_obj, self.obj, *tup[1], **tup[2]) for tup in func_tup)
|
true_false = tuple(tup[0](accessing_obj, self.obj, *tup[1], **tup[2]) for tup in func_tup)
|
||||||
return eval(evalstring % true_false)
|
return eval(evalstring % true_false)
|
||||||
|
|
||||||
def test():
|
def _test():
|
||||||
# testing
|
# testing
|
||||||
|
|
||||||
class TestObj(object):
|
class TestObj(object):
|
||||||
pass
|
pass
|
||||||
|
|
@ -390,9 +390,9 @@ def test():
|
||||||
import pdb
|
import pdb
|
||||||
obj1 = TestObj()
|
obj1 = TestObj()
|
||||||
obj2 = TestObj()
|
obj2 = TestObj()
|
||||||
|
|
||||||
#obj1.lock_storage = "owner:dbref(#4);edit:dbref(#5) or perm(Wizards);examine:perm(Builders);delete:perm(Wizards);get:all()"
|
#obj1.lock_storage = "owner:dbref(#4);edit:dbref(#5) or perm(Wizards);examine:perm(Builders);delete:perm(Wizards);get:all()"
|
||||||
#obj1.lock_storage = "cmd:all();admin:id(1);listen:all();send:all()"
|
#obj1.lock_storage = "cmd:all();admin:id(1);listen:all();send:all()"
|
||||||
obj1.lock_storage = "listen:perm(Immortals)"
|
obj1.lock_storage = "listen:perm(Immortals)"
|
||||||
|
|
||||||
pdb.set_trace()
|
pdb.set_trace()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This is part of Evennia's unittest framework, for testing
|
This is part of Evennia's unittest framework, for testing
|
||||||
the stability and integrrity of the codebase during updates.
|
the stability and integrrity of the codebase during updates.
|
||||||
|
|
||||||
This module tests the lock functionality of Evennia.
|
This module tests the lock functionality of Evennia.
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ class TestLockfuncs(LockTest):
|
||||||
def testrun(self):
|
def testrun(self):
|
||||||
self.obj2.permissions = ['Wizards']
|
self.obj2.permissions = ['Wizards']
|
||||||
self.assertEquals(True, lockfuncs.true(self.obj2, self.obj1))
|
self.assertEquals(True, lockfuncs.true(self.obj2, self.obj1))
|
||||||
self.assertEquals(False, lockfuncs.false(self.obj2, self.obj1))
|
self.assertEquals(False, lockfuncs.false(self.obj2, self.obj1))
|
||||||
self.assertEquals(True, lockfuncs.perm(self.obj2, self.obj1, 'Wizards'))
|
self.assertEquals(True, lockfuncs.perm(self.obj2, self.obj1, 'Wizards'))
|
||||||
self.assertEquals(True, lockfuncs.perm_above(self.obj2, self.obj1, 'Builders'))
|
self.assertEquals(True, lockfuncs.perm_above(self.obj2, self.obj1, 'Builders'))
|
||||||
dbref = self.obj2.dbref
|
dbref = self.obj2.dbref
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@ from src.utils import utils
|
||||||
from src.utils.utils import to_unicode
|
from src.utils.utils import to_unicode
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
|
|
||||||
|
__all__ = ("ObjectManager",)
|
||||||
|
|
||||||
# Try to use a custom way to parse id-tagged multimatches.
|
# Try to use a custom way to parse id-tagged multimatches.
|
||||||
|
|
||||||
AT_MULTIMATCH_INPUT = utils.mod_import(*settings.SEARCH_AT_MULTIMATCH_INPUT.rsplit('.', 1))
|
_AT_MULTIMATCH_INPUT = utils.mod_import(*settings.SEARCH_AT_MULTIMATCH_INPUT.rsplit('.', 1))
|
||||||
|
|
||||||
class ObjectManager(TypedObjectManager):
|
class ObjectManager(TypedObjectManager):
|
||||||
"""
|
"""
|
||||||
|
|
@ -288,7 +290,7 @@ class ObjectManager(TypedObjectManager):
|
||||||
matches = local_and_global_search(ostring, exact=True)
|
matches = local_and_global_search(ostring, exact=True)
|
||||||
if not matches:
|
if not matches:
|
||||||
# if we have no match, check if we are dealing with an "N-keyword" query - if so, strip it.
|
# if we have no match, check if we are dealing with an "N-keyword" query - if so, strip it.
|
||||||
match_number, ostring = AT_MULTIMATCH_INPUT(ostring)
|
match_number, ostring = _AT_MULTIMATCH_INPUT(ostring)
|
||||||
if match_number != None and ostring:
|
if match_number != None and ostring:
|
||||||
# Run search again, without match number:
|
# Run search again, without match number:
|
||||||
matches = local_and_global_search(ostring, exact=True)
|
matches = local_and_global_search(ostring, exact=True)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ from src.scripts.scripthandler import ScriptHandler
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
from src.utils.utils import make_iter, to_unicode, to_str, mod_import
|
from src.utils.utils import make_iter, to_unicode, to_str, mod_import
|
||||||
|
|
||||||
#PlayerDB = ContentType.objects.get(app_label="players", model="playerdb").model_class()
|
#__all__ = ("ObjAttribute", "Alias", "ObjectNick", "ObjectDB")
|
||||||
|
|
||||||
|
|
||||||
_AT_SEARCH_RESULT = mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
|
_AT_SEARCH_RESULT = mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
|
||||||
|
|
||||||
|
|
@ -211,7 +212,7 @@ class ObjectDB(TypedObject):
|
||||||
|
|
||||||
# aliases property (wraps (db_aliases)
|
# aliases property (wraps (db_aliases)
|
||||||
#@property
|
#@property
|
||||||
def aliases_get(self):
|
def __aliases_get(self):
|
||||||
"Getter. Allows for value = self.aliases"
|
"Getter. Allows for value = self.aliases"
|
||||||
try:
|
try:
|
||||||
return _GA(self, "_cached_aliases")
|
return _GA(self, "_cached_aliases")
|
||||||
|
|
@ -220,23 +221,23 @@ class ObjectDB(TypedObject):
|
||||||
_SA(self, "_cached_aliases", aliases)
|
_SA(self, "_cached_aliases", aliases)
|
||||||
return aliases
|
return aliases
|
||||||
#@aliases.setter
|
#@aliases.setter
|
||||||
def aliases_set(self, aliases):
|
def __aliases_set(self, aliases):
|
||||||
"Setter. Allows for self.aliases = value"
|
"Setter. Allows for self.aliases = value"
|
||||||
for alias in make_iter(aliases):
|
for alias in make_iter(aliases):
|
||||||
new_alias = Alias(db_key=alias, db_obj=self)
|
new_alias = Alias(db_key=alias, db_obj=self)
|
||||||
new_alias.save()
|
new_alias.save()
|
||||||
_SA(self, "_cached_aliases", aliases)
|
_SA(self, "_cached_aliases", aliases)
|
||||||
#@aliases.deleter
|
#@aliases.deleter
|
||||||
def aliases_del(self):
|
def __aliases_del(self):
|
||||||
"Deleter. Allows for del self.aliases"
|
"Deleter. Allows for del self.aliases"
|
||||||
for alias in Alias.objects.filter(db_obj=self):
|
for alias in Alias.objects.filter(db_obj=self):
|
||||||
alias.delete()
|
alias.delete()
|
||||||
_DA(self, "_cached_aliases")
|
_DA(self, "_cached_aliases")
|
||||||
aliases = property(aliases_get, aliases_set, aliases_del)
|
aliases = property(__aliases_get, __aliases_set, __aliases_del)
|
||||||
|
|
||||||
# player property (wraps db_player)
|
# player property (wraps db_player)
|
||||||
#@property
|
#@property
|
||||||
def player_get(self):
|
def __player_get(self):
|
||||||
"""
|
"""
|
||||||
Getter. Allows for value = self.player.
|
Getter. Allows for value = self.player.
|
||||||
We have to be careful here since Player is also
|
We have to be careful here since Player is also
|
||||||
|
|
@ -244,29 +245,29 @@ class ObjectDB(TypedObject):
|
||||||
"""
|
"""
|
||||||
return _get_cache(self, "player")
|
return _get_cache(self, "player")
|
||||||
#@player.setter
|
#@player.setter
|
||||||
def player_set(self, player):
|
def __player_set(self, player):
|
||||||
"Setter. Allows for self.player = value"
|
"Setter. Allows for self.player = value"
|
||||||
if isinstance(player, TypeClass):
|
if isinstance(player, TypeClass):
|
||||||
player = player.dbobj
|
player = player.dbobj
|
||||||
_set_cache(self, "player", player)
|
_set_cache(self, "player", player)
|
||||||
#@player.deleter
|
#@player.deleter
|
||||||
def player_del(self):
|
def __player_del(self):
|
||||||
"Deleter. Allows for del self.player"
|
"Deleter. Allows for del self.player"
|
||||||
self.db_player = None
|
self.db_player = None
|
||||||
self.save()
|
self.save()
|
||||||
_del_cache(self, "player")
|
_del_cache(self, "player")
|
||||||
player = property(player_get, player_set, player_del)
|
player = property(__player_get, __player_set, __player_del)
|
||||||
|
|
||||||
# location property (wraps db_location)
|
# location property (wraps db_location)
|
||||||
#@property
|
#@property
|
||||||
def location_get(self):
|
def __location_get(self):
|
||||||
"Getter. Allows for value = self.location."
|
"Getter. Allows for value = self.location."
|
||||||
loc = _get_cache(self, "location")
|
loc = _get_cache(self, "location")
|
||||||
if loc:
|
if loc:
|
||||||
return loc.typeclass
|
return loc.typeclass
|
||||||
return None
|
return None
|
||||||
#@location.setter
|
#@location.setter
|
||||||
def location_set(self, location):
|
def __location_set(self, location):
|
||||||
"Setter. Allows for self.location = location"
|
"Setter. Allows for self.location = location"
|
||||||
try:
|
try:
|
||||||
if location == None or type(location) == ObjectDB:
|
if location == None or type(location) == ObjectDB:
|
||||||
|
|
@ -289,23 +290,23 @@ class ObjectDB(TypedObject):
|
||||||
logger.log_trace(string)
|
logger.log_trace(string)
|
||||||
raise
|
raise
|
||||||
#@location.deleter
|
#@location.deleter
|
||||||
def location_del(self):
|
def __location_del(self):
|
||||||
"Deleter. Allows for del self.location"
|
"Deleter. Allows for del self.location"
|
||||||
self.db_location = None
|
self.db_location = None
|
||||||
self.save()
|
self.save()
|
||||||
_del_cache(self, "location")
|
_del_cache(self, "location")
|
||||||
location = property(location_get, location_set, location_del)
|
location = property(__location_get, __location_set, __location_del)
|
||||||
|
|
||||||
# home property (wraps db_home)
|
# home property (wraps db_home)
|
||||||
#@property
|
#@property
|
||||||
def home_get(self):
|
def __home_get(self):
|
||||||
"Getter. Allows for value = self.home"
|
"Getter. Allows for value = self.home"
|
||||||
home = _get_cache(self, "home")
|
home = _get_cache(self, "home")
|
||||||
if home:
|
if home:
|
||||||
return home.typeclass
|
return home.typeclass
|
||||||
return None
|
return None
|
||||||
#@home.setter
|
#@home.setter
|
||||||
def home_set(self, home):
|
def __home_set(self, home):
|
||||||
"Setter. Allows for self.home = value"
|
"Setter. Allows for self.home = value"
|
||||||
try:
|
try:
|
||||||
if home == None or type(home) == ObjectDB:
|
if home == None or type(home) == ObjectDB:
|
||||||
|
|
@ -326,23 +327,23 @@ class ObjectDB(TypedObject):
|
||||||
logger.log_trace(string)
|
logger.log_trace(string)
|
||||||
#raise
|
#raise
|
||||||
#@home.deleter
|
#@home.deleter
|
||||||
def home_del(self):
|
def __home_del(self):
|
||||||
"Deleter. Allows for del self.home."
|
"Deleter. Allows for del self.home."
|
||||||
self.db_home = None
|
self.db_home = None
|
||||||
self.save()
|
self.save()
|
||||||
_del_cache(self, "home")
|
_del_cache(self, "home")
|
||||||
home = property(home_get, home_set, home_del)
|
home = property(__home_get, __home_set, __home_del)
|
||||||
|
|
||||||
# destination property (wraps db_destination)
|
# destination property (wraps db_destination)
|
||||||
#@property
|
#@property
|
||||||
def destination_get(self):
|
def __destination_get(self):
|
||||||
"Getter. Allows for value = self.destination."
|
"Getter. Allows for value = self.destination."
|
||||||
dest = _get_cache(self, "destination")
|
dest = _get_cache(self, "destination")
|
||||||
if dest:
|
if dest:
|
||||||
return dest.typeclass
|
return dest.typeclass
|
||||||
return None
|
return None
|
||||||
#@destination.setter
|
#@destination.setter
|
||||||
def destination_set(self, destination):
|
def __destination_set(self, destination):
|
||||||
"Setter. Allows for self.destination = destination"
|
"Setter. Allows for self.destination = destination"
|
||||||
try:
|
try:
|
||||||
if destination == None or type(destination) == ObjectDB:
|
if destination == None or type(destination) == ObjectDB:
|
||||||
|
|
@ -365,33 +366,33 @@ class ObjectDB(TypedObject):
|
||||||
logger.log_trace(string)
|
logger.log_trace(string)
|
||||||
raise
|
raise
|
||||||
#@destination.deleter
|
#@destination.deleter
|
||||||
def destination_del(self):
|
def __destination_del(self):
|
||||||
"Deleter. Allows for del self.destination"
|
"Deleter. Allows for del self.destination"
|
||||||
self.db_destination = None
|
self.db_destination = None
|
||||||
self.save()
|
self.save()
|
||||||
_del_cache(self, "destination")
|
_del_cache(self, "destination")
|
||||||
destination = property(destination_get, destination_set, destination_del)
|
destination = property(__destination_get, __destination_set, __destination_del)
|
||||||
|
|
||||||
# cmdset_storage property.
|
# cmdset_storage property.
|
||||||
# This seems very sensitive to caching, so leaving it be for now. /Griatch
|
# This seems very sensitive to caching, so leaving it be for now. /Griatch
|
||||||
#@property
|
#@property
|
||||||
def cmdset_storage_get(self):
|
def __cmdset_storage_get(self):
|
||||||
"Getter. Allows for value = self.name. Returns a list of cmdset_storage."
|
"Getter. Allows for value = self.name. Returns a list of cmdset_storage."
|
||||||
if self.db_cmdset_storage:
|
if self.db_cmdset_storage:
|
||||||
return [path.strip() for path in self.db_cmdset_storage.split(',')]
|
return [path.strip() for path in self.db_cmdset_storage.split(',')]
|
||||||
return []
|
return []
|
||||||
#@cmdset_storage.setter
|
#@cmdset_storage.setter
|
||||||
def cmdset_storage_set(self, value):
|
def __cmdset_storage_set(self, value):
|
||||||
"Setter. Allows for self.name = value. Stores as a comma-separated string."
|
"Setter. Allows for self.name = value. Stores as a comma-separated string."
|
||||||
value = ",".join(str(val).strip() for val in make_iter(value))
|
value = ",".join(str(val).strip() for val in make_iter(value))
|
||||||
self.db_cmdset_storage = value
|
self.db_cmdset_storage = value
|
||||||
self.save()
|
self.save()
|
||||||
#@cmdset_storage.deleter
|
#@cmdset_storage.deleter
|
||||||
def cmdset_storage_del(self):
|
def __cmdset_storage_del(self):
|
||||||
"Deleter. Allows for del self.name"
|
"Deleter. Allows for del self.name"
|
||||||
self.db_cmdset_storage = ""
|
self.db_cmdset_storage = ""
|
||||||
self.save()
|
self.save()
|
||||||
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
|
cmdset_storage = property(__cmdset_storage_get, __cmdset_storage_set, __cmdset_storage_del)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
|
|
@ -409,7 +410,7 @@ class ObjectDB(TypedObject):
|
||||||
_default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object"
|
_default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object"
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def sessions_get(self):
|
def __sessions_get(self):
|
||||||
"""
|
"""
|
||||||
Retrieve sessions connected to this object.
|
Retrieve sessions connected to this object.
|
||||||
"""
|
"""
|
||||||
|
|
@ -417,42 +418,43 @@ class ObjectDB(TypedObject):
|
||||||
if self.player:
|
if self.player:
|
||||||
return self.player.sessions
|
return self.player.sessions
|
||||||
return []
|
return []
|
||||||
sessions = property(sessions_get)
|
sessions = property(__sessions_get)
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def has_player_get(self):
|
def __has_player_get(self):
|
||||||
"""
|
"""
|
||||||
Convenience function for checking if an active player is
|
Convenience function for checking if an active player is
|
||||||
currently connected to this object
|
currently connected to this object
|
||||||
"""
|
"""
|
||||||
return any(self.sessions)
|
return any(self.sessions)
|
||||||
has_player = property(has_player_get)
|
has_player = property(__has_player_get)
|
||||||
is_player = property(has_player_get)
|
is_player = property(__has_player_get)
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def is_superuser_get(self):
|
def __is_superuser_get(self):
|
||||||
"Check if user has a player, and if so, if it is a superuser."
|
"Check if user has a player, and if so, if it is a superuser."
|
||||||
return any(self.sessions) and self.player.is_superuser
|
return any(self.sessions) and self.player.is_superuser
|
||||||
is_superuser = property(is_superuser_get)
|
is_superuser = property(__is_superuser_get)
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def contents_get(self, exclude=None):
|
def contents_get(self, exclude=None):
|
||||||
"""
|
"""
|
||||||
Returns the contents of this object, i.e. all
|
Returns the contents of this object, i.e. all
|
||||||
objects that has this object set as its location.
|
objects that has this object set as its location.
|
||||||
|
This should be publically available.
|
||||||
"""
|
"""
|
||||||
return ObjectDB.objects.get_contents(self, excludeobj=exclude)
|
return ObjectDB.objects.get_contents(self, excludeobj=exclude)
|
||||||
contents = property(contents_get)
|
contents = property(contents_get)
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def exits_get(self):
|
def __exits_get(self):
|
||||||
"""
|
"""
|
||||||
Returns all exits from this object, i.e. all objects
|
Returns all exits from this object, i.e. all objects
|
||||||
at this location having the property destination != None.
|
at this location having the property destination != None.
|
||||||
"""
|
"""
|
||||||
return [exi for exi in self.contents
|
return [exi for exi in self.contents
|
||||||
if exi.destination]
|
if exi.destination]
|
||||||
exits = property(exits_get)
|
exits = property(__exits_get)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ they control by simply linking to a new object's user property.
|
||||||
|
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
from src.commands import cmdset, command
|
from src.commands import cmdset, command
|
||||||
|
__all__ = ("Object", "Character", "Room", "Exit")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Base class to inherit from.
|
# Base class to inherit from.
|
||||||
|
|
@ -24,11 +25,10 @@ from src.commands import cmdset, command
|
||||||
|
|
||||||
class Object(TypeClass):
|
class Object(TypeClass):
|
||||||
"""
|
"""
|
||||||
This is the base class for all in-game objects.
|
This is the base class for all in-game objects. Inherit from this
|
||||||
Inherit from this to create different types of
|
to create different types of objects in the game.
|
||||||
objects in the game.
|
|
||||||
"""
|
"""
|
||||||
|
# __init__ is only defined here in order to present docstring to API.
|
||||||
def __init__(self, dbobj):
|
def __init__(self, dbobj):
|
||||||
"""
|
"""
|
||||||
This is the root typeclass object, implementing an in-game Evennia
|
This is the root typeclass object, implementing an in-game Evennia
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,13 @@
|
||||||
The managers for the custom Player object and permissions.
|
The managers for the custom Player object and permissions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from functools import update_wrapper
|
from functools import update_wrapper
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from src.typeclasses.managers import returns_typeclass_list, returns_typeclass, TypedObjectManager
|
from src.typeclasses.managers import returns_typeclass_list, returns_typeclass, TypedObjectManager
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
|
__all__ = ("PlayerManager",)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Player Manager
|
# Player Manager
|
||||||
|
|
@ -35,16 +36,16 @@ def returns_player_list(method):
|
||||||
players.append(user.get_profile())
|
players.append(user.get_profile())
|
||||||
except Exception:
|
except Exception:
|
||||||
# there is something wrong with get_profile. But
|
# there is something wrong with get_profile. But
|
||||||
# there is a 1-1 relation between Users-Players, so we
|
# there is a 1-1 relation between Users-Players, so we
|
||||||
# try to go the other way instead.
|
# try to go the other way instead.
|
||||||
from src.players.models import PlayerDB
|
from src.players.models import PlayerDB
|
||||||
match = PlayerDB.objects.filter(user=user)
|
match = PlayerDB.objects.filter(user=user)
|
||||||
if match:
|
if match:
|
||||||
players.append(match[0])
|
players.append(match[0])
|
||||||
else:
|
else:
|
||||||
logger.log_trace("No connection User<->Player, maybe database was partially reset?")
|
logger.log_trace("No connection User<->Player, maybe database was partially reset?")
|
||||||
return players
|
return players
|
||||||
return update_wrapper(func, method)
|
return update_wrapper(func, method)
|
||||||
|
|
||||||
def returns_player(method):
|
def returns_player(method):
|
||||||
"""
|
"""
|
||||||
|
|
@ -57,18 +58,18 @@ def returns_player(method):
|
||||||
if match:
|
if match:
|
||||||
return match[0]
|
return match[0]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
return update_wrapper(func, method)
|
return update_wrapper(func, method)
|
||||||
|
|
||||||
class PlayerManager(TypedObjectManager):
|
class PlayerManager(TypedObjectManager):
|
||||||
"""
|
"""
|
||||||
This PlayerManager implements methods for searching
|
This PlayerManager implements methods for searching
|
||||||
and manipulating Players directly from the database.
|
and manipulating Players directly from the database.
|
||||||
|
|
||||||
Evennia-specific search methods (will return Characters if
|
Evennia-specific search methods (will return Characters if
|
||||||
possible or a Typeclass/list of Typeclassed objects, whereas
|
possible or a Typeclass/list of Typeclassed objects, whereas
|
||||||
Django-general methods will return Querysets or database objects):
|
Django-general methods will return Querysets or database objects):
|
||||||
|
|
||||||
dbref (converter)
|
dbref (converter)
|
||||||
dbref_search
|
dbref_search
|
||||||
get_dbref_range
|
get_dbref_range
|
||||||
|
|
@ -83,14 +84,14 @@ class PlayerManager(TypedObjectManager):
|
||||||
get_player_from_name
|
get_player_from_name
|
||||||
player_search (equivalent to ev.search_player)
|
player_search (equivalent to ev.search_player)
|
||||||
swap_character
|
swap_character
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def num_total_players(self):
|
def num_total_players(self):
|
||||||
"""
|
"""
|
||||||
Returns the total number of registered users/players.
|
Returns the total number of registered users/players.
|
||||||
"""
|
"""
|
||||||
return self.count()
|
return self.count()
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_connected_players(self):
|
def get_connected_players(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -99,7 +100,7 @@ class PlayerManager(TypedObjectManager):
|
||||||
return [player for player in self.all() if player.sessions]
|
return [player for player in self.all() if player.sessions]
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
@returns_player_list
|
@returns_player_list
|
||||||
def get_recently_created_players(self, days=7):
|
def get_recently_created_players(self, days=7):
|
||||||
"""
|
"""
|
||||||
Returns a QuerySet containing the player User accounts that have been
|
Returns a QuerySet containing the player User accounts that have been
|
||||||
|
|
@ -145,8 +146,8 @@ class PlayerManager(TypedObjectManager):
|
||||||
players = self.filter(user__username=uname)
|
players = self.filter(user__username=uname)
|
||||||
if players:
|
if players:
|
||||||
return players[0]
|
return players[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# @returns_typeclass_list
|
# @returns_typeclass_list
|
||||||
# def get_players_with_perm(self, permstring):
|
# def get_players_with_perm(self, permstring):
|
||||||
# """
|
# """
|
||||||
|
|
@ -159,7 +160,7 @@ class PlayerManager(TypedObjectManager):
|
||||||
# @returns_typeclass_list
|
# @returns_typeclass_list
|
||||||
# def get_players_with_group(self, groupstring):
|
# def get_players_with_group(self, groupstring):
|
||||||
# """
|
# """
|
||||||
# Returns all players belonging to the given group.
|
# Returns all players belonging to the given group.
|
||||||
# """
|
# """
|
||||||
# return [player.user for player in self.all()
|
# return [player.user for player in self.all()
|
||||||
# if player.has_group(groupstring)]
|
# if player.has_group(groupstring)]
|
||||||
|
|
@ -167,9 +168,9 @@ class PlayerManager(TypedObjectManager):
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def player_search(self, ostring):
|
def player_search(self, ostring):
|
||||||
"""
|
"""
|
||||||
Searches for a particular player by name or
|
Searches for a particular player by name or
|
||||||
database id.
|
database id.
|
||||||
|
|
||||||
ostring = a string or database id.
|
ostring = a string or database id.
|
||||||
"""
|
"""
|
||||||
ostring = ostring.lstrip("*")
|
ostring = ostring.lstrip("*")
|
||||||
|
|
@ -178,7 +179,7 @@ class PlayerManager(TypedObjectManager):
|
||||||
matches = self.filter(id=dbref)
|
matches = self.filter(id=dbref)
|
||||||
if matches:
|
if matches:
|
||||||
return matches
|
return matches
|
||||||
return self.filter(user__username__iexact=ostring)
|
return self.filter(user__username__iexact=ostring)
|
||||||
|
|
||||||
def swap_character(self, player, new_character, delete_old_character=False):
|
def swap_character(self, player, new_character, delete_old_character=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -192,7 +193,7 @@ class PlayerManager(TypedObjectManager):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# do the swap
|
# do the swap
|
||||||
old_character = player.character
|
old_character = player.character
|
||||||
if old_character:
|
if old_character:
|
||||||
old_character.player = None
|
old_character.player = None
|
||||||
try:
|
try:
|
||||||
|
|
@ -202,8 +203,7 @@ class PlayerManager(TypedObjectManager):
|
||||||
# recover old setup
|
# recover old setup
|
||||||
old_character.player = player
|
old_character.player = player
|
||||||
player.character = old_character
|
player.character = old_character
|
||||||
return False
|
return False
|
||||||
if delete_old_character:
|
if delete_old_character:
|
||||||
old_character.delete()
|
old_character.delete()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ from src.utils import logger, utils
|
||||||
from src.commands.cmdsethandler import CmdSetHandler
|
from src.commands.cmdsethandler import CmdSetHandler
|
||||||
from src.commands import cmdhandler
|
from src.commands import cmdhandler
|
||||||
|
|
||||||
|
__all__ = ("PlayerAttribute", "PlayerNick", "PlayerDB")
|
||||||
|
|
||||||
_AT_SEARCH_RESULT = utils.mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
|
_AT_SEARCH_RESULT = utils.mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
"""
|
"""
|
||||||
Typeclass for Player objects
|
Typeclass for Player objects
|
||||||
|
|
||||||
Note that this object is primarily intended to
|
Note that this object is primarily intended to
|
||||||
store OOC information, not game info! This
|
store OOC information, not game info! This
|
||||||
object represents the actual user (not their
|
object represents the actual user (not their
|
||||||
character) and has NO actual precence in the
|
character) and has NO actual precence in the
|
||||||
game world (this is handled by the associated
|
game world (this is handled by the associated
|
||||||
character object, so you should customize that
|
character object, so you should customize that
|
||||||
instead for most things).
|
instead for most things).
|
||||||
|
|
@ -12,12 +12,12 @@ instead for most things).
|
||||||
"""
|
"""
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
|
__all__ = ("Player",)
|
||||||
CMDSET_OOC = settings.CMDSET_OOC
|
CMDSET_OOC = settings.CMDSET_OOC
|
||||||
|
|
||||||
class Player(TypeClass):
|
class Player(TypeClass):
|
||||||
"""
|
"""
|
||||||
Base typeclass for all Players.
|
Base typeclass for all Players.
|
||||||
"""
|
"""
|
||||||
def __init__(self, dbobj):
|
def __init__(self, dbobj):
|
||||||
"""
|
"""
|
||||||
|
|
@ -27,7 +27,7 @@ class Player(TypeClass):
|
||||||
can connect to a Character Object in order to "enter" the
|
can connect to a Character Object in order to "enter" the
|
||||||
game.
|
game.
|
||||||
|
|
||||||
Player Typeclass API:
|
Player Typeclass API:
|
||||||
|
|
||||||
* Available properties (only available on initiated typeclass objects)
|
* Available properties (only available on initiated typeclass objects)
|
||||||
|
|
||||||
|
|
@ -38,22 +38,22 @@ class Player(TypeClass):
|
||||||
dbobj (Player, read-only) - link to database model. dbobj.typeclass points back to this class
|
dbobj (Player, read-only) - link to database model. dbobj.typeclass points back to this class
|
||||||
typeclass (Player, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
|
typeclass (Player, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
|
||||||
date_created (string) - time stamp of object creation
|
date_created (string) - time stamp of object creation
|
||||||
permissions (list of strings) - list of permission strings
|
permissions (list of strings) - list of permission strings
|
||||||
|
|
||||||
user (User, read-only) - django User authorization object
|
user (User, read-only) - django User authorization object
|
||||||
obj (Object) - game object controlled by player. 'character' can also be used.
|
obj (Object) - game object controlled by player. 'character' can also be used.
|
||||||
sessions (list of Sessions) - sessions connected to this player
|
sessions (list of Sessions) - sessions connected to this player
|
||||||
is_superuser (bool, read-only) - if the connected user is a superuser
|
is_superuser (bool, read-only) - if the connected user is a superuser
|
||||||
|
|
||||||
* Handlers
|
* Handlers
|
||||||
|
|
||||||
locks - lock-handler: use locks.add() to add new lock strings
|
locks - lock-handler: use locks.add() to add new lock strings
|
||||||
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
|
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
|
||||||
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
|
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
|
||||||
scripts - script-handler. Add new scripts to object with scripts.add()
|
scripts - script-handler. Add new scripts to object with scripts.add()
|
||||||
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
|
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
|
||||||
nicks - nick-handler. New nicks with nicks.add().
|
nicks - nick-handler. New nicks with nicks.add().
|
||||||
|
|
||||||
* Helper methods
|
* Helper methods
|
||||||
|
|
||||||
msg(outgoing_string, from_obj=None, data=None)
|
msg(outgoing_string, from_obj=None, data=None)
|
||||||
|
|
@ -68,12 +68,12 @@ class Player(TypeClass):
|
||||||
* Hook methods
|
* Hook methods
|
||||||
|
|
||||||
basetype_setup()
|
basetype_setup()
|
||||||
at_player_creation()
|
at_player_creation()
|
||||||
|
|
||||||
- note that the following hooks are also found on Objects and are
|
- note that the following hooks are also found on Objects and are
|
||||||
usually handled on the character level:
|
usually handled on the character level:
|
||||||
|
|
||||||
at_init()
|
at_init()
|
||||||
at_cmdset_get()
|
at_cmdset_get()
|
||||||
at_first_login()
|
at_first_login()
|
||||||
at_post_login()
|
at_post_login()
|
||||||
|
|
@ -86,11 +86,11 @@ class Player(TypeClass):
|
||||||
"""
|
"""
|
||||||
super(Player, self).__init__(dbobj)
|
super(Player, self).__init__(dbobj)
|
||||||
|
|
||||||
## methods inherited from database model
|
## methods inherited from database model
|
||||||
|
|
||||||
def msg(self, outgoing_string, from_obj=None, data=None):
|
def msg(self, outgoing_string, from_obj=None, data=None):
|
||||||
"""
|
"""
|
||||||
Evennia -> User
|
Evennia -> User
|
||||||
This is the main route for sending data back to the user from the server.
|
This is the main route for sending data back to the user from the server.
|
||||||
|
|
||||||
outgoing_string (string) - text data to send
|
outgoing_string (string) - text data to send
|
||||||
|
|
@ -106,7 +106,7 @@ class Player(TypeClass):
|
||||||
|
|
||||||
new_character (Object) - character/object to swap to
|
new_character (Object) - character/object to swap to
|
||||||
delete_old_character (bool) - delete the old character when swapping
|
delete_old_character (bool) - delete the old character when swapping
|
||||||
|
|
||||||
Returns: True/False depending on if swap suceeded or not.
|
Returns: True/False depending on if swap suceeded or not.
|
||||||
"""
|
"""
|
||||||
return self.dbobj.swap_character(new_character, delete_old_character=delete_old_character)
|
return self.dbobj.swap_character(new_character, delete_old_character=delete_old_character)
|
||||||
|
|
@ -117,44 +117,44 @@ class Player(TypeClass):
|
||||||
lets its typeclass execute the command. Evennia also calls
|
lets its typeclass execute the command. Evennia also calls
|
||||||
this method whenever the player sends a command on the command line.
|
this method whenever the player sends a command on the command line.
|
||||||
|
|
||||||
Argument:
|
Argument:
|
||||||
raw_string (string) - raw command input
|
raw_string (string) - raw command input
|
||||||
|
|
||||||
Returns Deferred - this is an asynchronous Twisted object that will
|
Returns Deferred - this is an asynchronous Twisted object that will
|
||||||
not fire until the command has actually finished executing. To overload
|
not fire until the command has actually finished executing. To overload
|
||||||
this one needs to attach callback functions to it, with addCallback(function).
|
this one needs to attach callback functions to it, with addCallback(function).
|
||||||
This function will be called with an eventual return value from the command
|
This function will be called with an eventual return value from the command
|
||||||
execution.
|
execution.
|
||||||
|
|
||||||
This return is not used at all by Evennia by default, but might be useful
|
This return is not used at all by Evennia by default, but might be useful
|
||||||
for coders intending to implement some sort of nested command structure.
|
for coders intending to implement some sort of nested command structure.
|
||||||
"""
|
"""
|
||||||
self.dbobj.execute_cmd(raw_string)
|
self.dbobj.execute_cmd(raw_string)
|
||||||
|
|
||||||
def search(self, ostring, global_search=False, attribute_name=None, use_nicks=False,
|
def search(self, ostring, global_search=False, attribute_name=None, use_nicks=False,
|
||||||
location=None, ignore_errors=False, player=False):
|
location=None, ignore_errors=False, player=False):
|
||||||
"""
|
"""
|
||||||
This method mimicks object.search if self.character is set. Otherwise only
|
This method mimicks object.search if self.character is set. Otherwise only
|
||||||
other Players can be searched with this method.
|
other Players can be searched with this method.
|
||||||
"""
|
"""
|
||||||
self.dbobj.search(ostring, global_search=global_search, attribute_name=attribute_name, use_nicks=use_nicks,
|
self.dbobj.search(ostring, global_search=global_search, attribute_name=attribute_name, use_nicks=use_nicks,
|
||||||
location=location, ignore_errors=ignore_errors, player=player)
|
location=location, ignore_errors=ignore_errors, player=player)
|
||||||
|
|
||||||
def is_typeclass(self, typeclass, exact=False):
|
def is_typeclass(self, typeclass, exact=False):
|
||||||
"""
|
"""
|
||||||
Returns true if this object has this type
|
Returns true if this object has this type
|
||||||
OR has a typeclass which is an subclass of
|
OR has a typeclass which is an subclass of
|
||||||
the given typeclass.
|
the given typeclass.
|
||||||
|
|
||||||
typeclass - can be a class object or the
|
typeclass - can be a class object or the
|
||||||
python path to such an object to match against.
|
python path to such an object to match against.
|
||||||
|
|
||||||
exact - returns true only if the object's
|
exact - returns true only if the object's
|
||||||
type is exactly this typeclass, ignoring
|
type is exactly this typeclass, ignoring
|
||||||
parents.
|
parents.
|
||||||
|
|
||||||
Returns: Boolean
|
Returns: Boolean
|
||||||
"""
|
"""
|
||||||
return self.dbobj.is_typeclass(typeclass, exact=exact)
|
return self.dbobj.is_typeclass(typeclass, exact=exact)
|
||||||
|
|
||||||
def swap_typeclass(self, new_typeclass, clean_attributes=False, no_default=True):
|
def swap_typeclass(self, new_typeclass, clean_attributes=False, no_default=True):
|
||||||
|
|
@ -162,18 +162,18 @@ class Player(TypeClass):
|
||||||
This performs an in-situ swap of the typeclass. This means
|
This performs an in-situ swap of the typeclass. This means
|
||||||
that in-game, this object will suddenly be something else.
|
that in-game, this object will suddenly be something else.
|
||||||
Player will not be affected. To 'move' a player to a different
|
Player will not be affected. To 'move' a player to a different
|
||||||
object entirely (while retaining this object's type), use
|
object entirely (while retaining this object's type), use
|
||||||
self.player.swap_object().
|
self.player.swap_object().
|
||||||
|
|
||||||
Note that this might be an error prone operation if the
|
Note that this might be an error prone operation if the
|
||||||
old/new typeclass was heavily customized - your code
|
old/new typeclass was heavily customized - your code
|
||||||
might expect one and not the other, so be careful to
|
might expect one and not the other, so be careful to
|
||||||
bug test your code if using this feature! Often its easiest
|
bug test your code if using this feature! Often its easiest
|
||||||
to create a new object and just swap the player over to
|
to create a new object and just swap the player over to
|
||||||
that one instead.
|
that one instead.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
new_typeclass (path/classobj) - type to switch to
|
new_typeclass (path/classobj) - type to switch to
|
||||||
clean_attributes (bool/list) - will delete all attributes
|
clean_attributes (bool/list) - will delete all attributes
|
||||||
stored on this object (but not any
|
stored on this object (but not any
|
||||||
of the database fields such as name or
|
of the database fields such as name or
|
||||||
|
|
@ -185,10 +185,10 @@ class Player(TypeClass):
|
||||||
no_default - if this is active, the swapper will not allow for
|
no_default - if this is active, the swapper will not allow for
|
||||||
swapping to a default typeclass in case the given
|
swapping to a default typeclass in case the given
|
||||||
one fails for some reason. Instead the old one
|
one fails for some reason. Instead the old one
|
||||||
will be preserved.
|
will be preserved.
|
||||||
Returns:
|
Returns:
|
||||||
boolean True/False depending on if the swap worked or not.
|
boolean True/False depending on if the swap worked or not.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.dbobj.swap_typeclass(new_typeclass, clean_attributes=clean_attributes, no_default=no_default)
|
self.dbobj.swap_typeclass(new_typeclass, clean_attributes=clean_attributes, no_default=no_default)
|
||||||
|
|
@ -200,52 +200,52 @@ class Player(TypeClass):
|
||||||
accessing_obj (Object)- object trying to access this one
|
accessing_obj (Object)- object trying to access this one
|
||||||
access_type (string) - type of access sought
|
access_type (string) - type of access sought
|
||||||
default (bool) - what to return if no lock of access_type was found
|
default (bool) - what to return if no lock of access_type was found
|
||||||
"""
|
"""
|
||||||
return self.dbobj.access(accessing_obj, access_type=access_type, default=default)
|
return self.dbobj.access(accessing_obj, access_type=access_type, default=default)
|
||||||
|
|
||||||
def check_permstring(self, permstring):
|
def check_permstring(self, permstring):
|
||||||
"""
|
"""
|
||||||
This explicitly checks the given string against this object's
|
This explicitly checks the given string against this object's
|
||||||
'permissions' property without involving any locks.
|
'permissions' property without involving any locks.
|
||||||
|
|
||||||
permstring (string) - permission string that need to match a permission on the object.
|
permstring (string) - permission string that need to match a permission on the object.
|
||||||
(example: 'Builders')
|
(example: 'Builders')
|
||||||
"""
|
"""
|
||||||
return self.dbobj.check_permstring(permstring)
|
return self.dbobj.check_permstring(permstring)
|
||||||
|
|
||||||
## player hooks
|
## player hooks
|
||||||
|
|
||||||
def basetype_setup(self):
|
def basetype_setup(self):
|
||||||
"""
|
"""
|
||||||
This sets up the basic properties for a player.
|
This sets up the basic properties for a player.
|
||||||
Overload this with at_player_creation rather than
|
Overload this with at_player_creation rather than
|
||||||
changing this method.
|
changing this method.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# the text encoding to use.
|
# the text encoding to use.
|
||||||
self.db.encoding = "utf-8"
|
self.db.encoding = "utf-8"
|
||||||
|
|
||||||
# A basic security setup
|
# A basic security setup
|
||||||
self.locks.add("examine:perm(Wizards)")
|
self.locks.add("examine:perm(Wizards)")
|
||||||
self.locks.add("edit:perm(Wizards)")
|
self.locks.add("edit:perm(Wizards)")
|
||||||
self.locks.add("delete:perm(Wizards)")
|
self.locks.add("delete:perm(Wizards)")
|
||||||
self.locks.add("boot:perm(Wizards)")
|
self.locks.add("boot:perm(Wizards)")
|
||||||
self.locks.add("msg:all()")
|
self.locks.add("msg:all()")
|
||||||
|
|
||||||
# The ooc player cmdset
|
# The ooc player cmdset
|
||||||
self.cmdset.add_default(CMDSET_OOC, permanent=True)
|
self.cmdset.add_default(CMDSET_OOC, permanent=True)
|
||||||
self.cmdset.outside_access = False
|
self.cmdset.outside_access = False
|
||||||
|
|
||||||
def at_player_creation(self):
|
def at_player_creation(self):
|
||||||
"""
|
"""
|
||||||
This is called once, the very first time
|
This is called once, the very first time
|
||||||
the player is created (i.e. first time they
|
the player is created (i.e. first time they
|
||||||
register with the game). It's a good place
|
register with the game). It's a good place
|
||||||
to store attributes all players should have,
|
to store attributes all players should have,
|
||||||
like configuration values etc.
|
like configuration values etc.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def at_init(self):
|
def at_init(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -257,7 +257,7 @@ class Player(TypeClass):
|
||||||
happens the moment the player logs in or reconnects after a
|
happens the moment the player logs in or reconnects after a
|
||||||
reload.
|
reload.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Note that the hooks below also exist in the character object's
|
# Note that the hooks below also exist in the character object's
|
||||||
# typeclass. You can often ignore these and rely on the character
|
# typeclass. You can often ignore these and rely on the character
|
||||||
|
|
@ -292,7 +292,7 @@ class Player(TypeClass):
|
||||||
"""
|
"""
|
||||||
Called at the end of the login
|
Called at the end of the login
|
||||||
process, just before letting
|
process, just before letting
|
||||||
them loose.
|
them loose.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -307,29 +307,29 @@ class Player(TypeClass):
|
||||||
"""
|
"""
|
||||||
Called when any text is emitted to this
|
Called when any text is emitted to this
|
||||||
object. If it returns False, no text
|
object. If it returns False, no text
|
||||||
will be sent automatically.
|
will be sent automatically.
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def at_message_send(self, message, to_object):
|
def at_message_send(self, message, to_object):
|
||||||
"""
|
"""
|
||||||
Called whenever this object tries to send text
|
Called whenever this object tries to send text
|
||||||
to another object. Only called if the object supplied
|
to another object. Only called if the object supplied
|
||||||
itself as a sender in the msg() call.
|
itself as a sender in the msg() call.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_server_reload(self):
|
def at_server_reload(self):
|
||||||
"""
|
"""
|
||||||
This hook is called whenever the server is shutting down for restart/reboot.
|
This hook is called whenever the server is shutting down for restart/reboot.
|
||||||
If you want to, for example, save non-persistent properties across a restart,
|
If you want to, for example, save non-persistent properties across a restart,
|
||||||
this is the place to do it.
|
this is the place to do it.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_server_shutdown(self):
|
def at_server_shutdown(self):
|
||||||
"""
|
"""
|
||||||
This hook is called whenever the server is shutting down fully (i.e. not for
|
This hook is called whenever the server is shutting down fully (i.e. not for
|
||||||
a restart).
|
a restart).
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,19 @@ The custom manager for Scripts.
|
||||||
|
|
||||||
from src.typeclasses.managers import TypedObjectManager
|
from src.typeclasses.managers import TypedObjectManager
|
||||||
from src.typeclasses.managers import returns_typeclass_list
|
from src.typeclasses.managers import returns_typeclass_list
|
||||||
|
__all__ = ("ScriptManager",)
|
||||||
|
|
||||||
VALIDATE_ITERATION = 0
|
VALIDATE_ITERATION = 0
|
||||||
|
|
||||||
class ScriptManager(TypedObjectManager):
|
class ScriptManager(TypedObjectManager):
|
||||||
"""
|
"""
|
||||||
This Scriptmanager implements methods for searching
|
This Scriptmanager implements methods for searching
|
||||||
and manipulating Scripts directly from the database.
|
and manipulating Scripts directly from the database.
|
||||||
|
|
||||||
Evennia-specific search methods (will return Typeclasses or
|
Evennia-specific search methods (will return Typeclasses or
|
||||||
lists of Typeclasses, whereas Django-general methods will return
|
lists of Typeclasses, whereas Django-general methods will return
|
||||||
Querysets or database objects).
|
Querysets or database objects).
|
||||||
|
|
||||||
dbref (converter)
|
dbref (converter)
|
||||||
dbref_search
|
dbref_search
|
||||||
get_dbref_range
|
get_dbref_range
|
||||||
|
|
@ -38,15 +39,15 @@ class ScriptManager(TypedObjectManager):
|
||||||
if not obj:
|
if not obj:
|
||||||
return []
|
return []
|
||||||
scripts = self.filter(db_obj=obj)
|
scripts = self.filter(db_obj=obj)
|
||||||
if key:
|
if key:
|
||||||
return scripts.filter(db_key=key)
|
return scripts.filter(db_key=key)
|
||||||
return scripts
|
return scripts
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_all_scripts(self, key=None):
|
def get_all_scripts(self, key=None):
|
||||||
"""
|
"""
|
||||||
Return all scripts, alternative only
|
Return all scripts, alternative only
|
||||||
scripts with a certain key/dbref or path.
|
scripts with a certain key/dbref or path.
|
||||||
"""
|
"""
|
||||||
if key:
|
if key:
|
||||||
dbref = self.dbref(key)
|
dbref = self.dbref(key)
|
||||||
|
|
@ -66,7 +67,7 @@ class ScriptManager(TypedObjectManager):
|
||||||
This stops and deletes a specific script directly
|
This stops and deletes a specific script directly
|
||||||
from the script database. This might be
|
from the script database. This might be
|
||||||
needed for global scripts not tied to
|
needed for global scripts not tied to
|
||||||
a specific game object.
|
a specific game object.
|
||||||
"""
|
"""
|
||||||
scripts = self.get_id(dbref)
|
scripts = self.get_id(dbref)
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
|
|
@ -76,7 +77,7 @@ class ScriptManager(TypedObjectManager):
|
||||||
"""
|
"""
|
||||||
This cleans up the script database of all non-persistent
|
This cleans up the script database of all non-persistent
|
||||||
scripts, or only those on obj. It is called every time the server restarts
|
scripts, or only those on obj. It is called every time the server restarts
|
||||||
and
|
and
|
||||||
"""
|
"""
|
||||||
if obj:
|
if obj:
|
||||||
to_stop = self.filter(db_persistent=False, db_obj=obj)
|
to_stop = self.filter(db_persistent=False, db_obj=obj)
|
||||||
|
|
@ -86,70 +87,70 @@ class ScriptManager(TypedObjectManager):
|
||||||
for script in to_stop.filter(db_is_active=True):
|
for script in to_stop.filter(db_is_active=True):
|
||||||
script.stop()
|
script.stop()
|
||||||
for script in to_stop.filter(db_is_active=False):
|
for script in to_stop.filter(db_is_active=False):
|
||||||
script.delete()
|
script.delete()
|
||||||
return nr_deleted
|
return nr_deleted
|
||||||
|
|
||||||
def validate(self, scripts=None, obj=None, key=None, dbref=None,
|
def validate(self, scripts=None, obj=None, key=None, dbref=None,
|
||||||
init_mode=False):
|
init_mode=False):
|
||||||
"""
|
"""
|
||||||
This will step through the script database and make sure
|
This will step through the script database and make sure
|
||||||
all objects run scripts that are still valid in the context
|
all objects run scripts that are still valid in the context
|
||||||
they are in. This is called by the game engine at regular
|
they are in. This is called by the game engine at regular
|
||||||
intervals but can also be initiated by player scripts.
|
intervals but can also be initiated by player scripts.
|
||||||
If key and/or obj is given, only update the related
|
If key and/or obj is given, only update the related
|
||||||
script/object.
|
script/object.
|
||||||
|
|
||||||
Only one of the arguments are supposed to be supplied
|
Only one of the arguments are supposed to be supplied
|
||||||
at a time, since they are exclusive to each other.
|
at a time, since they are exclusive to each other.
|
||||||
|
|
||||||
scripts = a list of scripts objects obtained somewhere.
|
scripts = a list of scripts objects obtained somewhere.
|
||||||
obj = validate only scripts defined on a special object.
|
obj = validate only scripts defined on a special object.
|
||||||
key = validate only scripts with a particular key
|
key = validate only scripts with a particular key
|
||||||
dbref = validate only the single script with this particular id.
|
dbref = validate only the single script with this particular id.
|
||||||
|
|
||||||
init_mode - This is used during server upstart and can have
|
init_mode - This is used during server upstart and can have
|
||||||
three values:
|
three values:
|
||||||
False (no init mode). Called during run.
|
False (no init mode). Called during run.
|
||||||
"reset" - server reboot. Kill non-persistent scripts
|
"reset" - server reboot. Kill non-persistent scripts
|
||||||
"reload" - server reload. Keep non-persistent scripts.
|
"reload" - server reload. Keep non-persistent scripts.
|
||||||
|
|
||||||
This method also makes sure start any scripts it validates,
|
This method also makes sure start any scripts it validates,
|
||||||
this should be harmless, since already-active scripts
|
this should be harmless, since already-active scripts
|
||||||
have the property 'is_running' set and will be skipped.
|
have the property 'is_running' set and will be skipped.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# we store a variable that tracks if we are calling a
|
# we store a variable that tracks if we are calling a
|
||||||
# validation from within another validation (avoids
|
# validation from within another validation (avoids
|
||||||
# loops).
|
# loops).
|
||||||
|
|
||||||
global VALIDATE_ITERATION
|
global VALIDATE_ITERATION
|
||||||
if VALIDATE_ITERATION > 0:
|
if VALIDATE_ITERATION > 0:
|
||||||
# we are in a nested validation. Exit.
|
# we are in a nested validation. Exit.
|
||||||
VALIDATE_ITERATION -= 1
|
VALIDATE_ITERATION -= 1
|
||||||
return None, None
|
return None, None
|
||||||
VALIDATE_ITERATION += 1
|
VALIDATE_ITERATION += 1
|
||||||
|
|
||||||
# not in a validation - loop. Validate as normal.
|
# not in a validation - loop. Validate as normal.
|
||||||
|
|
||||||
nr_started = 0
|
nr_started = 0
|
||||||
nr_stopped = 0
|
nr_stopped = 0
|
||||||
|
|
||||||
if init_mode:
|
if init_mode:
|
||||||
if init_mode == 'reset':
|
if init_mode == 'reset':
|
||||||
# special mode when server starts or object logs in.
|
# special mode when server starts or object logs in.
|
||||||
# This deletes all non-persistent scripts from database
|
# This deletes all non-persistent scripts from database
|
||||||
nr_stopped += self.remove_non_persistent(obj=obj)
|
nr_stopped += self.remove_non_persistent(obj=obj)
|
||||||
# turn off the activity flag for all remaining scripts
|
# turn off the activity flag for all remaining scripts
|
||||||
scripts = self.get_all_scripts()
|
scripts = self.get_all_scripts()
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
script.dbobj.is_active = False
|
script.dbobj.is_active = False
|
||||||
|
|
||||||
elif not scripts:
|
elif not scripts:
|
||||||
# normal operation
|
# normal operation
|
||||||
if dbref and self.dbref(dbref):
|
if dbref and self.dbref(dbref):
|
||||||
scripts = self.get_id(dbref)
|
scripts = self.get_id(dbref)
|
||||||
elif obj:
|
elif obj:
|
||||||
scripts = self.get_all_scripts_on_obj(obj, key=key)
|
scripts = self.get_all_scripts_on_obj(obj, key=key)
|
||||||
else:
|
else:
|
||||||
scripts = self.get_all_scripts(key=key) #self.model.get_all_cached_instances()
|
scripts = self.get_all_scripts(key=key) #self.model.get_all_cached_instances()
|
||||||
|
|
||||||
|
|
@ -158,46 +159,46 @@ class ScriptManager(TypedObjectManager):
|
||||||
VALIDATE_ITERATION -= 1
|
VALIDATE_ITERATION -= 1
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
#print "scripts to validate: [%s]" % (", ".join(script.key for script in scripts))
|
#print "scripts to validate: [%s]" % (", ".join(script.key for script in scripts))
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
#print "validating %s (%i) (init_mode=%s)" % (script.key, id(script.dbobj), init_mode)
|
#print "validating %s (%i) (init_mode=%s)" % (script.key, id(script.dbobj), init_mode)
|
||||||
if script.is_valid():
|
if script.is_valid():
|
||||||
nr_started += script.start(force_restart=init_mode)
|
nr_started += script.start(force_restart=init_mode)
|
||||||
#print "back from start. nr_started=", nr_started
|
#print "back from start. nr_started=", nr_started
|
||||||
else:
|
else:
|
||||||
script.stop()
|
script.stop()
|
||||||
nr_stopped += 1
|
nr_stopped += 1
|
||||||
VALIDATE_ITERATION -= 1
|
VALIDATE_ITERATION -= 1
|
||||||
return nr_started, nr_stopped
|
return nr_started, nr_stopped
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def script_search(self, ostring, obj=None, only_timed=False):
|
def script_search(self, ostring, obj=None, only_timed=False):
|
||||||
"""
|
"""
|
||||||
Search for a particular script.
|
Search for a particular script.
|
||||||
|
|
||||||
ostring - search criterion - a script ID or key
|
ostring - search criterion - a script ID or key
|
||||||
obj - limit search to scripts defined on this object
|
obj - limit search to scripts defined on this object
|
||||||
only_timed - limit search only to scripts that run
|
only_timed - limit search only to scripts that run
|
||||||
on a timer.
|
on a timer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ostring = ostring.strip()
|
ostring = ostring.strip()
|
||||||
|
|
||||||
dbref = self.dbref(ostring)
|
dbref = self.dbref(ostring)
|
||||||
if dbref:
|
if dbref:
|
||||||
# this is a dbref, try to find the script directly
|
# this is a dbref, try to find the script directly
|
||||||
dbref_match = self.dbref_search(dbref)
|
dbref_match = self.dbref_search(dbref)
|
||||||
if dbref_match:
|
if dbref_match:
|
||||||
ok = True
|
ok = True
|
||||||
if obj and obj != dbref_match.obj:
|
if obj and obj != dbref_match.obj:
|
||||||
ok = False
|
ok = False
|
||||||
if only_timed and dbref_match.interval:
|
if only_timed and dbref_match.interval:
|
||||||
ok = False
|
ok = False
|
||||||
if ok:
|
if ok:
|
||||||
return [dbref_match]
|
return [dbref_match]
|
||||||
# not a dbref; normal search
|
# not a dbref; normal search
|
||||||
scripts = self.filter(db_key__iexact=ostring)
|
scripts = self.filter(db_key__iexact=ostring)
|
||||||
|
|
||||||
if obj:
|
if obj:
|
||||||
scripts = scripts.exclude(db_obj=None).filter(db_obj__db_key__iexact=ostring)
|
scripts = scripts.exclude(db_obj=None).filter(db_obj__db_key__iexact=ostring)
|
||||||
if only_timed:
|
if only_timed:
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ from src.typeclasses.models import Attribute, TypedObject
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from src.scripts.manager import ScriptManager
|
from src.scripts.manager import ScriptManager
|
||||||
|
|
||||||
|
__all__ = ("ScriptAttribute", "ScriptDB")
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# ScriptAttribute
|
# ScriptAttribute
|
||||||
|
|
@ -121,122 +123,122 @@ class ScriptDB(TypedObject):
|
||||||
|
|
||||||
# desc property (wraps db_desc)
|
# desc property (wraps db_desc)
|
||||||
#@property
|
#@property
|
||||||
def desc_get(self):
|
def __desc_get(self):
|
||||||
"Getter. Allows for value = self.desc"
|
"Getter. Allows for value = self.desc"
|
||||||
return self.db_desc
|
return self.db_desc
|
||||||
#@desc.setter
|
#@desc.setter
|
||||||
def desc_set(self, value):
|
def __desc_set(self, value):
|
||||||
"Setter. Allows for self.desc = value"
|
"Setter. Allows for self.desc = value"
|
||||||
self.db_desc = value
|
self.db_desc = value
|
||||||
self.save()
|
self.save()
|
||||||
#@desc.deleter
|
#@desc.deleter
|
||||||
def desc_del(self):
|
def __desc_del(self):
|
||||||
"Deleter. Allows for del self.desc"
|
"Deleter. Allows for del self.desc"
|
||||||
self.db_desc = ""
|
self.db_desc = ""
|
||||||
self.save()
|
self.save()
|
||||||
desc = property(desc_get, desc_set, desc_del)
|
desc = property(__desc_get, __desc_set, __desc_del)
|
||||||
|
|
||||||
# obj property (wraps db_obj)
|
# obj property (wraps db_obj)
|
||||||
#@property
|
#@property
|
||||||
def obj_get(self):
|
def __obj_get(self):
|
||||||
"Getter. Allows for value = self.obj"
|
"Getter. Allows for value = self.obj"
|
||||||
return self.db_obj
|
return self.db_obj
|
||||||
#@obj.setter
|
#@obj.setter
|
||||||
def obj_set(self, value):
|
def __obj_set(self, value):
|
||||||
"Setter. Allows for self.obj = value"
|
"Setter. Allows for self.obj = value"
|
||||||
self.db_obj = value
|
self.db_obj = value
|
||||||
self.save()
|
self.save()
|
||||||
#@obj.deleter
|
#@obj.deleter
|
||||||
def obj_del(self):
|
def __obj_del(self):
|
||||||
"Deleter. Allows for del self.obj"
|
"Deleter. Allows for del self.obj"
|
||||||
self.db_obj = None
|
self.db_obj = None
|
||||||
self.save()
|
self.save()
|
||||||
obj = property(obj_get, obj_set, obj_del)
|
obj = property(__obj_get, __obj_set, __obj_del)
|
||||||
|
|
||||||
# interval property (wraps db_interval)
|
# interval property (wraps db_interval)
|
||||||
#@property
|
#@property
|
||||||
def interval_get(self):
|
def __interval_get(self):
|
||||||
"Getter. Allows for value = self.interval"
|
"Getter. Allows for value = self.interval"
|
||||||
return self.db_interval
|
return self.db_interval
|
||||||
#@interval.setter
|
#@interval.setter
|
||||||
def interval_set(self, value):
|
def __interval_set(self, value):
|
||||||
"Setter. Allows for self.interval = value"
|
"Setter. Allows for self.interval = value"
|
||||||
self.db_interval = int(value)
|
self.db_interval = int(value)
|
||||||
self.save()
|
self.save()
|
||||||
#@interval.deleter
|
#@interval.deleter
|
||||||
def interval_del(self):
|
def __interval_del(self):
|
||||||
"Deleter. Allows for del self.interval"
|
"Deleter. Allows for del self.interval"
|
||||||
self.db_interval = 0
|
self.db_interval = 0
|
||||||
self.save()
|
self.save()
|
||||||
interval = property(interval_get, interval_set, interval_del)
|
interval = property(__interval_get, __interval_set, __interval_del)
|
||||||
|
|
||||||
# start_delay property (wraps db_start_delay)
|
# start_delay property (wraps db_start_delay)
|
||||||
#@property
|
#@property
|
||||||
def start_delay_get(self):
|
def __start_delay_get(self):
|
||||||
"Getter. Allows for value = self.start_delay"
|
"Getter. Allows for value = self.start_delay"
|
||||||
return self.db_start_delay
|
return self.db_start_delay
|
||||||
#@start_delay.setter
|
#@start_delay.setter
|
||||||
def start_delay_set(self, value):
|
def __start_delay_set(self, value):
|
||||||
"Setter. Allows for self.start_delay = value"
|
"Setter. Allows for self.start_delay = value"
|
||||||
self.db_start_delay = value
|
self.db_start_delay = value
|
||||||
self.save()
|
self.save()
|
||||||
#@start_delay.deleter
|
#@start_delay.deleter
|
||||||
def start_delay_del(self):
|
def __start_delay_del(self):
|
||||||
"Deleter. Allows for del self.start_delay"
|
"Deleter. Allows for del self.start_delay"
|
||||||
self.db_start_delay = False
|
self.db_start_delay = False
|
||||||
self.save()
|
self.save()
|
||||||
start_delay = property(start_delay_get, start_delay_set, start_delay_del)
|
start_delay = property(__start_delay_get, __start_delay_set, __start_delay_del)
|
||||||
|
|
||||||
# repeats property (wraps db_repeats)
|
# repeats property (wraps db_repeats)
|
||||||
#@property
|
#@property
|
||||||
def repeats_get(self):
|
def __repeats_get(self):
|
||||||
"Getter. Allows for value = self.repeats"
|
"Getter. Allows for value = self.repeats"
|
||||||
return self.db_repeats
|
return self.db_repeats
|
||||||
#@repeats.setter
|
#@repeats.setter
|
||||||
def repeats_set(self, value):
|
def __repeats_set(self, value):
|
||||||
"Setter. Allows for self.repeats = value"
|
"Setter. Allows for self.repeats = value"
|
||||||
self.db_repeats = int(value)
|
self.db_repeats = int(value)
|
||||||
self.save()
|
self.save()
|
||||||
#@repeats.deleter
|
#@repeats.deleter
|
||||||
def repeats_del(self):
|
def __repeats_del(self):
|
||||||
"Deleter. Allows for del self.repeats"
|
"Deleter. Allows for del self.repeats"
|
||||||
self.db_repeats = 0
|
self.db_repeats = 0
|
||||||
self.save()
|
self.save()
|
||||||
repeats = property(repeats_get, repeats_set, repeats_del)
|
repeats = property(__repeats_get, __repeats_set, __repeats_del)
|
||||||
|
|
||||||
# persistent property (wraps db_persistent)
|
# persistent property (wraps db_persistent)
|
||||||
#@property
|
#@property
|
||||||
def persistent_get(self):
|
def __persistent_get(self):
|
||||||
"Getter. Allows for value = self.persistent"
|
"Getter. Allows for value = self.persistent"
|
||||||
return self.db_persistent
|
return self.db_persistent
|
||||||
#@persistent.setter
|
#@persistent.setter
|
||||||
def persistent_set(self, value):
|
def __persistent_set(self, value):
|
||||||
"Setter. Allows for self.persistent = value"
|
"Setter. Allows for self.persistent = value"
|
||||||
self.db_persistent = value
|
self.db_persistent = value
|
||||||
self.save()
|
self.save()
|
||||||
#@persistent.deleter
|
#@persistent.deleter
|
||||||
def persistent_del(self):
|
def __persistent_del(self):
|
||||||
"Deleter. Allows for del self.persistent"
|
"Deleter. Allows for del self.persistent"
|
||||||
self.db_persistent = False
|
self.db_persistent = False
|
||||||
self.save()
|
self.save()
|
||||||
persistent = property(persistent_get, persistent_set, persistent_del)
|
persistent = property(__persistent_get, __persistent_set, __persistent_del)
|
||||||
|
|
||||||
# is_active property (wraps db_is_active)
|
# is_active property (wraps db_is_active)
|
||||||
#@property
|
#@property
|
||||||
def is_active_get(self):
|
def __is_active_get(self):
|
||||||
"Getter. Allows for value = self.is_active"
|
"Getter. Allows for value = self.is_active"
|
||||||
return self.db_is_active
|
return self.db_is_active
|
||||||
#@is_active.setter
|
#@is_active.setter
|
||||||
def is_active_set(self, value):
|
def __is_active_set(self, value):
|
||||||
"Setter. Allows for self.is_active = value"
|
"Setter. Allows for self.is_active = value"
|
||||||
self.db_is_active = value
|
self.db_is_active = value
|
||||||
self.save()
|
self.save()
|
||||||
#@is_active.deleter
|
#@is_active.deleter
|
||||||
def is_active_del(self):
|
def __is_active_del(self):
|
||||||
"Deleter. Allows for del self.is_active"
|
"Deleter. Allows for del self.is_active"
|
||||||
self.db_is_active = False
|
self.db_is_active = False
|
||||||
self.save()
|
self.save()
|
||||||
is_active = property(is_active_get, is_active_set, is_active_del)
|
is_active = property(__is_active_get, __is_active_set, __is_active_del)
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,29 @@
|
||||||
This module contains the base Script class that all
|
This module contains the base Script class that all
|
||||||
scripts are inheriting from.
|
scripts are inheriting from.
|
||||||
|
|
||||||
It also defines a few common scripts.
|
It also defines a few common scripts.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from time import time
|
from time import time
|
||||||
from twisted.internet.defer import maybeDeferred
|
from twisted.internet.defer import maybeDeferred
|
||||||
from twisted.internet.task import LoopingCall
|
from twisted.internet.task import LoopingCall
|
||||||
from twisted.internet import task
|
from twisted.internet import task
|
||||||
from src.server.sessionhandler import SESSIONS
|
from src.server.sessionhandler import SESSIONS
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
from src.scripts.models import ScriptDB
|
from src.scripts.models import ScriptDB
|
||||||
from src.comms import channelhandler
|
from src.comms import channelhandler
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
|
|
||||||
|
__all__ = ("Script", "DoNothing", "CheckSessions", "ValidateScripts", "ValidateChannelHandler", "AddCmdSet")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Base script, inherit from Script below instead.
|
# Base script, inherit from Script below instead.
|
||||||
#
|
#
|
||||||
class ScriptClass(TypeClass):
|
class ScriptClass(TypeClass):
|
||||||
"""
|
"""
|
||||||
Base class for scripts. Don't inherit from this, inherit from Script instead.
|
Base class for scripts. Don't inherit from this, inherit from Script instead.
|
||||||
"""
|
"""
|
||||||
# private methods
|
# private methods
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""
|
"""
|
||||||
|
|
@ -32,7 +34,7 @@ class ScriptClass(TypeClass):
|
||||||
try:
|
try:
|
||||||
return other.id == self.id
|
return other.id == self.id
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _start_task(self, start_now=True):
|
def _start_task(self, start_now=True):
|
||||||
"start task runner"
|
"start task runner"
|
||||||
|
|
@ -43,17 +45,17 @@ class ScriptClass(TypeClass):
|
||||||
#print " start with paused time:", self.key, self.ndb._paused_time
|
#print " start with paused time:", self.key, self.ndb._paused_time
|
||||||
self.ndb.twisted_task.start(self.ndb._paused_time, now=False)
|
self.ndb.twisted_task.start(self.ndb._paused_time, now=False)
|
||||||
else:
|
else:
|
||||||
# starting script anew.
|
# starting script anew.
|
||||||
#print "_start_task: self.interval:", self.key, self.dbobj.interval
|
#print "_start_task: self.interval:", self.key, self.dbobj.interval
|
||||||
self.ndb.twisted_task.start(self.dbobj.interval, now=start_now and not self.start_delay)
|
self.ndb.twisted_task.start(self.dbobj.interval, now=start_now and not self.start_delay)
|
||||||
self.ndb.time_last_called = int(time())
|
self.ndb.time_last_called = int(time())
|
||||||
|
|
||||||
def _stop_task(self):
|
def _stop_task(self):
|
||||||
"stop task runner"
|
"stop task runner"
|
||||||
try:
|
try:
|
||||||
#print "stopping twisted task:", id(self.ndb.twisted_task), self.obj
|
#print "stopping twisted task:", id(self.ndb.twisted_task), self.obj
|
||||||
if self.ndb.twisted_task and self.ndb.twisted_task.running:
|
if self.ndb.twisted_task and self.ndb.twisted_task.running:
|
||||||
self.ndb.twisted_task.stop()
|
self.ndb.twisted_task.stop()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
def _step_err_callback(self, e):
|
def _step_err_callback(self, e):
|
||||||
|
|
@ -69,14 +71,14 @@ class ScriptClass(TypeClass):
|
||||||
"step task runner. No try..except needed due to defer wrap."
|
"step task runner. No try..except needed due to defer wrap."
|
||||||
if not self.is_valid():
|
if not self.is_valid():
|
||||||
self.stop()
|
self.stop()
|
||||||
return
|
return
|
||||||
self.at_repeat()
|
self.at_repeat()
|
||||||
repeats = self.dbobj.db_repeats
|
repeats = self.dbobj.db_repeats
|
||||||
if repeats <= 0:
|
if repeats <= 0:
|
||||||
pass # infinite repeat
|
pass # infinite repeat
|
||||||
elif repeats == 1:
|
elif repeats == 1:
|
||||||
self.stop()
|
self.stop()
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.dbobj.db_repeats -= 1
|
self.dbobj.db_repeats -= 1
|
||||||
self.ndb.time_last_called = int(time())
|
self.ndb.time_last_called = int(time())
|
||||||
|
|
@ -84,7 +86,7 @@ class ScriptClass(TypeClass):
|
||||||
|
|
||||||
if self.ndb._paused_time:
|
if self.ndb._paused_time:
|
||||||
# this means we were running an unpaused script, for the time remaining
|
# this means we were running an unpaused script, for the time remaining
|
||||||
# after the pause. Now we start a normal-running timer again.
|
# after the pause. Now we start a normal-running timer again.
|
||||||
#print "switching to normal run:", self.key
|
#print "switching to normal run:", self.key
|
||||||
del self.ndb._paused_time
|
del self.ndb._paused_time
|
||||||
self._stop_task()
|
self._stop_task()
|
||||||
|
|
@ -93,23 +95,23 @@ class ScriptClass(TypeClass):
|
||||||
|
|
||||||
def _step_task(self):
|
def _step_task(self):
|
||||||
"step task"
|
"step task"
|
||||||
try:
|
try:
|
||||||
d = maybeDeferred(self._step_succ_callback)
|
d = maybeDeferred(self._step_succ_callback)
|
||||||
d.addErrback(self._step_err_callback)
|
d.addErrback(self._step_err_callback)
|
||||||
return d
|
return d
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
||||||
|
|
||||||
# Public methods
|
# Public methods
|
||||||
|
|
||||||
def time_until_next_repeat(self):
|
def time_until_next_repeat(self):
|
||||||
"""
|
"""
|
||||||
Returns the time in seconds until the script will be
|
Returns the time in seconds until the script will be
|
||||||
run again. If this is not a stepping script, returns None.
|
run again. If this is not a stepping script, returns None.
|
||||||
This is not used in any way by the script's stepping
|
This is not used in any way by the script's stepping
|
||||||
system; it's only here for the user to be able to
|
system; it's only here for the user to be able to
|
||||||
check in on their scripts and when they will next be run.
|
check in on their scripts and when they will next be run.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if self.ndb._paused_time:
|
if self.ndb._paused_time:
|
||||||
|
|
@ -117,7 +119,7 @@ class ScriptClass(TypeClass):
|
||||||
else:
|
else:
|
||||||
return max(0, (self.ndb.time_last_called + self.dbobj.db_interval) - int(time()))
|
return max(0, (self.ndb.time_last_called + self.dbobj.db_interval) - int(time()))
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def start(self, force_restart=False):
|
def start(self, force_restart=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -125,33 +127,33 @@ class ScriptClass(TypeClass):
|
||||||
persistent scripts, this is usually once every server start)
|
persistent scripts, this is usually once every server start)
|
||||||
|
|
||||||
force_restart - if True, will always restart the script, regardless
|
force_restart - if True, will always restart the script, regardless
|
||||||
of if it has started before.
|
of if it has started before.
|
||||||
|
|
||||||
returns 0 or 1 to indicated the script has been started or not. Used in counting.
|
returns 0 or 1 to indicated the script has been started or not. Used in counting.
|
||||||
"""
|
"""
|
||||||
#print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj),
|
#print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj),
|
||||||
# self.is_active, force_restart)
|
# self.is_active, force_restart)
|
||||||
|
|
||||||
if self.dbobj.is_active and not force_restart:
|
if self.dbobj.is_active and not force_restart:
|
||||||
# script already runs and should not be restarted.
|
# script already runs and should not be restarted.
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
obj = self.obj
|
obj = self.obj
|
||||||
if obj:
|
if obj:
|
||||||
# check so the scripted object is valid and initalized
|
# check so the scripted object is valid and initalized
|
||||||
try:
|
try:
|
||||||
dummy = object.__getattribute__(obj, 'cmdset')
|
dummy = object.__getattribute__(obj, 'cmdset')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# this means the object is not initialized.
|
# this means the object is not initialized.
|
||||||
self.dbobj.is_active = False
|
self.dbobj.is_active = False
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# try to restart a paused script
|
# try to restart a paused script
|
||||||
if self.unpause():
|
if self.unpause():
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# try to start the script from scratch
|
# try to start the script from scratch
|
||||||
try:
|
try:
|
||||||
self.dbobj.is_active = True
|
self.dbobj.is_active = True
|
||||||
self.at_start()
|
self.at_start()
|
||||||
if self.dbobj.db_interval > 0:
|
if self.dbobj.db_interval > 0:
|
||||||
|
|
@ -159,15 +161,15 @@ class ScriptClass(TypeClass):
|
||||||
return 1
|
return 1
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
self.dbobj.is_active = False
|
self.dbobj.is_active = False
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def stop(self, kill=False):
|
def stop(self, kill=False):
|
||||||
"""
|
"""
|
||||||
Called to stop the script from running.
|
Called to stop the script from running.
|
||||||
This also deletes the script.
|
This also deletes the script.
|
||||||
|
|
||||||
kill - don't call finishing hooks.
|
kill - don't call finishing hooks.
|
||||||
"""
|
"""
|
||||||
#print "stopping script %s" % self.key
|
#print "stopping script %s" % self.key
|
||||||
#import pdb
|
#import pdb
|
||||||
|
|
@ -197,29 +199,29 @@ class ScriptClass(TypeClass):
|
||||||
#print "pausing", self.key, self.time_until_next_repeat()
|
#print "pausing", self.key, self.time_until_next_repeat()
|
||||||
dt = self.time_until_next_repeat()
|
dt = self.time_until_next_repeat()
|
||||||
if dt == None:
|
if dt == None:
|
||||||
return
|
return
|
||||||
self.db._paused_time = dt
|
self.db._paused_time = dt
|
||||||
self._stop_task()
|
self._stop_task()
|
||||||
|
|
||||||
def unpause(self):
|
def unpause(self):
|
||||||
"""
|
"""
|
||||||
Restart a paused script. This WILL call at_start().
|
Restart a paused script. This WILL call at_start().
|
||||||
"""
|
"""
|
||||||
#print "unpausing", self.key, self.db._paused_time
|
#print "unpausing", self.key, self.db._paused_time
|
||||||
dt = self.db._paused_time
|
dt = self.db._paused_time
|
||||||
if dt == None:
|
if dt == None:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
self.dbobj.is_active = True
|
self.dbobj.is_active = True
|
||||||
self.at_start()
|
self.at_start()
|
||||||
self.ndb._paused_time = dt
|
self.ndb._paused_time = dt
|
||||||
self._start_task(start_now=False)
|
self._start_task(start_now=False)
|
||||||
del self.db._paused_time
|
del self.db._paused_time
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
self.dbobj.is_active = False
|
self.dbobj.is_active = False
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# hooks
|
# hooks
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
|
|
@ -230,7 +232,7 @@ class ScriptClass(TypeClass):
|
||||||
pass
|
pass
|
||||||
def at_start(self):
|
def at_start(self):
|
||||||
"placeholder."
|
"placeholder."
|
||||||
pass
|
pass
|
||||||
def at_stop(self):
|
def at_stop(self):
|
||||||
"placeholder"
|
"placeholder"
|
||||||
pass
|
pass
|
||||||
|
|
@ -240,7 +242,7 @@ class ScriptClass(TypeClass):
|
||||||
def at_init(self):
|
def at_init(self):
|
||||||
"called when typeclass re-caches. Usually not used for scripts."
|
"called when typeclass re-caches. Usually not used for scripts."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Base Script - inherit from this
|
# Base Script - inherit from this
|
||||||
|
|
@ -255,36 +257,36 @@ class Script(ScriptClass):
|
||||||
def __init__(self, dbobj):
|
def __init__(self, dbobj):
|
||||||
"""
|
"""
|
||||||
This is the base TypeClass for all Scripts. Scripts describe events, timers and states in game,
|
This is the base TypeClass for all Scripts. Scripts describe events, timers and states in game,
|
||||||
they can have a time component or describe a state that changes under certain conditions.
|
they can have a time component or describe a state that changes under certain conditions.
|
||||||
|
|
||||||
Script API:
|
Script API:
|
||||||
|
|
||||||
* Available properties (only available on initiated Typeclass objects)
|
* Available properties (only available on initiated Typeclass objects)
|
||||||
|
|
||||||
key (string) - name of object
|
key (string) - name of object
|
||||||
name (string)- same as key
|
name (string)- same as key
|
||||||
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
|
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
|
||||||
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
||||||
dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class
|
dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class
|
||||||
typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
|
typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
|
||||||
date_created (string) - time stamp of object creation
|
date_created (string) - time stamp of object creation
|
||||||
permissions (list of strings) - list of permission strings
|
permissions (list of strings) - list of permission strings
|
||||||
|
|
||||||
desc (string) - optional description of script, shown in listings
|
desc (string) - optional description of script, shown in listings
|
||||||
obj (Object) - optional object that this script is connected to and acts on (set automatically by obj.scripts.add())
|
obj (Object) - optional object that this script is connected to and acts on (set automatically by obj.scripts.add())
|
||||||
interval (int) - how often script should run, in seconds. <0 turns off ticker
|
interval (int) - how often script should run, in seconds. <=0 turns off ticker
|
||||||
start_delay (bool) - if the script should start repeating right away or wait self.interval seconds
|
start_delay (bool) - if the script should start repeating right away or wait self.interval seconds
|
||||||
repeats (int) - how many times the script should repeat before stopping. 0 means infinite repeats
|
repeats (int) - how many times the script should repeat before stopping. <=0 means infinite repeats
|
||||||
persistent (bool) - if script should survive a server shutdown or not
|
persistent (bool) - if script should survive a server shutdown or not
|
||||||
is_active (bool) - if script is currently running
|
is_active (bool) - if script is currently running
|
||||||
|
|
||||||
* Handlers
|
* Handlers
|
||||||
|
|
||||||
locks - lock-handler: use locks.add() to add new lock strings
|
locks - lock-handler: use locks.add() to add new lock strings
|
||||||
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
|
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
|
||||||
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
|
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
|
||||||
|
|
||||||
* Helper methods
|
* Helper methods
|
||||||
|
|
||||||
start() - start script (this usually happens automatically at creation and obj.script.add() etc)
|
start() - start script (this usually happens automatically at creation and obj.script.add() etc)
|
||||||
stop() - stop script, and delete it
|
stop() - stop script, and delete it
|
||||||
|
|
@ -292,48 +294,48 @@ class Script(ScriptClass):
|
||||||
unpause() - restart a previously paused script. The script will continue as if it was never paused.
|
unpause() - restart a previously paused script. The script will continue as if it was never paused.
|
||||||
time_until_next_repeat() - if a timed script (interval>0), returns time until next tick
|
time_until_next_repeat() - if a timed script (interval>0), returns time until next tick
|
||||||
|
|
||||||
* Hook methods
|
* Hook methods
|
||||||
|
|
||||||
at_script_creation() - called only once, when an object of this
|
at_script_creation() - called only once, when an object of this
|
||||||
class is first created.
|
class is first created.
|
||||||
is_valid() - is called to check if the script is valid to be running
|
is_valid() - is called to check if the script is valid to be running
|
||||||
at the current time. If is_valid() returns False, the running
|
at the current time. If is_valid() returns False, the running
|
||||||
script is stopped and removed from the game. You can use this
|
script is stopped and removed from the game. You can use this
|
||||||
to check state changes (i.e. an script tracking some combat
|
to check state changes (i.e. an script tracking some combat
|
||||||
stats at regular intervals is only valid to run while there is
|
stats at regular intervals is only valid to run while there is
|
||||||
actual combat going on).
|
actual combat going on).
|
||||||
at_start() - Called every time the script is started, which for persistent
|
at_start() - Called every time the script is started, which for persistent
|
||||||
scripts is at least once every server start. Note that this is
|
scripts is at least once every server start. Note that this is
|
||||||
unaffected by self.delay_start, which only delays the first call
|
unaffected by self.delay_start, which only delays the first call
|
||||||
to at_repeat().
|
to at_repeat().
|
||||||
at_repeat() - Called every self.interval seconds. It will be called immediately
|
at_repeat() - Called every self.interval seconds. It will be called immediately
|
||||||
upon launch unless self.delay_start is True, which will delay
|
upon launch unless self.delay_start is True, which will delay
|
||||||
the first call of this method by self.interval seconds. If
|
the first call of this method by self.interval seconds. If
|
||||||
self.interval==0, this method will never be called.
|
self.interval<=0, this method will never be called.
|
||||||
at_stop() - Called as the script object is stopped and is about to be removed from
|
at_stop() - Called as the script object is stopped and is about to be removed from
|
||||||
the game, e.g. because is_valid() returned False.
|
the game, e.g. because is_valid() returned False.
|
||||||
at_server_reload() - Called when server reloads. Can be used to save temporary
|
at_server_reload() - Called when server reloads. Can be used to save temporary
|
||||||
variables you want should survive a reload.
|
variables you want should survive a reload.
|
||||||
at_server_shutdown() - called at a full server shutdown.
|
at_server_shutdown() - called at a full server shutdown.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
super(Script, self).__init__(dbobj)
|
super(Script, self).__init__(dbobj)
|
||||||
|
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"""
|
"""
|
||||||
Only called once, by the create function.
|
Only called once, by the create function.
|
||||||
"""
|
"""
|
||||||
self.key = "<unnamed>"
|
self.key = "<unnamed>"
|
||||||
self.desc = ""
|
self.desc = ""
|
||||||
self.interval = 0 # infinite
|
self.interval = 0 # infinite
|
||||||
self.start_delay = False
|
self.start_delay = False
|
||||||
self.repeats = 0 # infinite
|
self.repeats = 0 # infinite
|
||||||
self.persistent = False
|
self.persistent = False
|
||||||
|
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
"""
|
"""
|
||||||
Is called to check if the script is valid to run at this time.
|
Is called to check if the script is valid to run at this time.
|
||||||
Should return a boolean. The method is assumed to collect all needed
|
Should return a boolean. The method is assumed to collect all needed
|
||||||
information from its related self.obj.
|
information from its related self.obj.
|
||||||
"""
|
"""
|
||||||
|
|
@ -342,7 +344,7 @@ class Script(ScriptClass):
|
||||||
def at_start(self):
|
def at_start(self):
|
||||||
"""
|
"""
|
||||||
Called whenever the script is started, which for persistent
|
Called whenever the script is started, which for persistent
|
||||||
scripts is at least once every server start. It will also be called
|
scripts is at least once every server start. It will also be called
|
||||||
when starting again after a pause (such as after a server reload)
|
when starting again after a pause (such as after a server reload)
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
@ -350,10 +352,10 @@ class Script(ScriptClass):
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"""
|
"""
|
||||||
Called repeatedly if this Script is set to repeat
|
Called repeatedly if this Script is set to repeat
|
||||||
regularly.
|
regularly.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_stop(self):
|
def at_stop(self):
|
||||||
"""
|
"""
|
||||||
Called whenever when it's time for this script to stop
|
Called whenever when it's time for this script to stop
|
||||||
|
|
@ -363,38 +365,38 @@ class Script(ScriptClass):
|
||||||
|
|
||||||
def at_server_reload(self):
|
def at_server_reload(self):
|
||||||
"""
|
"""
|
||||||
This hook is called whenever the server is shutting down for restart/reboot.
|
This hook is called whenever the server is shutting down for restart/reboot.
|
||||||
If you want to, for example, save non-persistent properties across a restart,
|
If you want to, for example, save non-persistent properties across a restart,
|
||||||
this is the place to do it.
|
this is the place to do it.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_server_shutdown(self):
|
def at_server_shutdown(self):
|
||||||
"""
|
"""
|
||||||
This hook is called whenever the server is shutting down fully (i.e. not for
|
This hook is called whenever the server is shutting down fully (i.e. not for
|
||||||
a restart).
|
a restart).
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Some useful default Script types used by Evennia.
|
# Some useful default Script types used by Evennia.
|
||||||
|
|
||||||
class DoNothing(Script):
|
class DoNothing(Script):
|
||||||
"An script that does nothing. Used as default fallback."
|
"An script that does nothing. Used as default fallback."
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"Setup the script"
|
"Setup the script"
|
||||||
self.key = "sys_do_nothing"
|
self.key = "sys_do_nothing"
|
||||||
self.desc = "This is a placeholder script."
|
self.desc = "This is a placeholder script."
|
||||||
|
|
||||||
class CheckSessions(Script):
|
class CheckSessions(Script):
|
||||||
"Check sessions regularly."
|
"Check sessions regularly."
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"Setup the script"
|
"Setup the script"
|
||||||
self.key = "sys_session_check"
|
self.key = "sys_session_check"
|
||||||
self.desc = "Checks sessions so they are live."
|
self.desc = "Checks sessions so they are live."
|
||||||
self.interval = 60 # repeat every 60 seconds
|
self.interval = 60 # repeat every 60 seconds
|
||||||
self.persistent = True
|
self.persistent = True
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"called every 60 seconds"
|
"called every 60 seconds"
|
||||||
|
|
@ -403,7 +405,7 @@ class CheckSessions(Script):
|
||||||
SESSIONS.validate_sessions()
|
SESSIONS.validate_sessions()
|
||||||
|
|
||||||
class ValidateScripts(Script):
|
class ValidateScripts(Script):
|
||||||
"Check script validation regularly"
|
"Check script validation regularly"
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"Setup the script"
|
"Setup the script"
|
||||||
self.key = "sys_scripts_validate"
|
self.key = "sys_scripts_validate"
|
||||||
|
|
@ -412,31 +414,31 @@ class ValidateScripts(Script):
|
||||||
self.persistent = True
|
self.persistent = True
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"called every hour"
|
"called every hour"
|
||||||
#print "ValidateScripts run."
|
#print "ValidateScripts run."
|
||||||
ScriptDB.objects.validate()
|
ScriptDB.objects.validate()
|
||||||
|
|
||||||
class ValidateChannelHandler(Script):
|
class ValidateChannelHandler(Script):
|
||||||
"Update the channelhandler to make sure it's in sync."
|
"Update the channelhandler to make sure it's in sync."
|
||||||
|
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"Setup the script"
|
"Setup the script"
|
||||||
self.key = "sys_channels_validate"
|
self.key = "sys_channels_validate"
|
||||||
self.desc = "Updates the channel handler"
|
self.desc = "Updates the channel handler"
|
||||||
self.interval = 3700 # validate a little later than ValidateScripts
|
self.interval = 3700 # validate a little later than ValidateScripts
|
||||||
self.persistent = True
|
self.persistent = True
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
"called every hour+"
|
"called every hour+"
|
||||||
#print "ValidateChannelHandler run."
|
#print "ValidateChannelHandler run."
|
||||||
channelhandler.CHANNELHANDLER.update()
|
channelhandler.CHANNELHANDLER.update()
|
||||||
|
|
||||||
class AddCmdSet(Script):
|
class AddCmdSet(Script):
|
||||||
"""
|
"""
|
||||||
This script permanently assigns a command set
|
This script permanently assigns a command set
|
||||||
to an object whenever it is started. This is not
|
to an object whenever it is started. This is not
|
||||||
used by the core system anymore, it's here mostly
|
used by the core system anymore, it's here mostly
|
||||||
as an example.
|
as an example.
|
||||||
"""
|
"""
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"Setup the script"
|
"Setup the script"
|
||||||
|
|
@ -444,12 +446,12 @@ class AddCmdSet(Script):
|
||||||
self.key = "add_cmdset"
|
self.key = "add_cmdset"
|
||||||
if not self.desc:
|
if not self.desc:
|
||||||
self.desc = "Adds a cmdset to an object."
|
self.desc = "Adds a cmdset to an object."
|
||||||
self.persistent = True
|
self.persistent = True
|
||||||
|
|
||||||
# this needs to be assigned to upon creation.
|
# this needs to be assigned to upon creation.
|
||||||
# It should be a string pointing to the right
|
# It should be a string pointing to the right
|
||||||
# cmdset module and cmdset class name, e.g.
|
# cmdset module and cmdset class name, e.g.
|
||||||
# 'examples.cmdset_redbutton.RedButtonCmdSet'
|
# 'examples.cmdset_redbutton.RedButtonCmdSet'
|
||||||
# self.db.cmdset = <cmdset_path>
|
# self.db.cmdset = <cmdset_path>
|
||||||
# self.db.add_default = <bool>
|
# self.db.add_default = <bool>
|
||||||
|
|
||||||
|
|
@ -461,12 +463,12 @@ class AddCmdSet(Script):
|
||||||
self.obj.cmdset.add_default(cmdset)
|
self.obj.cmdset.add_default(cmdset)
|
||||||
else:
|
else:
|
||||||
self.obj.cmdset.add(cmdset)
|
self.obj.cmdset.add(cmdset)
|
||||||
|
|
||||||
def at_stop(self):
|
def at_stop(self):
|
||||||
"""
|
"""
|
||||||
This removes the cmdset when the script stops
|
This removes the cmdset when the script stops
|
||||||
"""
|
"""
|
||||||
cmdset = self.db.cmdset
|
cmdset = self.db.cmdset
|
||||||
if cmdset:
|
if cmdset:
|
||||||
if self.db.add_default:
|
if self.db.add_default:
|
||||||
self.obj.cmdset.delete_default()
|
self.obj.cmdset.delete_default()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from functools import update_wrapper
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from src.utils import idmapper
|
from src.utils import idmapper
|
||||||
from src.utils.utils import make_iter
|
from src.utils.utils import make_iter
|
||||||
#from src.typeclasses import idmap
|
__all__ = ("AttributeManager", "TypedObjectManager")
|
||||||
|
|
||||||
# Managers
|
# Managers
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ from src.locks.lockhandler import LockHandler
|
||||||
from src.utils import logger, utils
|
from src.utils import logger, utils
|
||||||
from src.utils.utils import make_iter, is_iter, has_parent, to_unicode, to_str
|
from src.utils.utils import make_iter, is_iter, has_parent, to_unicode, to_str
|
||||||
|
|
||||||
|
__all__ = ("Attribute", "TypeNick", "TypedObject")
|
||||||
|
|
||||||
_PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
_PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||||
|
|
||||||
_CTYPEGET = ContentType.objects.get
|
_CTYPEGET = ContentType.objects.get
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ used by the typesystem or django itself.
|
||||||
from src.utils.logger import log_trace, log_errmsg
|
from src.utils.logger import log_trace, log_errmsg
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
__all__ = ("TypeClass",)
|
||||||
|
|
||||||
# these are called so many times it's worth to avoid lookup calls
|
# these are called so many times it's worth to avoid lookup calls
|
||||||
_GA = object.__getattribute__
|
_GA = object.__getattribute__
|
||||||
_SA = object.__setattr__
|
_SA = object.__setattr__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue