Compare commits

...

3 commits

Author SHA1 Message Date
Campbell Alden
cb70df80e1 Add a script for seeding data into the database
Expects a Data argument which is a directory containing the text for
A Study in Scarlet
2026-08-15 00:14:12 +09:00
Campbell Alden
81bad03ebd Remove HTML from stored data for entries
HTML will be rendered for entries derived from the plain text (at least,
I think).
2026-08-15 00:13:15 +09:00
Campbell Alden
5060f6a97f Fix a circular reference issue between users and the auth service 2026-08-15 00:12:38 +09:00
8 changed files with 50 additions and 11 deletions

View file

@ -7,4 +7,7 @@ buildPythonApplication {
src = ./.; src = ./.;
pyproject = true; pyproject = true;
build-system = [setuptools]; build-system = [setuptools];
postInstall = ''
install -Dm755 scripts/seed.py $out/bin/seed
'';
} }

42
scripts/seed.py Normal file
View file

@ -0,0 +1,42 @@
#!/usr/bin/env python
from sqlalchemy.orm import Session
from src.infra.publication import (
PublicationEntryModel,
PublicationSequenceModel,
PublicationModel,
PublicationOrderModel,
)
import argparse
import os
from src.config.database import Database
from src.infra.db import get_database
if __name__ == '__main__':
arg_parser = argparse.ArgumentParser('seed.py', 'run to load seed data into a database')
arg_parser.add_argument('-u', '--url', help='The URL for the database', required=True)
arg_parser.add_argument('-d', '--data', help='the directory containing large content files', required=True)
args = arg_parser.parse_args()
with open(os.path.join(args.data, './a-study-in-scarlet.txt')) as infile:
text = infile.read()
db = get_database(Database(url=args.url, echo=True))
with Session(db) as session:
entry = PublicationEntryModel(text=text)
session.add(entry)
publication = PublicationModel(
title='Sherlock Holmes Canon',
description='A collection of detective mystery novels featuring Sherlock Holmes',
by_line='Sir Arthur Conan Doyle',
)
session.flush()
order = PublicationOrderModel(title='Published Timeline', publication_id=publication.id)
session.flush()
sequence = PublicationSequenceModel(
position=0,
entry_id=entry.id,
order_id=order.id,
duration=None,
)
session.commit()

View file

@ -12,7 +12,6 @@ class PublicationEntryModel(Base):
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
text: Mapped[str] = mapped_column(Text()) text: Mapped[str] = mapped_column(Text())
html: Mapped[str | None] = mapped_column(Text())
sequences: Mapped[list['PublicationSequenceModel']] = relationship(back_populates='entry') sequences: Mapped[list['PublicationSequenceModel']] = relationship(back_populates='entry')
@ -56,7 +55,7 @@ class PublicationModel(Base):
def model_to_entry(db_pub_entry: PublicationEntryModel) -> Entry: def model_to_entry(db_pub_entry: PublicationEntryModel) -> Entry:
return Entry(id=db_pub_entry.id, text=db_pub_entry.text, html=db_pub_entry.html) return Entry(id=db_pub_entry.id, text=db_pub_entry.text)
def model_to_sequence(db_pub_position: PublicationSequenceModel) -> Sequence: def model_to_sequence(db_pub_position: PublicationSequenceModel) -> Sequence:

View file

@ -6,7 +6,8 @@ from sqlalchemy import String, VARCHAR, Engine, select
from sqlalchemy.orm import mapped_column, Mapped, Session from sqlalchemy.orm import mapped_column, Mapped, Session
from argon2 import PasswordHasher from argon2 import PasswordHasher
from src.infra.db import Base from src.infra.db import Base
from src.services.users import UserRepo, UserDTO, User from src.services.users.data import UserDTO, User
from src.services.users.repo import UserRepo
class UserModel(Base): class UserModel(Base):

View file

@ -4,7 +4,7 @@ from src.services.router import Router
from src.services.notifications import NotificationService, get_notification_service from src.services.notifications import NotificationService, get_notification_service
from src.services.email import EmailService, get_email_service from src.services.email import EmailService, get_email_service
from src.services.auth import AuthService from src.services.auth import AuthService
from src.services.users import UserService from src.services.users.service import UserService
from dataclasses import dataclass from dataclasses import dataclass
from src.infra.db import get_database from src.infra.db import get_database
from src.infra.users import UserRepoImpl from src.infra.users import UserRepoImpl

View file

@ -7,7 +7,7 @@ from dataclasses import dataclass, asdict
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
import jwt import jwt
from src.services.users import User from src.services.users.data import User
from src.config.auth import Auth as AuthConfig from src.config.auth import Auth as AuthConfig
JWT = str JWT = str

View file

@ -6,7 +6,6 @@ from dataclasses import dataclass, field
class Entry: class Entry:
id: int id: int
text: str text: str
html: str | None = None
@dataclass @dataclass

View file

@ -1,5 +0,0 @@
from .data import User, UserProfile, UserDTO, SignupError, LoginError
from .service import UserService
from .repo import UserRepo
__all__ = ['User', 'UserProfile', 'UserDTO', 'SignupError', 'LoginError', 'UserService', 'UserRepo']