"""
The app uses :mod:`pony` to manage a sqlite-database. The database is structured as follows.
.. image:: ../docs/ponyorm_diagram.png
"""
import os
from datetime import datetime
import toolz
from pony.orm import (
Database,
Json,
Optional,
PrimaryKey,
Required,
Set,
buffer,
db_session,
select,
)
from . import APP_DIR
from .utils import CD, update_word_state_dict
db = Database()
db_path = APP_DIR / "db.sqlite"
db.bind(
provider="sqlite",
filename=str(db_path),
create_db=not db_path.exists(),
)
[docs]class Template(db.Entity):
"""Contains data of a :class:`fields.Template` and all cards that have been generated with the template."""
[docs] id = PrimaryKey(int, auto=True)
"""Id."""
[docs] name = Required(str, unique=True)
"""A unique name for the template."""
[docs] description = Optional(str)
"""A short description of the template."""
"""References to all the cards that have been generated using this template."""
[docs] additional_info = Optional(Json)
"""Additional info."""
@db_session
[docs] def get_card(self, name):
"""Get a single :class:`Card` by name. (unique attribute)."""
cards_by_name = select(c for c in self.cards if c.name == name)
return toolz.first(cards_by_name) if cards_by_name else None
@db_session
[docs] def get_cards_by_selector(self, selector):
"""Get cards by selector."""
return select(c for c in self.cards if selector(c))
@db_session
[docs] def add_card(self, name):
"""Create a new :class:`Card` with relation to this template."""
card = Card(name=name, state="waiting", template=self)
return card
@classmethod
@db_session
[docs] def names(cls):
"""Return list of all Templates in database."""
return [template.name for template in cls.select()]
[docs]class Card(db.Entity):
"""Object containing the data for a card."""
id = PrimaryKey(int, auto=True)
name = Required(str)
state = Required(str)
base_data = Optional(Json)
fields = Optional(Json)
media_files = Set("MediaFile")
dt_queried = Optional(datetime)
dt_generated = Optional(datetime)
dt_exported = Optional(datetime)
template = Required(Template)
def __setattr__(self, key, value):
"""Change state according to values set."""
super().__setattr__(key, value)
if key == "base_data":
self.dt_queried = datetime.now()
self.state = "ready"
if key == "fields":
self.dt_generated = datetime.now()
self.state = "done"
if key == "state":
update_word_state_dict(self.name, self.state)
@db_session
@db_session
@db_session
db.generate_mapping(create_tables=True)
# pylint: disable = W,C,R,I
if __name__ == "__main__":
from . import ANKI_DIR
from .exporter import export_cards
with db_session:
template = Template.get(name="Portuguese Vocab")
cards = select(c for c in template.cards if c.state == ("done" or "exported"))
export_cards(
cards, "/home/david/Schreibtisch/", os.path.join(ANKI_DIR, "vocab_card")
)