I18n string cleanup and refactoring
This commit is contained in:
parent
59dd0b007a
commit
7ff8cbb341
62 changed files with 890 additions and 738 deletions
|
|
@ -10,7 +10,6 @@ which is a non-db version of Attributes.
|
|||
"""
|
||||
import re
|
||||
import fnmatch
|
||||
import weakref
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
|
@ -117,6 +116,7 @@ class IAttribute:
|
|||
class InMemoryAttribute(IAttribute):
|
||||
"""
|
||||
This Attribute is used purely for NAttributes/NAttributeHandler. It has no database backend.
|
||||
|
||||
"""
|
||||
|
||||
# Primary Key has no meaning for an InMemoryAttribute. This merely serves to satisfy other code.
|
||||
|
|
@ -126,11 +126,12 @@ class InMemoryAttribute(IAttribute):
|
|||
Create an Attribute that exists only in Memory.
|
||||
|
||||
Args:
|
||||
pk (int): This is a fake 'primary key' / id-field. It doesn't actually have to be unique, but is fed an
|
||||
incrementing number from the InMemoryBackend by default. This is needed only so Attributes can be
|
||||
sorted. Some parts of the API also see the lack of a .pk field as a sign that the Attribute was
|
||||
deleted.
|
||||
pk (int): This is a fake 'primary key' / id-field. It doesn't actually have to be
|
||||
unique, but is fed an incrementing number from the InMemoryBackend by default. This
|
||||
is needed only so Attributes can be sorted. Some parts of the API also see the lack
|
||||
of a .pk field as a sign that the Attribute was deleted.
|
||||
**kwargs: Other keyword arguments are used to construct the actual Attribute.
|
||||
|
||||
"""
|
||||
self.id = pk
|
||||
self.pk = pk
|
||||
|
|
@ -245,8 +246,8 @@ class Attribute(IAttribute, SharedMemoryModel):
|
|||
lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
|
||||
|
||||
# value property (wraps db_value)
|
||||
# @property
|
||||
def __value_get(self):
|
||||
@property
|
||||
def value(self):
|
||||
"""
|
||||
Getter. Allows for `value = self.value`.
|
||||
We cannot cache here since it makes certain cases (such
|
||||
|
|
@ -255,8 +256,8 @@ class Attribute(IAttribute, SharedMemoryModel):
|
|||
"""
|
||||
return from_pickle(self.db_value, db_obj=self)
|
||||
|
||||
# @value.setter
|
||||
def __value_set(self, new_value):
|
||||
@value.setter
|
||||
def value(self, new_value):
|
||||
"""
|
||||
Setter. Allows for self.value = value. We cannot cache here,
|
||||
see self.__value_get.
|
||||
|
|
@ -264,14 +265,11 @@ class Attribute(IAttribute, SharedMemoryModel):
|
|||
self.db_value = to_pickle(new_value)
|
||||
self.save(update_fields=["db_value"])
|
||||
|
||||
# @value.deleter
|
||||
def __value_del(self):
|
||||
@value.deleter
|
||||
def value(self):
|
||||
"""Deleter. Allows for del attr.value. This removes the entire attribute."""
|
||||
self.delete()
|
||||
|
||||
value = property(__value_get, __value_set, __value_del)
|
||||
|
||||
|
||||
#
|
||||
# Handlers making use of the Attribute model
|
||||
#
|
||||
|
|
@ -348,7 +346,7 @@ class IAttributeBackend:
|
|||
|
||||
def _get_cache_key(self, key, category):
|
||||
"""
|
||||
|
||||
Fetch cache key.
|
||||
|
||||
Args:
|
||||
key (str): The key of the Attribute being searched for.
|
||||
|
|
@ -529,7 +527,8 @@ class IAttributeBackend:
|
|||
|
||||
def create_attribute(self, key, category, lockstring, value, strvalue=False, cache=True):
|
||||
"""
|
||||
Creates Attribute (using the class specified for the backend), (optionally) caches it, and returns it.
|
||||
Creates Attribute (using the class specified for the backend), (optionally) caches it, and
|
||||
returns it.
|
||||
|
||||
This MUST actively save the Attribute to whatever database backend is used, AND
|
||||
call self.set_cache(key, category, new_attrobj)
|
||||
|
|
@ -714,7 +713,8 @@ class IAttributeBackend:
|
|||
]
|
||||
)
|
||||
else:
|
||||
# have to cast the results to a list or we'll get a RuntimeError for removing from the dict we're iterating
|
||||
# have to cast the results to a list or we'll get a RuntimeError for removing from the
|
||||
# dict we're iterating
|
||||
self.do_batch_delete(list(attrs))
|
||||
self.reset_cache()
|
||||
|
||||
|
|
@ -735,10 +735,10 @@ class IAttributeBackend:
|
|||
|
||||
class InMemoryAttributeBackend(IAttributeBackend):
|
||||
"""
|
||||
This Backend for Attributes stores NOTHING in the database. Everything is kept in memory, and normally lost
|
||||
on a crash, reload, shared memory flush, etc. It generates IDs for the Attributes it manages, but these are
|
||||
of little importance beyond sorting and satisfying the caching logic to know an Attribute hasn't been
|
||||
deleted out from under the cache's nose.
|
||||
This Backend for Attributes stores NOTHING in the database. Everything is kept in memory, and
|
||||
normally lost on a crash, reload, shared memory flush, etc. It generates IDs for the Attributes
|
||||
it manages, but these are of little importance beyond sorting and satisfying the caching logic
|
||||
to know an Attribute hasn't been deleted out from under the cache's nose.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -810,7 +810,8 @@ class InMemoryAttributeBackend(IAttributeBackend):
|
|||
|
||||
def do_delete_attribute(self, attr):
|
||||
"""
|
||||
Removes the Attribute from local storage. Once it's out of the cache, garbage collection will handle the rest.
|
||||
Removes the Attribute from local storage. Once it's out of the cache, garbage collection
|
||||
will handle the rest.
|
||||
|
||||
Args:
|
||||
attr (IAttribute): The attribute to delete.
|
||||
|
|
@ -929,8 +930,9 @@ class AttributeHandler:
|
|||
Setup the AttributeHandler.
|
||||
|
||||
Args:
|
||||
obj (TypedObject): An Account, Object, Channel, ServerSession (not technically a typed object), etc.
|
||||
backend_class (IAttributeBackend class): The class of the backend to use.
|
||||
obj (TypedObject): An Account, Object, Channel, ServerSession (not technically a typed
|
||||
object), etc. backend_class (IAttributeBackend class): The class of the backend to
|
||||
use.
|
||||
"""
|
||||
self.obj = obj
|
||||
self.backend = backend_class(self, self._attrtype)
|
||||
|
|
@ -1263,6 +1265,7 @@ class DbHolder:
|
|||
all = property(get_all)
|
||||
|
||||
|
||||
#
|
||||
# Nick templating
|
||||
#
|
||||
|
||||
|
|
@ -1282,7 +1285,7 @@ This happens in two steps:
|
|||
|
||||
This will be converted to the following regex:
|
||||
|
||||
\@desc (?P<1>\w+) (?P<2>\w+) $(?P<3>\w+)
|
||||
\@desc (?P<1>\w+) (?P<2>\w+) $(?P<3>\w+)
|
||||
|
||||
Supported template markers (through fnmatch)
|
||||
* matches anything (non-greedy) -> .*?
|
||||
|
|
@ -1345,7 +1348,7 @@ def initialize_nick_templates(pattern, replacement, pattern_is_regex=False):
|
|||
# groups. we need to split out any | - separated parts so we can
|
||||
# attach the line-break/ending extras all regexes require.
|
||||
pattern_regex_string = r"|".join(
|
||||
or_part + r"(?:[\n\r]*?)\Z"
|
||||
or_part + r"(?:[\n\r]*?)\Z"
|
||||
for or_part in _RE_OR.split(pattern))
|
||||
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -595,13 +595,21 @@ class TypeclassManager(TypedObjectManager):
|
|||
Search by supplying a string with optional extra search criteria to aid the query.
|
||||
|
||||
Args:
|
||||
query (str): A search criteria that accepts extra search criteria on the
|
||||
query (str): A search criteria that accepts extra search criteria on the following
|
||||
forms:
|
||||
|
||||
[key|alias|#dbref...]
|
||||
[tag==<tagstr>[:category]...]
|
||||
[attr==<key>:<value>:category...]
|
||||
|
||||
All three can be combined in the same query, separated by spaces.
|
||||
|
||||
following forms: [key|alias|#dbref...] [tag==<tagstr>[:category]...] [attr==<key>:<value>:category...]
|
||||
" != " != "
|
||||
Returns:
|
||||
matches (queryset): A queryset result matching all queries exactly. If wanting to use spaces or
|
||||
==, != in tags or attributes, enclose them in quotes.
|
||||
matches (queryset): A queryset result matching all queries exactly. If wanting to use
|
||||
spaces or ==, != in tags or attributes, enclose them in quotes.
|
||||
|
||||
Example:
|
||||
house = smart_search("key=foo alias=bar tag=house:building tag=magic attr=color:red")
|
||||
|
||||
Note:
|
||||
The flexibility of this method is limited by the input line format. Tag/attribute
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ _SA = object.__setattr__
|
|||
def call_at_first_save(sender, instance, created, **kwargs):
|
||||
"""
|
||||
Receives a signal just after the object is saved.
|
||||
|
||||
"""
|
||||
if created:
|
||||
instance.at_first_save()
|
||||
|
|
@ -77,6 +78,7 @@ def call_at_first_save(sender, instance, created, **kwargs):
|
|||
def remove_attributes_on_delete(sender, instance, **kwargs):
|
||||
"""
|
||||
Wipe object's Attributes when it's deleted
|
||||
|
||||
"""
|
||||
instance.db_attributes.all().delete()
|
||||
|
||||
|
|
@ -98,6 +100,7 @@ class TypeclassBase(SharedMemoryModelBase):
|
|||
Metaclass which should be set for the root of model proxies
|
||||
that don't define any new fields, like Object, Script etc. This
|
||||
is the basis for the typeclassing system.
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, name, bases, attrs):
|
||||
|
|
@ -208,7 +211,8 @@ class TypedObject(SharedMemoryModel):
|
|||
"typeclass",
|
||||
max_length=255,
|
||||
null=True,
|
||||
help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.",
|
||||
help_text="this defines what 'type' of entity this is. This variable holds "
|
||||
"a Python path to a module with a valid Evennia Typeclass.",
|
||||
db_index=True,
|
||||
)
|
||||
# Creation date. This is not changed once the object is created.
|
||||
|
|
@ -217,16 +221,20 @@ class TypedObject(SharedMemoryModel):
|
|||
db_lock_storage = models.TextField(
|
||||
"locks",
|
||||
blank=True,
|
||||
help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.",
|
||||
help_text="locks limit access to an entity. A lock is defined as a 'lock string' "
|
||||
"on the form 'type:lockfunctions', defining what functionality is locked and "
|
||||
"how to determine access. Not defining a lock means no access is granted.",
|
||||
)
|
||||
# many2many relationships
|
||||
db_attributes = models.ManyToManyField(
|
||||
Attribute,
|
||||
help_text="attributes on this object. An attribute can hold any pickle-able python object (see docs for special cases).",
|
||||
help_text="attributes on this object. An attribute can hold any pickle-able "
|
||||
"python object (see docs for special cases).",
|
||||
)
|
||||
db_tags = models.ManyToManyField(
|
||||
Tag,
|
||||
help_text="tags on this object. Tags are simple string markers to identify, group and alias objects.",
|
||||
help_text="tags on this object. Tags are simple string markers to identify, "
|
||||
"group and alias objects.",
|
||||
)
|
||||
|
||||
# Database manager
|
||||
|
|
@ -701,8 +709,8 @@ class TypedObject(SharedMemoryModel):
|
|||
# Attribute storage
|
||||
#
|
||||
|
||||
# @property db
|
||||
def __db_get(self):
|
||||
@property
|
||||
def db(self):
|
||||
"""
|
||||
Attribute handler wrapper. Allows for the syntax
|
||||
|
||||
|
|
@ -725,26 +733,24 @@ class TypedObject(SharedMemoryModel):
|
|||
self._db_holder = DbHolder(self, "attributes")
|
||||
return self._db_holder
|
||||
|
||||
# @db.setter
|
||||
def __db_set(self, value):
|
||||
@db.setter
|
||||
def db(self, value):
|
||||
"Stop accidentally replacing the db object"
|
||||
string = "Cannot assign directly to db object! "
|
||||
string += "Use db.attr=value instead."
|
||||
raise Exception(string)
|
||||
|
||||
# @db.deleter
|
||||
def __db_del(self):
|
||||
@db.deleter
|
||||
def db(self):
|
||||
"Stop accidental deletion."
|
||||
raise Exception("Cannot delete the db object!")
|
||||
|
||||
db = property(__db_get, __db_set, __db_del)
|
||||
|
||||
#
|
||||
# Non-persistent (ndb) storage
|
||||
#
|
||||
|
||||
# @property ndb
|
||||
def __ndb_get(self):
|
||||
@property
|
||||
def ndb(self):
|
||||
"""
|
||||
A non-attr_obj store (ndb: NonDataBase). Everything stored
|
||||
to this is guaranteed to be cleared when a server is shutdown.
|
||||
|
|
@ -757,20 +763,18 @@ class TypedObject(SharedMemoryModel):
|
|||
self._ndb_holder = DbHolder(self, "nattrhandler", manager_name="nattributes")
|
||||
return self._ndb_holder
|
||||
|
||||
# @db.setter
|
||||
def __ndb_set(self, value):
|
||||
@ndb.setter
|
||||
def ndb(self, value):
|
||||
"Stop accidentally replacing the ndb object"
|
||||
string = "Cannot assign directly to ndb object! "
|
||||
string += "Use ndb.attr=value instead."
|
||||
raise Exception(string)
|
||||
|
||||
# @db.deleter
|
||||
def __ndb_del(self):
|
||||
@ndb.deleter
|
||||
def ndb(self):
|
||||
"Stop accidental deletion."
|
||||
raise Exception("Cannot delete the ndb object!")
|
||||
|
||||
ndb = property(__ndb_get, __ndb_set, __ndb_del)
|
||||
|
||||
def get_display_name(self, looker, **kwargs):
|
||||
"""
|
||||
Displays the name of the object in a viewer-aware manner.
|
||||
|
|
@ -879,7 +883,7 @@ class TypedObject(SharedMemoryModel):
|
|||
"""
|
||||
try:
|
||||
return reverse("%s-create" % slugify(cls._meta.verbose_name))
|
||||
except:
|
||||
except Exception:
|
||||
return "#"
|
||||
|
||||
def web_get_detail_url(self):
|
||||
|
|
@ -919,7 +923,7 @@ class TypedObject(SharedMemoryModel):
|
|||
"%s-detail" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
return "#"
|
||||
|
||||
def web_get_puppet_url(self):
|
||||
|
|
@ -931,19 +935,17 @@ class TypedObject(SharedMemoryModel):
|
|||
str: URI path to object puppet page, if defined.
|
||||
|
||||
Examples:
|
||||
::
|
||||
|
||||
```python
|
||||
Oscar (Character) = '/characters/oscar/1/puppet/'
|
||||
```
|
||||
|
||||
For this to work, the developer must have defined a named view somewhere
|
||||
in urls.py that follows the format 'modelname-action', so in this case
|
||||
a named view of 'character-puppet' would be referenced by this method.
|
||||
::
|
||||
|
||||
```python
|
||||
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/puppet/$',
|
||||
CharPuppetView.as_view(), name='character-puppet')
|
||||
```
|
||||
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/puppet/$',
|
||||
CharPuppetView.as_view(), name='character-puppet')
|
||||
|
||||
If no View has been created and defined in urls.py, returns an
|
||||
HTML anchor.
|
||||
|
|
@ -959,7 +961,7 @@ class TypedObject(SharedMemoryModel):
|
|||
"%s-puppet" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
return "#"
|
||||
|
||||
def web_get_update_url(self):
|
||||
|
|
@ -979,11 +981,10 @@ class TypedObject(SharedMemoryModel):
|
|||
For this to work, the developer must have defined a named view somewhere
|
||||
in urls.py that follows the format 'modelname-action', so in this case
|
||||
a named view of 'character-update' would be referenced by this method.
|
||||
::
|
||||
|
||||
```python
|
||||
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/change/$',
|
||||
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/change/$',
|
||||
CharUpdateView.as_view(), name='character-update')
|
||||
```
|
||||
|
||||
If no View has been created and defined in urls.py, returns an
|
||||
HTML anchor.
|
||||
|
|
@ -999,7 +1000,7 @@ class TypedObject(SharedMemoryModel):
|
|||
"%s-update" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
return "#"
|
||||
|
||||
def web_get_delete_url(self):
|
||||
|
|
@ -1019,11 +1020,10 @@ class TypedObject(SharedMemoryModel):
|
|||
somewhere in urls.py that follows the format 'modelname-action', so
|
||||
in this case a named view of 'character-detail' would be referenced
|
||||
by this method.
|
||||
::
|
||||
|
||||
```python
|
||||
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$',
|
||||
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$',
|
||||
CharDeleteView.as_view(), name='character-delete')
|
||||
```
|
||||
|
||||
If no View has been created and defined in urls.py, returns an HTML
|
||||
anchor.
|
||||
|
|
@ -1039,7 +1039,7 @@ class TypedObject(SharedMemoryModel):
|
|||
"%s-delete" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
return "#"
|
||||
|
||||
# Used by Django Sites/Admin
|
||||
|
|
|
|||
|
|
@ -125,7 +125,10 @@ class TagHandler(object):
|
|||
self._cache_complete = False
|
||||
|
||||
def _query_all(self):
|
||||
"Get all tags for this objects"
|
||||
"""
|
||||
Get all tags for this object.
|
||||
|
||||
"""
|
||||
query = {
|
||||
"%s__id" % self._model: self._objid,
|
||||
"tag__db_model": self._model,
|
||||
|
|
@ -137,7 +140,10 @@ class TagHandler(object):
|
|||
]
|
||||
|
||||
def _fullcache(self):
|
||||
"Cache all tags of this object"
|
||||
"""
|
||||
Cache all tags of this object.
|
||||
|
||||
"""
|
||||
if not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||
return
|
||||
tags = self._query_all()
|
||||
|
|
@ -277,6 +283,7 @@ class TagHandler(object):
|
|||
def reset_cache(self):
|
||||
"""
|
||||
Reset the cache from the outside.
|
||||
|
||||
"""
|
||||
self._cache_complete = False
|
||||
self._cache = {}
|
||||
|
|
@ -483,8 +490,9 @@ class TagHandler(object):
|
|||
Batch-add tags from a list of tuples.
|
||||
|
||||
Args:
|
||||
*args (tuple or str): Each argument should be a `tagstr` keys or tuple `(keystr, category)` or
|
||||
`(keystr, category, data)`. It's possible to mix input types.
|
||||
*args (tuple or str): Each argument should be a `tagstr` keys or tuple
|
||||
`(keystr, category)` or `(keystr, category, data)`. It's possible to mix input
|
||||
types.
|
||||
|
||||
Notes:
|
||||
This will generate a mimimal number of self.add calls,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue