I18n string cleanup and refactoring

This commit is contained in:
Griatch 2021-05-26 21:55:05 +02:00
parent 59dd0b007a
commit 7ff8cbb341
62 changed files with 890 additions and 738 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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,