From d3c667a654a27e8023c341fc3ec0e452599f0318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sat, 25 Feb 2017 23:24:30 +0100 Subject: More prefix work --- archivist/cli.py | 9 +++---- archivist/model.py | 27 +++++++++++++++++--- archivist/prefixes.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 archivist/prefixes.py diff --git a/archivist/cli.py b/archivist/cli.py index 4316705..f73a7a4 100644 --- a/archivist/cli.py +++ b/archivist/cli.py @@ -19,14 +19,11 @@ def db(): @db.command() def init(): """Initialize the database, if not done already.""" - from .model import create_tables, Prefix, db + from .model import create_tables, db + from .prefixes import register_prefixes create_tables() with db.atomic(): - Prefix.create(name='year', builtin=True) - Prefix.create(name='month', builtin=True) - Prefix.create(name='day', builtin=True) - Prefix.create(name='date', builtin=True, pseudo=True) - Prefix.create(name='direction', builtin=True, pseudo=True) + register_prefixes() @db.command() @click.confirmation_option(prompt="Are you sure you want to drop the database?") diff --git a/archivist/model.py b/archivist/model.py index b281edc..b8a1604 100644 --- a/archivist/model.py +++ b/archivist/model.py @@ -1,7 +1,10 @@ from peewee import * from playhouse.fields import CompressedField +from playhouse.hybrid import * import datetime + +from .prefixes import query_pseudo_prefix db = SqliteDatabase('test.db', pragmas=[('foreign_keys', 'ON')]) @@ -26,21 +29,39 @@ class BaseModel(Model): @table class Document(BaseModel): content = CompressedField() - created = DateTimeField(default=datetime.datetime.now) + created = DateField(default=datetime.datetime.now) description = CharField(null=True) direction = BooleanField(null=True) original_path = CharField(null=True) + inserted = DateTimeField(default=datetime.datetime.now) + + @classmethod + def matches(cls, prefix, value): + return query_pseudo_prefix(prefix, value) or Document.id << ( + DocumentTag.select(DocumentTag.document) + .join(Tag, on=Tag.matches(prefix, value))) @table class Prefix(BaseModel): - name = CharField(null=True, unique=True) + name = CharField(primary_key = True) builtin = BooleanField(default = False) pseudo = BooleanField(default = False) + description = CharField(null=True) @table class Tag(BaseModel): name = CharField() - prefix = ForeignKeyField(Prefix, null=True, related_name = 'tag') + prefix = ForeignKeyField(Prefix, null=True, related_name = 'tag', db_column = 'prefix') + description = CharField(null=True) + + @hybrid_method + def matches(self, prefix, name): + return (self.prefix == prefix) & (self.name == name) + + class Meta: + indexes = [ + (('name', 'prefix'), True) + ] @table class DocumentTag(BaseModel): diff --git a/archivist/prefixes.py b/archivist/prefixes.py new file mode 100644 index 0000000..4e73ca7 --- /dev/null +++ b/archivist/prefixes.py @@ -0,0 +1,69 @@ +from peewee import Field + +prefixes = {} +registered = False + +def register_prefixes(): + global registered + if registered: return + + if not prefixes: + _create_prefixes() + + for prefix in prefixes.values(): + prefix.get_or_create() + + registered = True + +def _create_prefixes(): + from .model import Document + + FieldPseudoPrefix('direction', 'In- or outgoing', Document.direction) + FieldPseudoPrefix('date', 'Date of creation', Document.created) + + for part in ('day', 'month', 'year'): + FieldPartPseudoPrefix(part, part.capitalize() + ' of creation', Document.created, part) + +def query_pseudo_prefix(prefix, value): + register_prefixes() + + if prefix in prefixes: + return prefixes[prefix].as_query(value) + return None + +class PseudoPrefix: + def __init__(self, name, description, accessor): + self.name = name + self.accessor = accessor + self.description = description + prefixes[name] = self + + def get_or_create(self): + from .model import Prefix + return Prefix.get_or_create(name = self.name, defaults={ + 'description' : self.description, + 'builtin' : True, + 'pseudo' : True}) + + def check_for(self, document, value): + return self.accessor(document) == value + + def as_query(self, value): + raise NotImplementedError + +class FieldPseudoPrefix(PseudoPrefix): + def __init__(self, name, description, field): + self._field = field + super().__init__(name, description, lambda doc: getattr(doc, field.name)) + + def as_query(self, value): + return self._field == value + +class FieldPartPseudoPrefix(PseudoPrefix): + def __init__(self, name, description, field, part): + self._field = field + self._field_part = getattr(field, part) + super().__init__(name, description, lambda doc: getattr(getattr(doc, field.name), part)) + + def as_query(self, value): + return self._field_part == value -- cgit v1.2.3