restructuring for poetry-slam
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import enum
|
||||
|
||||
import nanoid
|
||||
from nanoid_dictionary import human_alphabet
|
||||
from pyramid_sqlalchemy import BaseObject
|
||||
from slugify import slugify
|
||||
from sqlalchemy import Column, String
|
||||
|
||||
|
||||
def genslug():
|
||||
return nanoid.generate(human_alphabet[2:], 5)
|
||||
|
||||
|
||||
class SlugMixin:
|
||||
slug = Column(String, index=True, unique=True, default=genslug)
|
||||
|
||||
@property
|
||||
def uri(self):
|
||||
return "-".join([self.slug, slugify(self.name.title().replace(" ", ""), ok="", only_ascii=True, lower=False)])
|
||||
|
||||
|
||||
class IterableMixin:
|
||||
"""
|
||||
Allows for iterating over Model objects' column names and values
|
||||
"""
|
||||
|
||||
def __iter__(self):
|
||||
values = vars(self)
|
||||
for attr in self.__mapper__.columns.keys():
|
||||
if attr in values:
|
||||
yield attr, values[attr]
|
||||
for relname in self.__mapper__.relationships.keys():
|
||||
relvals = []
|
||||
reliter = self.__getattribute__(relname)
|
||||
if not reliter:
|
||||
yield relname, relvals
|
||||
continue
|
||||
for rel in reliter:
|
||||
try:
|
||||
relvals.append({k: v for k, v in vars(rel).items() if not k.startswith("_")})
|
||||
except TypeError:
|
||||
relvals.append(rel)
|
||||
yield relname, relvals
|
||||
|
||||
def __json__(self, request):
|
||||
serialized = dict()
|
||||
for key, value in self:
|
||||
try:
|
||||
serialized[key] = getattr(self.value, "__json__")(request)
|
||||
except AttributeError:
|
||||
serialized[key] = value
|
||||
return serialized
|
||||
|
||||
def __repr__(self):
|
||||
return str(dict(self))
|
||||
|
||||
|
||||
def multivalue_string_factory(name, column=Column(String), separator=";"):
|
||||
"""
|
||||
Generate a mixin class that adds a string column with getters and setters
|
||||
that convert list values to strings and back again. Equivalent to:
|
||||
|
||||
class MultiValueString:
|
||||
_name = column
|
||||
|
||||
@property
|
||||
def name_property(self):
|
||||
return self._name.split(';')
|
||||
|
||||
@name.setter
|
||||
def name(self, val):
|
||||
return ';'.join(val)
|
||||
"""
|
||||
attr = f"_{name}"
|
||||
prop = property(lambda self: getattr(self, attr).split(separator))
|
||||
setter = prop.setter(lambda self, val: setattr(self, attr, separator.join(val)))
|
||||
return type(
|
||||
"MultiValueString",
|
||||
(object,),
|
||||
{
|
||||
attr: column,
|
||||
f"{name}_property": prop,
|
||||
name: setter,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class EnumField(enum.Enum):
|
||||
"""
|
||||
A serializable enum.
|
||||
"""
|
||||
|
||||
def __json__(self, request):
|
||||
return self.value
|
||||
|
||||
|
||||
SavingThrowsMixin = multivalue_string_factory("saving_throws")
|
||||
SkillsMixin = multivalue_string_factory("skills")
|
||||
|
||||
STATS = ["STR", "DEX", "CON", "INT", "WIS", "CHA"]
|
||||
CREATURE_TYPES = [
|
||||
"aberation",
|
||||
"beast",
|
||||
"celestial",
|
||||
"construct",
|
||||
"dragon",
|
||||
"elemental",
|
||||
"fey",
|
||||
"fiend",
|
||||
"Giant",
|
||||
"humanoid",
|
||||
"monstrosity",
|
||||
"ooze",
|
||||
"plant",
|
||||
"undead",
|
||||
]
|
||||
CreatureTypesEnum = EnumField("CreatureTypesEnum", ((k, k) for k in CREATURE_TYPES))
|
||||
StatsEnum = EnumField("StatsEnum", ((k, k) for k in STATS))
|
||||
|
||||
# class Table(*Bases):
|
||||
Bases = [BaseObject, IterableMixin, SlugMixin]
|
||||
Reference in New Issue
Block a user