1 Commits

Author SHA1 Message Date
Thomas Peetz de2f2f34b2 setup multi-module project
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-08-12 15:13:06 +02:00
926 changed files with 197500 additions and 23302 deletions
-12
View File
@@ -1,12 +0,0 @@
# Posted by barth, modified by community. See post 'Timeline' for change history
# Retrieved 2026-08-19, License - CC BY-SA 4.0
NEXUS_URL=https://nexus.thpeetz.de
MAVEN_REPO=maven-snapshots
GROUP_ID=de.thpeetz
ARTIFACT_ID=kontor-spring
VERSION=0.3.0-SNAPSHOT
FILE_EXTENSION=jar
download_url=$(curl -X GET "${NEXUS_URL}/service/rest/v1/search/assets?repository=${MAVEN_REPO}&maven.groupId=${GROUP_ID}&maven.artifactId=${ARTIFACT_ID}&maven.baseVersion=${VERSION}&maven.extension=${FILE_EXTENSION}" -H "accept: application/json" | jq -rc '.items | .[].downloadUrl' | sort | tail -n 1)
wget $download_url
+1 -3
View File
@@ -14,9 +14,7 @@ ENV PATH="/root/.local/bin:${PATH}"
WORKDIR /app WORKDIR /app
COPY ./pyproject.toml . COPY ./pyproject.toml .
#RUN --mount=type=bind,source=/home/tpeetz/projects/kontor/kontor-model,target=/container/kontor-model uv add /container/kontor-model
#COPY ../kontor-model/ /container
RUN uv add /container/kontor-model
RUN uv sync RUN uv sync
# ------------------------------- Production Stage ------------------------------ ## # ------------------------------- Production Stage ------------------------------ ##
+1 -4
View File
@@ -24,13 +24,10 @@ dependencies = [
"psycopg2-binary>=2.9.10", "psycopg2-binary>=2.9.10",
"pytest-cov>=6.1.1", "pytest-cov>=6.1.1",
"databases[sqlite]>=0.9.0", "databases[sqlite]>=0.9.0",
"pydantic[email]>=2.11.3",
"jinja2>=3.1.6", "jinja2>=3.1.6",
"asyncpg>=0.30.0", "asyncpg>=0.30.0",
"bcrypt>=4.3.0", "bcrypt>=4.3.0",
"fastapi-jwt-auth>=0.5.0", "fastapi-jwt-auth>=0.5.0",
"msgspec[toml,yaml]>=0.21.1", "msgspec[toml,yaml]>=0.21.1",
"kontor-model",
] ]
[tool.uv.sources]
kontor-model = { path = "../kontor-model", editable = true }
-7
View File
@@ -18,7 +18,6 @@ from src.apis.version1.comics import (
from src.apis.version1.media import ( from src.apis.version1.media import (
actor, actor,
file, file,
lofi,
mediaactorfile, mediaactorfile,
mediavideo, mediavideo,
mediaarticle, mediaarticle,
@@ -105,12 +104,6 @@ api_router.include_router(
tags=["media"], tags=["media"],
dependencies=[Depends(get_current_user_from_token)], dependencies=[Depends(get_current_user_from_token)],
) )
api_router.include_router(
lofi.router,
prefix="/media",
tags=["media"],
dependencies=[Depends(get_current_user_from_token)],
)
api_router.include_router( api_router.include_router(
mediaarticle.router, mediaarticle.router,
prefix="/media", prefix="/media",
+2 -2
View File
@@ -9,8 +9,8 @@ from src.core.security import (
authenticate_user_by_username, authenticate_user_by_username,
create_access_token, create_access_token,
) )
from kontor_model.schema.admin.login import LoginRequest from src.schema.admin.login import LoginRequest
from kontor_model.schema.admin.token import Token from src.schema.admin.token import Token
from src.webapps.auth.forms import LoginForm from src.webapps.auth.forms import LoginForm
login_router = APIRouter() login_router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.admin import MailAccount from src.db.models.admin import MailAccount
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.admin.mailaccount import MailAccountResponse, to_response from src.schema.admin.mailaccount import MailAccountResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter from fastapi import APIRouter
from kontor_model.db.models.bookshelf import Article from src.db.models.bookshelf import Article
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.bookshelf.article import ArticleResponse, to_response from src.schema.bookshelf.article import ArticleResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter from fastapi import APIRouter
from kontor_model.db.models.bookshelf import ArticleAuthor from src.db.models.bookshelf import ArticleAuthor
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.bookshelf.articleauthor import ArticleAuthorResponse, to_response from src.schema.bookshelf.articleauthor import ArticleAuthorResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.bookshelf import Author from src.db.models.bookshelf import Author
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.bookshelf.author import AuthorResponse, to_response from src.schema.bookshelf.author import AuthorResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter from fastapi import APIRouter
from kontor_model.db.models.bookshelf import Book from src.db.models.bookshelf import Book
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.bookshelf.book import BookResponse, to_response from src.schema.bookshelf.book import BookResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter from fastapi import APIRouter
from kontor_model.db.models.bookshelf import BookAuthor from src.db.models.bookshelf import BookAuthor
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.bookshelf.bookauthor import BookAuthorResponse, to_response from src.schema.bookshelf.bookauthor import BookAuthorResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter from fastapi import APIRouter
from kontor_model.db.models.bookshelf import BookshelfPublisher from src.db.models.bookshelf import BookshelfPublisher
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.bookshelf.publisher import PublisherResponse, to_response from src.schema.bookshelf.publisher import PublisherResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,11 +2,11 @@ from typing import List
from fastapi import APIRouter, HTTPException, status from fastapi import APIRouter, HTTPException, status
from kontor_model.db.models.comic import Artist from src.db.models.comic import Artist
from kontor_model.db.repository.comics.artist import get_artist_details from src.db.repository.comics.artist import get_artist_details
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.artist import ArtistCreation, ArtistResponse, artist_to_response from src.schema.comics.artist import ArtistCreation, ArtistResponse, artist_to_response
from kontor_model.schema.comics.artist_details import ArtistDetailResponse from src.schema.comics.artist_details import ArtistDetailResponse
router = APIRouter() router = APIRouter()
+4 -4
View File
@@ -3,13 +3,13 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from src.core.log_conf import logger from src.core.log_conf import logger
from kontor_model.db.models.comic import Comic from src.db.models.comic import Comic
from kontor_model.db.repository.comics.comic import ( from src.db.repository.comics.comic import (
get_comic_details, get_comic_details,
) )
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.comic import ComicResponse, comic_to_response from src.schema.comics.comic import ComicResponse, comic_to_response
from kontor_model.schema.comics.comic_details import ComicDetailsResponse from src.schema.comics.comic_details import ComicDetailsResponse
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.comic import ComicWork from src.db.models.comic import ComicWork
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.comicwork import ComicWorkResponse, comicwork_to_response from src.schema.comics.comicwork import ComicWorkResponse, comicwork_to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.comic import Issue from src.db.models.comic import Issue
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.issue import IssueResponse, issue_to_response from src.schema.comics.issue import IssueResponse, issue_to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.comic import IssueWork from src.db.models.comic import IssueWork
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.issuework import IssueWorkResponse, issuework_to_response from src.schema.comics.issuework import IssueWorkResponse, issuework_to_response
router = APIRouter() router = APIRouter()
@@ -2,11 +2,11 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.comic import Publisher from src.db.models.comic import Publisher
from kontor_model.db.repository.comics.publisher import get_publisher_details from src.db.repository.comics.publisher import get_publisher_details
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.publisher import PublisherResponse, publisher_to_response from src.schema.comics.publisher import PublisherResponse, publisher_to_response
from kontor_model.schema.comics.publisher_details import PublisherDetailsResponse from src.schema.comics.publisher_details import PublisherDetailsResponse
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.comic import StoryArc from src.db.models.comic import StoryArc
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.storyarc import StoryArcResponse, storyarc_to_response from src.schema.comics.storyarc import StoryArcResponse, storyarc_to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.comic import Volume from src.db.models.comic import Volume
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.volume import VolumeResponse, volume_to_response from src.schema.comics.volume import VolumeResponse, volume_to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.comic import WorkType from src.db.models.comic import WorkType
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.comics.worktype import WorktypeResponse, worktype_to_response from src.schema.comics.worktype import WorktypeResponse, worktype_to_response
router = APIRouter() router = APIRouter()
+1 -1
View File
@@ -1,6 +1,6 @@
from fastapi import APIRouter, status from fastapi import APIRouter, status
from kontor_model.schema.admin.healthcheck import HealthCheck from src.schema.admin.healthcheck import HealthCheck
health_router = APIRouter() health_router = APIRouter()
+3 -3
View File
@@ -2,10 +2,10 @@ from typing import List
from fastapi import APIRouter, status, HTTPException from fastapi import APIRouter, status, HTTPException
from src.core.log_conf import logger from src.core.log_conf import logger
from kontor_model.db.repository.media.actor import delete_mediaactor, import_mediaactor from src.db.repository.media.actor import delete_mediaactor, import_mediaactor
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.media.actor import MediaActorModel, MediaActorResponse, actor_to_response from src.schema.media.actor import MediaActorModel, MediaActorResponse, actor_to_response
from kontor_model.db.models.media import MediaActor from src.db.models.media import MediaActor
router = APIRouter() router = APIRouter()
+6 -6
View File
@@ -2,21 +2,21 @@ from typing import List
from fastapi import APIRouter, status, HTTPException from fastapi import APIRouter, status, HTTPException
from src.core.log_conf import logger from src.core.log_conf import logger
from kontor_model.db.repository.media.actorfile import ( from src.db.repository.media.actorfile import (
create_new_mediaactorfile, create_new_mediaactorfile,
delete_mediaactorfile, delete_mediaactorfile,
) )
from kontor_model.db.repository.media.file import delete_mediafile, import_mediafile from src.db.repository.media.file import delete_mediafile, import_mediafile
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.media.actor import MediaActorResponse, actor_to_response from src.schema.media.actor import MediaActorResponse, actor_to_response
from kontor_model.schema.media.actorfile import MediaActorFileResponse, actorfile_to_response from src.schema.media.actorfile import MediaActorFileResponse, actorfile_to_response
from kontor_model.schema.media.file import ( from src.schema.media.file import (
MediaFileModel, MediaFileModel,
MediaFileResponse, MediaFileResponse,
file_to_response, file_to_response,
file_to_model, file_to_model,
) )
from kontor_model.db.models.media import MediaFile from src.db.models.media import MediaFile
router = APIRouter() router = APIRouter()
@@ -1,42 +0,0 @@
from typing import List
from fastapi import APIRouter, HTTPException
from kontor_model.db.models.media import MediaLofi
from src.db.session import SessionDep
from kontor_model.schema.media.lofi import MediaLofiResponse, lofi_to_response
router = APIRouter()
@router.get("/lofi", response_model=List[MediaLofiResponse])
def get_all_lofis(
db: SessionDep, review: bool = False, download: bool = False
) -> List[MediaLofiResponse]:
"""
Get all MediaLofis.
"""
results: List[MediaLofiResponse] = []
lofis: List[MediaLofi]
if review:
lofis = db.query(MediaLofi).filter(MediaLofi.review.is_(True)).all()
elif download:
lofis = db.query(MediaLofi).filter(MediaLofi.should_download.is_(True)).all()
else:
lofis = db.query(MediaLofi).all()
for medialofi in lofis:
response = lofi_to_response(medialofi)
results.append(response)
return results
@router.get("/lofi/{lofi_id}", response_model=MediaLofiResponse)
def get_lofi(lofi_id: str, db: SessionDep) -> MediaLofiResponse:
"""
Get MediaLofi by id.
"""
lofi = db.get(MediaLofi, lofi_id)
if lofi is None:
raise HTTPException(status_code=404, detail="MediaLofi could not be found")
response = lofi_to_response(lofi)
return response
@@ -1,10 +1,10 @@
from typing import List from typing import List
from fastapi import APIRouter, status, HTTPException from fastapi import APIRouter, status, HTTPException
from src.core.log_conf import logger from src.core.log_conf import logger
from kontor_model.db.models.media import MediaActorFile from src.db.models.media import MediaActorFile
from kontor_model.db.repository.media.actorfile import delete_mediaactorfile, import_mediaactorfile from src.db.repository.media.actorfile import delete_mediaactorfile, import_mediaactorfile
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.media.actorfile import MediaActorFileModel, MediaActorFileResponse, actorfile_to_response from src.schema.media.actorfile import MediaActorFileModel, MediaActorFileResponse, actorfile_to_response
router = APIRouter() router = APIRouter()
@@ -3,9 +3,9 @@ from typing import List
from fastapi import APIRouter from fastapi import APIRouter
from kontor_model.db.models.media import MediaArticle from src.db.models.media import MediaArticle
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.media.article import MediaArticleResponse, to_response from src.schema.media.article import MediaArticleResponse, to_response
router = APIRouter() router = APIRouter()
@@ -3,9 +3,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.media import MediaVideo from src.db.models.media import MediaVideo
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.media.video import MediaVideoResponse, video_to_response from src.schema.media.video import MediaVideoResponse, video_to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.tysc import Card from src.db.models.tysc import Card
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.card import CardResponse, to_response from src.schema.tysc.card import CardResponse, to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.tysc import CardSet from src.db.models.tysc import CardSet
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.cardset import CardSetResponse, to_response from src.schema.tysc.cardset import CardSetResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.tysc import FieldPosition from src.db.models.tysc import FieldPosition
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.fieldposition import FieldPositionResponse, to_response from src.schema.tysc.fieldposition import FieldPositionResponse, to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.tysc import Player from src.db.models.tysc import Player
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.player import PlayerResponse, to_response from src.schema.tysc.player import PlayerResponse, to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.tysc import Rooster from src.db.models.tysc import Rooster
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.rooster import RoosterResponse, to_response from src.schema.tysc.rooster import RoosterResponse, to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -3,8 +3,8 @@ from fastapi import APIRouter, HTTPException
from src.core.log_conf import logger from src.core.log_conf import logger
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.sport import SportResponse, to_response from src.schema.tysc.sport import SportResponse, to_response
from kontor_model.db.models.tysc import Sport from src.db.models.tysc import Sport
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.tysc import Team from src.db.models.tysc import Team
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.team import TeamResponse, to_response from src.schema.tysc.team import TeamResponse, to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.tysc import Vendor from src.db.models.tysc import Vendor
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.tysc.vendor import VendorResponse, to_response from src.schema.tysc.vendor import VendorResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.admin import Assignment from src.db.models.admin import Assignment
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.user.assignment import AssignmentResponse, to_response from src.schema.user.assignment import AssignmentResponse, to_response
router = APIRouter() router = APIRouter()
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from kontor_model.db.models.admin import Permission from src.db.models.admin import Permission
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.user.permission import PermissionResponse, to_response from src.schema.user.permission import PermissionResponse, to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -4,10 +4,10 @@ from sqlalchemy import select
from src.core.log_conf import logger from src.core.log_conf import logger
from src.core.security import CurrentUser from src.core.security import CurrentUser
from kontor_model.db.models.admin import Profile from src.db.models.admin import Profile
from src.db.repository.user import create_new_profile from src.db.repository.user import create_new_profile
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.user.profile import ProfileResponse, ProfileModel, to_response from src.schema.user.profile import ProfileResponse, ProfileModel, to_response
router = APIRouter() router = APIRouter()
+2 -2
View File
@@ -2,9 +2,9 @@ from typing import List
from fastapi import APIRouter from fastapi import APIRouter
from kontor_model.db.models.admin import Token from src.db.models.admin import Token
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.user.token import TokenResponse, to_response from src.schema.user.token import TokenResponse, to_response
router = APIRouter() router = APIRouter()
+5 -5
View File
@@ -15,15 +15,15 @@ from pydantic import ValidationError
from src.core.config import settings from src.core.config import settings
from src.core.log_conf import logger from src.core.log_conf import logger
from kontor_model.db.models.admin import Profile from src.db.models.admin import Profile
from kontor_model.db.repository.admin import ( from src.db.repository.admin import (
get_profile_by_username, get_profile_by_username,
get_profile_by_email, get_profile_by_email,
is_database_empty, is_database_empty,
) )
from src.db.session import SessionLocal from src.db.session import SessionLocal
from kontor_model.schema.admin.token import TokenData from src.schema.admin.token import TokenData
from kontor_model.schema.user.profile import ProfileModel, to_model from src.schema.user.profile import ProfileModel, to_model
oauth2_scheme = OAuth2PasswordBearer( oauth2_scheme = OAuth2PasswordBearer(
tokenUrl="/token", tokenUrl="/token",
@@ -163,7 +163,7 @@ async def get_current_user(
async def get_current_active_user( async def get_current_active_user(
current_user: Annotated[Profile, Security(get_current_user, scopes=["me"])], current_user: Annotated[Profile, Security(get_current_user, scopes=["me"])],
) -> ProfileModel: ) -> ProfileModel:
if not bool(current_user.enabled): if not current_user.enabled:
raise HTTPException(status_code=400, detail="Inactive user") raise HTTPException(status_code=400, detail="Inactive user")
user_model = to_model(current_user) user_model = to_model(current_user)
return user_model return user_model
+75
View File
@@ -0,0 +1,75 @@
from datetime import datetime
from typing import List
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, mapped_column, Mapped
from src.db.models.base import Base, BaseMixin
class Profile(Base, BaseMixin):
__tablename__ = 'profile'
first_name: Mapped[str]
last_name: Mapped[str]
user_name: Mapped[str] = mapped_column(nullable=False)
email: Mapped[str]
password: Mapped[str]
enabled: Mapped[bool]
assignments: Mapped[List["Assignment"]] = relationship(back_populates="profile")
tokens: Mapped[List["Token"]] = relationship(back_populates="profile")
def get_full_name(self) -> str:
full_name: str = ""
if self.first_name is not None:
full_name += str(self.first_name)
if self.last_name is not None:
if len(full_name) > 0:
full_name += " "
full_name += str(self.last_name)
return full_name
def __str__(self):
return f"Profile({self.id} {self.user_name}, {self.email})"
class Token(Base, BaseMixin):
__tablename__ = "token"
token: Mapped[str] = mapped_column(nullable=False, unique=True)
name: Mapped[str]
last_used_date: Mapped[datetime]
enabled: Mapped[bool]
profile_id = mapped_column(ForeignKey("profile.id"), nullable=False)
profile: Mapped[Profile] = relationship(back_populates="tokens")
class Permission(Base, BaseMixin):
__tablename__ = "permission"
name: Mapped[str] = mapped_column(nullable=False)
assignments: Mapped[List["Assignment"]] = relationship(back_populates="permission")
class Assignment(Base, BaseMixin):
__tablename__ = "assignment"
profile_id = mapped_column(ForeignKey("profile.id"), nullable=False)
profile: Mapped[Profile] = relationship(back_populates="assignments")
permission_id = mapped_column(ForeignKey("permission.id"), nullable=False)
permission: Mapped[Permission] = relationship(back_populates="assignments")
class MailAccount(Base, BaseMixin):
__tablename__ = "mail_account"
host: Mapped[str]
port: Mapped[int]
protocol: Mapped[str]
user_name: Mapped[str]
password: Mapped[str]
start_tls: Mapped[bool]
class Mail(Base, BaseMixin):
__tablename__ = "mail"
folder: Mapped[str]
subject: Mapped[str]
body: Mapped[str]
sent_date: Mapped[datetime]
received_date: Mapped[datetime]
+27
View File
@@ -0,0 +1,27 @@
from typing import Optional
import uuid
from datetime import datetime
from sqlalchemy import func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class BaseMixin:
id: Mapped[str] = mapped_column(primary_key=True, default=str(uuid.uuid4()))
created_date: Mapped[datetime] = mapped_column(default=func.now())
last_modified_date: Mapped[datetime] = mapped_column(default=func.now())
version: Mapped[int] = mapped_column(default=0)
class BaseVideoMixin:
cloud_link: Mapped[Optional[str]]
file_name: Mapped[Optional[str]]
path: Mapped[str]
review: Mapped[bool]
title: Mapped[str]
url: Mapped[str]
should_download: Mapped[bool]
+52
View File
@@ -0,0 +1,52 @@
from typing import List
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.db.models.base import Base, BaseMixin
class Article(Base, BaseMixin):
__tablename__ = 'article'
title: Mapped[str] = mapped_column(unique=True)
article_authors = relationship("ArticleAuthor")
class Author(Base, BaseMixin):
__tablename__ = 'author'
first_name: Mapped[str]
last_name: Mapped[str]
article_authors: Mapped[List["ArticleAuthor"]] = relationship(back_populates="author")
book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="author")
class BookshelfPublisher(Base, BaseMixin):
__tablename__ = 'bookshelf_publisher'
name: Mapped[str] = mapped_column(unique=True)
books: Mapped[List["Book"]] = relationship(back_populates="publisher")
class Book(Base, BaseMixin):
__tablename__ = 'book'
isbn: Mapped[str] = mapped_column(unique=True)
title: Mapped[str]
year: Mapped[int] = mapped_column(nullable=False)
publisher_id: Mapped[str] = mapped_column(ForeignKey("bookshelf_publisher.id"), nullable=False)
publisher: Mapped[BookshelfPublisher] = relationship(back_populates="books")
book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="book")
class ArticleAuthor(Base, BaseMixin):
__tablename__ = 'article_author'
article_id: Mapped[str] = mapped_column(ForeignKey("article.id"), nullable=False)
article: Mapped[Article] = relationship(back_populates="article_authors")
author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False)
author: Mapped[Author] = relationship(back_populates="article_authors")
class BookAuthor(Base, BaseMixin):
__tablename__ = 'book_author'
author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False)
author: Mapped[Author] = relationship(back_populates="book_authors")
book_id: Mapped[str] = mapped_column(ForeignKey("book.id"), nullable=False)
book: Mapped[Book] = relationship(back_populates="book_authors")
+188
View File
@@ -0,0 +1,188 @@
import uuid
from datetime import datetime
from typing import Dict, List, Optional, Any
from natsort import natsorted
from sqlalchemy import ForeignKey, func
from sqlalchemy.orm import relationship, Mapped, mapped_column
from src.db.models.base import Base, BaseMixin
class Publisher(Base):
__tablename__ = "publisher"
id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4)
created_date: Mapped[datetime] = mapped_column(default=func.now())
last_modified_date: Mapped[datetime] = mapped_column(default=func.now())
version: Mapped[int] = mapped_column(default=0)
name: Mapped[str] = mapped_column(unique=True)
weblink: Mapped[Optional[str]]
parent_publisher_id: Mapped[Optional[str]] = mapped_column(ForeignKey('publisher.id'))
parent_publisher: Mapped[Optional['Publisher']] = relationship(back_populates="imprints", remote_side=[id])
imprints: Mapped[List['Publisher']] = relationship(back_populates="parent_publisher")
comics: Mapped[List["Comic"]] = relationship(back_populates="publisher")
def __repr__(self):
return f'Publisher({self.id} {self.name})'
def __str__(self):
return self.__repr__()
class Comic(Base, BaseMixin):
__tablename__ = 'comic'
title: Mapped[str] = mapped_column(unique=True)
publisher_id: Mapped[str] = mapped_column(ForeignKey('publisher.id'), nullable=False)
publisher: Mapped[Publisher] = relationship(back_populates="comics")
current_order: Mapped[bool]
completed: Mapped[bool]
weblink: Mapped[Optional[str]]
issues: Mapped[List["Issue"]] = relationship(back_populates="comic", order_by="Issue.issue_number")
story_arcs: Mapped[List["StoryArc"]] = relationship(back_populates="comic")
trade_paperbacks: Mapped[List["TradePaperback"]] = relationship(back_populates="comic")
volumes: Mapped[List["Volume"]] = relationship(back_populates="comic")
comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="comic")
def __repr__(self):
return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})'
def __str__(self):
return f'{self.title}({self.id})'
def get_artists(self) -> Dict[Any, List[Any]]:
works: Dict[Any, List[Any]] = {}
for work in self.comic_works:
work_type = work.work_type
artist = work.artist
if work_type in works:
works[work_type].append(artist)
else:
works[work_type] = [artist]
return works
def sorted_issues(self):
sorted_issues = natsorted(self.issues, key=lambda x: getattr(x, 'issue_number'))
return sorted_issues
class Volume(Base, BaseMixin):
__tablename__ = "volume"
name: Mapped[str] = mapped_column(nullable=False)
comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic: Mapped[Comic] = relationship(back_populates="volumes")
story_arcs: Mapped[List["StoryArc"]] = relationship(back_populates="volume")
issues: Mapped[List["Issue"]] = relationship(back_populates="volume")
class TradePaperback(Base, BaseMixin):
__tablename__ = "trade_paperback"
name: Mapped[str] = mapped_column(nullable=False)
issue_start: Mapped[int]
issue_end: Mapped[int]
comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic: Mapped[Comic] = relationship(back_populates="trade_paperbacks")
class StoryArc(Base, BaseMixin):
__tablename__ = "story_arc"
name: Mapped[str] = mapped_column(nullable=False)
comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic: Mapped[Comic] = relationship(back_populates="story_arcs")
volume_id: Mapped[str] = mapped_column(ForeignKey("volume.id"), nullable=True)
volume: Mapped[Volume] = relationship(back_populates="story_arcs")
issues: Mapped[List["Issue"]] = relationship(back_populates="story_arc")
class Issue(Base, BaseMixin):
__tablename__ = "issue"
issue_number: Mapped[str]
title: Mapped[Optional[str]]
published_on: Mapped[Optional[datetime]]
in_stock: Mapped[bool]
is_read: Mapped[bool]
comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic: Mapped[Comic] = relationship(back_populates="issues")
volume_id: Mapped[str] = mapped_column(ForeignKey("volume.id"), nullable=True)
volume: Mapped[Volume] = relationship(back_populates="issues")
story_arc_id: Mapped[str] = mapped_column(ForeignKey("story_arc.id"), nullable=True)
story_arc: Mapped[StoryArc] = relationship(back_populates="issues")
issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="issue")
def get_full_title(self) -> str:
full_title: str = str(self.issue_number)
if self.title:
full_title += str(": " + self.title)
return full_title
def get_artists(self) -> Dict[Any, List[Any]]:
works: Dict[Any, List[Any]] = {}
for work in self.issue_works:
work_type = work.work_type
artist = work.artist
if work_type in works:
works[work_type].append(artist)
else:
works[work_type] = [artist]
return works
class Artist(Base, BaseMixin):
__tablename__ = "artist"
name: Mapped[str] = mapped_column(nullable=False)
weblink: Mapped[str] = mapped_column(nullable=True)
comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="artist")
issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="artist")
def get_comics(self) -> Dict[Any, List[Comic]]:
works: Dict[Any, List[Comic]] = {}
for work in self.comic_works:
work_type = work.work_type
comic = work.comic
if work_type in works:
works[work_type].append(comic)
else:
works[work_type] = [comic]
return works
class WorkType(Base, BaseMixin):
__tablename__ = "worktype"
name: Mapped[str] = mapped_column(nullable=False, unique=True)
comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="work_type")
issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="work_type")
def get_artists(self) -> Dict[str, List[Artist]]:
works: Dict[str, List[Artist]] = {}
for work in self.comic_works:
comic = work.comic.title
artist = work.artist
if comic in works:
works[comic].append(artist)
else:
works[comic] = [artist]
return works
def __repr__(self):
return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})'
def __str__(self):
return f'{self.name}({self.id})'
class ComicWork(Base, BaseMixin):
__tablename__ = "comic_work"
comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic: Mapped[Comic] = relationship(back_populates="comic_works")
artist_id: Mapped[str] = mapped_column(ForeignKey("artist.id"), nullable=False)
artist: Mapped[Artist] = relationship(back_populates="comic_works")
work_type_id: Mapped[str] = mapped_column(ForeignKey("worktype.id"), nullable=False)
work_type: Mapped[WorkType] = relationship(back_populates="comic_works")
class IssueWork(Base, BaseMixin):
__tablename__ = "issue_work"
issue_id: Mapped[str] = mapped_column(ForeignKey("issue.id"), nullable=False)
issue: Mapped[Issue] = relationship(back_populates="issue_works")
artist_id: Mapped[str] = mapped_column(ForeignKey("artist.id"), nullable=False)
artist: Mapped[Artist] = relationship(back_populates="issue_works")
work_type_id: Mapped[str] = mapped_column(ForeignKey("worktype.id"), nullable=False)
work_type: Mapped[WorkType] = relationship(back_populates="issue_works")
+97
View File
@@ -0,0 +1,97 @@
import logging
import re
import subprocess
from datetime import datetime
from pathlib import Path
from typing import List, Optional
import requests
from bs4 import BeautifulSoup
from sqlalchemy import ForeignKey
from sqlalchemy.orm import Mapped, relationship, mapped_column
from src.db.models.base import Base, BaseMixin, BaseVideoMixin
class MediaFile(Base, BaseMixin, BaseVideoMixin):
"""
MediaFile represents video link.
"""
__tablename__ = "media_file"
media_actor_files: Mapped[List["MediaActorFile"]] = relationship(
back_populates="media_file"
)
def __repr__(self):
return f"MediaFile({self.id} {self.title} {self.title})"
def __str__(self):
return f"{self.title}({self.id})"
def update_title(self):
"""
Update title from url.
"""
class MediaActor(Base, BaseMixin):
__tablename__ = "media_actor"
name: Mapped[str]
url: Mapped[Optional[str]] = mapped_column(unique=True)
media_actor_files = relationship("MediaActorFile")
def __repr__(self) -> str:
return f"MediaActor({self.id} {self.name} {self.url})"
def __str__(self) -> str:
return f"{self.url}({self.id})"
class MediaActorFile(Base, BaseMixin):
__tablename__ = "media_actor_file"
media_actor_id: Mapped[str] = mapped_column(
ForeignKey("media_actor.id"), nullable=False
)
media_actor: Mapped[MediaActor] = relationship(back_populates="media_actor_files")
media_file_id: Mapped[str] = mapped_column(
ForeignKey("media_file.id"), nullable=True
)
media_file: Mapped[MediaFile] = relationship(back_populates="media_actor_files")
def __repr__(self):
return f"MediaActorFile({self.id} {self.media_actor_id} {self.media_file_id})"
def __str__(self) -> str:
return f"{self.id} {self.media_actor_id} {self.media_file_id}"
class MediaArticle(Base, BaseMixin):
__tablename__ = "media_article"
review: Mapped[bool]
title: Mapped[str]
url: Mapped[str] = mapped_column(unique=True)
class MediaVideo(Base, BaseMixin):
"""
MediaFile represents video link.
"""
__tablename__ = "media_video"
cloud_link: Mapped[str]
file_name: Mapped[str]
path: Mapped[str]
review: Mapped[bool]
title: Mapped[str]
url: Mapped[str] = mapped_column(unique=True)
should_download: Mapped[bool]
def __repr__(self):
return f"MediaFile({self.id} {self.title} {self.url})"
def __str__(self):
if self.title is None:
return f"{self.url}({self.id})"
else:
return f"{self.title}({self.id})"
+100
View File
@@ -0,0 +1,100 @@
from typing import List
from sqlalchemy import ForeignKey, UniqueConstraint
from sqlalchemy.orm import relationship, mapped_column, Mapped
from src.db.models.base import Base, BaseMixin
class Sport(Base, BaseMixin):
__tablename__ = "sport"
__table_args__ = (
UniqueConstraint("name"),
)
name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True)
teams: Mapped[List["Team"]] = relationship(back_populates="sport")
positions: Mapped[List["FieldPosition"]] = relationship(back_populates="sport")
class Team(Base, BaseMixin):
__tablename__ = "team"
name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True)
short_name: Mapped[str] = mapped_column(nullable=False)
sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False)
sport: Mapped[Sport] = relationship(back_populates="teams")
roosters: Mapped[List["Rooster"]] = relationship(back_populates="team")
class FieldPosition(Base, BaseMixin):
__tablename__ = "field_position"
__table_args__ = (
UniqueConstraint("name", "sport_id"),
UniqueConstraint("short_name", "sport_id"),
)
name: Mapped[str] = mapped_column(nullable=False, index=True)
short_name: Mapped[str] = mapped_column(nullable=False)
sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False, index=True)
sport: Mapped[Sport] = relationship(back_populates="positions")
roosters: Mapped[List["Rooster"]] = relationship(back_populates="position")
class Player(Base, BaseMixin):
__tablename__ = "player"
__table_args__ = (
UniqueConstraint("first_name", "last_name"),
)
first_name: Mapped[str] = mapped_column(nullable=False, index=True)
last_name: Mapped[str] = mapped_column(nullable=False, index=True)
roosters: Mapped[List["Rooster"]] = relationship(back_populates="player")
def get_full_name(self) -> str:
return f"{self.last_name}, {self.first_name}"
class Rooster(Base, BaseMixin):
__tablename__ = "rooster"
__table_args__ = (
UniqueConstraint("year", "team_id", "player_id", "position_id"),
)
year: Mapped[int]
team_id: Mapped[str] = mapped_column(ForeignKey("team.id"), nullable=False, index=True)
team: Mapped[Team] = relationship(back_populates="roosters")
player_id: Mapped[str] = mapped_column(ForeignKey("player.id"), nullable=False, index=True)
player: Mapped[Player] = relationship(back_populates="roosters")
position_id: Mapped[str] = mapped_column(ForeignKey("field_position.id"), nullable=False, index=True)
position: Mapped[FieldPosition] = relationship(back_populates="roosters")
cards: Mapped[List["Card"]] = relationship(back_populates="rooster")
class Vendor(Base, BaseMixin):
__tablename__ = "vendor"
name: Mapped[str] = mapped_column(nullable=False, unique=True, index=True)
card_sets: Mapped[List["CardSet"]] = relationship(back_populates="vendor")
cards: Mapped[List["Card"]] = relationship(back_populates="vendor")
class CardSet(Base, BaseMixin):
__tablename__ = "card_set"
__table_args__ = (
UniqueConstraint("name", "vendor_id"),
)
name: Mapped[str] = mapped_column(index=True)
parallel_set: Mapped[bool]
insert_set: Mapped[bool]
vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False, index=True)
vendor: Mapped[Vendor] = relationship(back_populates="card_sets")
cards: Mapped[List["Card"]] = relationship(back_populates="card_set")
class Card(Base, BaseMixin):
__tablename__ = "card"
__table_args__ = (
UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"),
)
card_number: Mapped[int] = mapped_column(index=True)
year: Mapped[int] = mapped_column(index=True)
card_set_id: Mapped[str] = mapped_column(ForeignKey("card_set.id"), nullable=False)
card_set: Mapped[CardSet] = relationship(back_populates="cards")
rooster_id: Mapped[str] = mapped_column(ForeignKey("rooster.id"), nullable=False)
rooster: Mapped[Rooster] = relationship(back_populates="cards")
vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False)
vendor: Mapped[Vendor] = relationship(back_populates="cards")
+18
View File
@@ -0,0 +1,18 @@
from typing import Optional
from sqlalchemy.orm import Session
from src.db.models.admin import Profile
def get_profile_by_username(username: str, db: Session) -> Optional[Profile]:
profile = db.query(Profile).filter(Profile.user_name == username).first()
return profile
def get_profile_by_email(email: str, db: Session) -> Optional[Profile]:
profile = db.query(Profile).filter(Profile.email == email).first()
return profile
def is_database_empty(db: Session) -> bool:
profiles = db.query(Profile).all()
return len(profiles) == 0
@@ -0,0 +1,47 @@
import uuid
from typing import List, Optional
from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.comic import Artist
from src.schema.comics.artist import AddArtist
from src.schema.comics.artist_details import ArtistDetailResponse, ArtistWorktypeComicResponse, ArtistWorktypeIssueResponse
from src.schema.comics.comic import ComicResponse
from src.schema.comics.worktype import WorktypeResponse
def get_artist_details(artist: Artist) -> ArtistDetailResponse:
comic_works: List[ArtistWorktypeComicResponse] = []
comic_works_map = {}
for work in artist.comic_works:
worktype_id = work.work_type.id
if worktype_id in comic_works_map:
comic = ComicResponse(id=work.comic.id, title=work.comic.title, completed=work.comic.completed)
comic_works_map[worktype_id].comics.append(comic)
else:
comic_works_map[worktype_id] = ArtistWorktypeComicResponse(
worktype=WorktypeResponse(id=worktype_id, name=work.work_type.name),
comics=[ComicResponse(id=work.comic.id, title=work.comic.title, completed=work.comic.completed)]
)
for value in comic_works_map.values():
comic_works.append(value)
issue_works: List[ArtistWorktypeIssueResponse] = []
response = ArtistDetailResponse(
id=artist.id,
name=str(artist.name),
weblink=str(artist.weblink),
comic_works=comic_works,
issue_works=issue_works,
)
return response
def update_artist(add_artist: AddArtist, artist_id: str, db: Session) -> Optional[Artist]:
logger.info("update artist")
artist: Optional[Artist] = db.get(Artist, artist_id)
if artist is not None:
artist.name = add_artist.name
db.add(artist)
db.commit()
db.refresh(artist)
return artist
@@ -0,0 +1,72 @@
from typing import Dict, List, Optional
from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.comic import Comic, Issue
from src.schema.comics.artist import artist_to_response
from src.schema.comics.comic import ComicSchema, comic_to_response
from src.schema.comics.comic_details import ComicDetailsResponse, ComicWorktypeArtistResponse
from src.schema.comics.issue import IssueResponse, issue_to_response
from src.schema.comics.issue_details import IssueDetailsResponse
from src.schema.comics.publisher import publisher_to_response
from src.schema.comics.volume import VolumeResponse, volume_to_response
from src.schema.comics.worktype import worktype_to_response
def get_issue_details(issue: Issue) -> IssueDetailsResponse:
volume = None
if issue.volume:
volume = volume_to_response(issue.volume)
response = IssueDetailsResponse(
id=issue.id,
issue_number=str(issue.issue_number),
in_stock=bool(issue.in_stock),
is_read=bool(issue.is_read),
comic=comic_to_response(issue.comic),
volume=volume
)
return response
def update_comic(new_comic: ComicSchema, comic_id: str, db: Session) -> Optional[Comic]:
logger.info(f"update_comic: {new_comic} with {comic_id}")
comic: Optional[Comic] = db.get(Comic, comic_id)
return comic
def get_comic_details(comic: Comic) -> ComicDetailsResponse:
volumes: List[VolumeResponse] = []
for volume in comic.volumes:
volumes.append(volume_to_response(volume))
issues: List[IssueResponse] = []
for issue in comic.issues:
issues.append(issue_to_response(issue))
works: List[ComicWorktypeArtistResponse] = []
works_map: Dict[str, ComicWorktypeArtistResponse] = {}
for work in comic.comic_works:
worktype_id = work.work_type.id
if worktype_id in works_map:
artist = artist_to_response(work.artist)
works_map[worktype_id].artists.append(artist)
logger.info(f"add artist to response map: {artist} -> {works_map}")
print(f"add artist to response map: {artist} -> {works_map}")
else:
works_map[worktype_id] = ComicWorktypeArtistResponse(
worktype=worktype_to_response(work.work_type),
artists=[artist_to_response(work.artist)]
)
for value in works_map.values():
works.append(value)
response = ComicDetailsResponse(
id=str(comic.id),
created=str(comic.created_date),
title=str(comic.title),
completed=bool(comic.completed),
current_order=bool(comic.current_order),
weblink=str(comic.weblink),
publisher=publisher_to_response(comic.publisher),
issues=issues,
volumes=volumes,
works=works
)
return response
@@ -0,0 +1,24 @@
from typing import List
from src.db.models.comic import Publisher
from src.schema.comics.comic import ComicResponse
from src.schema.comics.publisher import PublisherResponse
from src.schema.comics.publisher_details import PublisherDetailsResponse
def get_publisher_details(publisher: Publisher) -> PublisherDetailsResponse:
imprints: List[PublisherResponse] = []
for imprint in publisher.imprints:
imprints.append(PublisherResponse(id=imprint.id, name=str(imprint.name)))
comics: List[ComicResponse] = []
for comic in publisher.comics:
comics.append(
ComicResponse(id=comic.id, title=comic.title, completed=comic.completed)
)
parent_publisher: PublisherResponse | None = None
if publisher.parent_publisher:
parent_publisher = PublisherResponse(id=publisher.parent_publisher.id, name=str(publisher.parent_publisher.name))
response: PublisherDetailsResponse = PublisherDetailsResponse(
id=publisher.id, name=str(publisher.name), parent_publisher=parent_publisher, imprints=imprints, comics=comics
)
return response
@@ -0,0 +1,33 @@
import uuid
from datetime import datetime
from typing import AnyStr, Optional
from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.comic import WorkType
from src.schema.comics.worktype import AddWorkType
def create_new_worktype(work: AddWorkType, db: Session) -> WorkType:
worktype = WorkType()
worktype.id = str(uuid.uuid4())
worktype.created_date = datetime.now()
worktype.last_modified_date = datetime.now()
worktype.name = work.worktype
db.add(worktype)
db.commit()
db.refresh(worktype)
logger.info(f"create_new_worktype: {worktype}")
return worktype
def update_worktype(work: AddWorkType, worktype_id: AnyStr, db: Session) -> Optional[WorkType]:
logger.info("update worktype")
worktype: Optional[WorkType] = db.get(WorkType, worktype_id)
if worktype is not None:
worktype.name = work.worktype
db.add(worktype)
db.commit()
db.refresh(worktype)
return worktype
@@ -0,0 +1,66 @@
from datetime import datetime
import uuid
from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.media import MediaActor
from src.db.repository.media.actorfile import delete_mediaactorfile
from src.schema.media.actor import MediaActorModel
def create_new_mediaactor(new_actor: MediaActorModel, db: Session) -> MediaActor:
logger.info(f"create MediaActor with url {new_actor.url}")
media_actor: MediaActor = MediaActor()
media_actor.id = str(uuid.uuid4())
if new_actor.name is not None:
media_actor.name = new_actor.name
media_actor.url = new_actor.url
media_actor.created_date = datetime.now()
media_actor.last_modified_date = datetime.now()
media_actor.version = 0
db.add(media_actor)
db.commit()
db.refresh(media_actor)
logger.info(f"created {media_actor}")
return media_actor
def delete_mediaactor(db: Session, actor_id: str):
logger.info(f"delete MediaActor with id {actor_id}")
media_actor = db.get(MediaActor, actor_id)
if media_actor is not None:
actor_files = media_actor.media_actor_files
for actor_file in actor_files:
delete_mediaactorfile(db, actorfile_id=actor_file.id)
db.refresh(media_actor)
db.delete(media_actor)
db.commit()
def import_mediaactor(db: Session, new_actor: MediaActorModel) -> MediaActor:
"""
import MediaFile and set missing values with default ones.
"""
logger.info("import MediaActor with %s", new_actor)
media_actor: MediaActor = MediaActor()
media_actor.id = new_actor.id
if new_actor.created_date:
media_actor.created_date = new_actor.created_date
else:
media_actor.created_date = datetime.now()
if new_actor.last_modified_date:
media_actor.last_modified_date = new_actor.last_modified_date
else:
media_actor.last_modified_date = datetime.now()
media_actor.version = new_actor.version
if new_actor.name:
media_actor.name = new_actor.name
else:
media_actor.name = ""
if new_actor.url:
media_actor.url = new_actor.url
else:
media_actor.url = ""
db.add(media_actor)
db.commit()
db.refresh(media_actor)
return media_actor
@@ -0,0 +1,64 @@
from datetime import datetime
import uuid
from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.media import MediaActorFile
from src.schema.media.actorfile import MediaActorFileModel
def create_new_mediaactorfile(
db: Session, actor_id: str, file_id: str
) -> MediaActorFile:
"""
Create relation for MediaFile and MediaActor
"""
logger.info("create MediaActorFile with actor %s and file %s", actor_id, file_id)
media_actor_file: MediaActorFile = MediaActorFile()
media_actor_file.id = str(uuid.uuid4())
media_actor_file.created_date = datetime.now()
media_actor_file.last_modified_date = datetime.now()
media_actor_file.version = 0
media_actor_file.media_actor_id = actor_id
media_actor_file.media_file_id = file_id
db.add(media_actor_file)
db.commit()
db.refresh(media_actor_file)
return media_actor_file
def delete_mediaactorfile(db: Session, actorfile_id: str):
"""
Delete relation between MediaFile and MediaActor.
"""
logger.info("delete MediaActorFile with id %s", actorfile_id)
media_actorfile = db.get(MediaActorFile, actorfile_id)
db.delete(media_actorfile)
db.commit()
def import_mediaactorfile(
db: Session, new_actorfile: MediaActorFileModel
) -> MediaActorFile:
"""
Import MediaFile and set missing values with default ones.
"""
logger.info("import MediaActorFile with %s", new_actorfile)
media_actor_file: MediaActorFile = MediaActorFile()
media_actor_file.id = new_actorfile.id
if new_actorfile.created_date:
media_actor_file.created_date = new_actorfile.created_date
else:
media_actor_file.created_date = datetime.now()
if new_actorfile.last_modified_date:
media_actor_file.last_modified_date = new_actorfile.last_modified_date
else:
media_actor_file.last_modified_date = datetime.now()
media_actor_file.version = new_actorfile.version
media_actor_file.media_actor_id = new_actorfile.media_actor_id
media_actor_file.media_file_id = new_actorfile.media_file_id
db.add(media_actor_file)
db.commit()
db.refresh(media_actor_file)
return media_actor_file
@@ -0,0 +1,78 @@
from datetime import datetime
import uuid
from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.media import MediaFile
from src.schema.media.file import MediaFileModel
def create_new_mediafile(link: str, db: Session) -> MediaFile:
"""
Create MediaFile with gievne URL.
"""
logger.info("create MediaFile with url {link}")
media_file: MediaFile = MediaFile()
media_file.id = str(uuid.uuid4())
media_file.url = link
media_file.created_date = datetime.now()
media_file.last_modified_date = datetime.now()
media_file.version = 0
media_file.review = True
media_file.should_download = True
db.add(media_file)
db.commit()
db.refresh(media_file)
logger.info("created %s", media_file)
return media_file
def delete_mediafile(db: Session, media_file_id: str):
"""
Delete MediaFile with given ID from db.
"""
logger.info("delete MediaFile with id %s", media_file_id)
media_file = db.get(MediaFile, media_file_id)
db.delete(media_file)
db.commit()
def import_mediafile(db: Session, new_file: MediaFileModel) -> MediaFile:
"""
import MediaActor and set missing values with defautl ones.
"""
logger.info("import MediaFile with %s", new_file)
media_file: MediaFile = MediaFile()
media_file.id = new_file.id
if new_file.created_date:
media_file.created_date = new_file.created_date
else:
media_file.created_date = datetime.now()
if new_file.last_modified_date:
media_file.last_modified_date = new_file.last_modified_date
else:
media_file.last_modified_date = datetime.now()
media_file.version = new_file.version
if new_file.title:
media_file.title = new_file.title
else:
media_file.title = ""
if new_file.file_name:
media_file.file_name = new_file.file_name
else:
media_file.file_name = ""
if new_file.cloud_link:
media_file.cloud_link = new_file.cloud_link
else:
media_file.cloud_link = ""
if new_file.url:
media_file.url = new_file.url
else:
media_file.url = ""
media_file.review = new_file.review
media_file.should_download = new_file.should_download
db.add(media_file)
db.commit()
db.refresh(media_file)
return media_file
@@ -0,0 +1,23 @@
from datetime import datetime
import uuid
from sqlalchemy.orm import Session
from src.db.models.media import MediaVideo
from src.webapps.media.forms import AddLinkForm
def create_new_video(video: AddLinkForm, db: Session) -> MediaVideo:
print(video.url)
media_video = MediaVideo()
media_video.id = str(uuid.uuid4())
media_video.url = str(video.url)
media_video.created_date = datetime.now()
media_video.last_modified_date = datetime.now()
media_video.review = True
media_video.should_download = True
db.add(media_video)
db.commit()
db.refresh(media_video)
print(media_video)
return media_video
+2 -2
View File
@@ -2,10 +2,10 @@ from datetime import datetime
from typing import Optional from typing import Optional
import uuid import uuid
from src.core.log_conf import logger from src.core.log_conf import logger
from kontor_model.db.models.admin import Assignment, Profile from src.db.models.admin import Assignment, Profile
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from kontor_model.schema.user.profile import ProfileModel from src.schema.user.profile import ProfileModel
def create_new_profile(new_profile: ProfileModel, db: Session) -> Profile: def create_new_profile(new_profile: ProfileModel, db: Session) -> Profile:
+1 -1
View File
@@ -10,7 +10,7 @@ from src.apis.version1.admin.login import login_router
from src.core.config import settings from src.core.config import settings
from src.core.log_conf import logger from src.core.log_conf import logger
from src.core.middleware import RequestLoggingMiddleware from src.core.middleware import RequestLoggingMiddleware
from kontor_model.db.models.base import Base from src.db.models.base import Base
from src.db.session import engine from src.db.session import engine
from src.db.utils import check_db_connected, check_db_disconnected from src.db.utils import check_db_connected, check_db_disconnected
from src.webapps.base import api_router as web_app_router from src.webapps.base import api_router as web_app_router
@@ -0,0 +1,34 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.admin import MailAccount
class MailAccountResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
host: str
port: int
protocol: str
user_name: str
password: str
start_tls: bool
def to_response(account: MailAccount) -> MailAccountResponse:
response: MailAccountResponse = MailAccountResponse(
id=account.id,
created_date=account.created_date,
last_modified_date=account.last_modified_date,
version=account.version,
host=account.host,
port=account.port,
protocol=account.protocol,
user_name=account.user_name,
password=account.password,
start_tls=account.start_tls,
)
return response
@@ -0,0 +1,23 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.bookshelf import Article
class ArticleResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
title: str
def to_response(article: Article) -> ArticleResponse:
response: ArticleResponse = ArticleResponse(
id=article.id,
created_date=article.created_date,
last_modified_date=article.last_modified_date,
version=article.version,
title=article.title
)
return response
@@ -0,0 +1,25 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.bookshelf import ArticleAuthor
class ArticleAuthorResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
article_id: str
author_id: str
def to_response(articleauthor: ArticleAuthor) -> ArticleAuthorResponse:
response: ArticleAuthorResponse = ArticleAuthorResponse(
id=articleauthor.id,
created_date=articleauthor.created_date,
last_modified_date=articleauthor.last_modified_date,
version=articleauthor.version,
article_id=articleauthor.article_id,
author_id=articleauthor.author_id
)
return response
+25
View File
@@ -0,0 +1,25 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.bookshelf import Author
class AuthorResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
first_name: str
last_name: str
def to_response(author: Author) -> AuthorResponse:
response: AuthorResponse = AuthorResponse(
id=author.id,
created_date=author.created_date,
last_modified_date=author.last_modified_date,
version=author.version,
first_name=author.first_name,
last_name=author.last_name
)
return response
+29
View File
@@ -0,0 +1,29 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.bookshelf import Book
class BookResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
isbn: str
title: str
year: int
publisher_id: str
def to_response(book: Book) -> BookResponse:
response: BookResponse = BookResponse(
id=book.id,
created_date=book.created_date,
last_modified_date=book.last_modified_date,
version=book.version,
isbn=book.isbn,
title=book.title,
year=book.year,
publisher_id=book.publisher_id
)
return response
@@ -0,0 +1,25 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.bookshelf import BookAuthor
class BookAuthorResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
author_id: str
book_id: str
def to_response(bookauthor: BookAuthor) -> BookAuthorResponse:
response: BookAuthorResponse = BookAuthorResponse(
id=bookauthor.id,
created_date=bookauthor.created_date,
last_modified_date=bookauthor.last_modified_date,
version=bookauthor.version,
author_id=bookauthor.author_id,
book_id=bookauthor.book_id
)
return response
@@ -0,0 +1,23 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.bookshelf import BookshelfPublisher
class PublisherResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
def to_response(publisher: BookshelfPublisher) -> PublisherResponse:
response: PublisherResponse = PublisherResponse(
id=publisher.id,
created_date=publisher.created_date,
last_modified_date=publisher.last_modified_date,
version=publisher.version,
name=publisher.name
)
return response
+35
View File
@@ -0,0 +1,35 @@
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
from src.db.models.comic import Artist
class ArtistCreation(BaseModel):
id: str
name: str
class ArtistResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
weblink: Optional[str]
def artist_to_response(artist: Artist) -> ArtistResponse:
response: ArtistResponse = ArtistResponse(
id=artist.id,
created_date=artist.created_date,
last_modified_date=artist.last_modified_date,
version=artist.version,
name=artist.name,
weblink=artist.weblink
)
return response
class AddArtist(BaseModel):
id: str
name: str
@@ -0,0 +1,22 @@
from typing import List
from pydantic import BaseModel
from src.schema.comics.comic import ComicResponse
from src.schema.comics.issue_details import IssueDetailsResponse
from src.schema.comics.worktype import WorktypeResponse
class ArtistWorktypeComicResponse(BaseModel):
worktype: WorktypeResponse
comics: List[ComicResponse]
class ArtistWorktypeIssueResponse(BaseModel):
worktype: WorktypeResponse
issues: List[IssueDetailsResponse]
class ArtistDetailResponse(BaseModel):
id: str
name: str
weblink: str
comic_works: List[ArtistWorktypeComicResponse]
issue_works: List[ArtistWorktypeIssueResponse]
+48
View File
@@ -0,0 +1,48 @@
"""
Schema definitions for Comics.
"""
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, AnyUrl
from src.db.models.comic import Comic
class ComicResponse(BaseModel):
"""
Pydantic model for returning Comic objects.
"""
id: str
created_date: datetime
last_modified_date: datetime
version: int
title: str
publisher_id: str
current_order: bool
completed: bool
weblink: Optional[str]
def comic_to_response(comic: Comic) -> ComicResponse:
response: ComicResponse = ComicResponse(
id=comic.id,
created_date=comic.created_date,
last_modified_date=comic.last_modified_date,
version=comic.version,
title=comic.title,
publisher_id=comic.publisher_id,
current_order=comic.current_order,
completed=comic.completed,
weblink=comic.weblink
)
return response
class ComicSchema(BaseModel):
"""
Pydantic model for uploading Comic object.
"""
id: str
title: str
weblink: Optional[AnyUrl]
completed: Optional[bool]
current_order: Optional[bool]
@@ -0,0 +1,26 @@
from typing import List
from pydantic import BaseModel
from src.schema.comics.artist import ArtistResponse
from src.schema.comics.issue import IssueResponse
from src.schema.comics.publisher import PublisherResponse
from src.schema.comics.volume import VolumeResponse
from src.schema.comics.worktype import WorktypeResponse
class ComicWorktypeArtistResponse(BaseModel):
worktype: WorktypeResponse
artists: List[ArtistResponse]
class ComicDetailsResponse(BaseModel):
id: str
created: str
title: str
completed : bool
current_order : bool
weblink: str
publisher: PublisherResponse
issues: List[IssueResponse]
volumes: List[VolumeResponse]
works: List[ComicWorktypeArtistResponse]
+32
View File
@@ -0,0 +1,32 @@
"""
Model definitions for ComicWork.
"""
from datetime import datetime
from pydantic import BaseModel
from src.db.models.comic import ComicWork
class ComicWorkResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
comic_id: str
artist_id: str
work_type_id: str
def comicwork_to_response(comicwork: ComicWork) -> ComicWorkResponse:
response: ComicWorkResponse = ComicWorkResponse(
id=comicwork.id,
created_date=comicwork.created_date,
last_modified_date=comicwork.last_modified_date,
version=comicwork.version,
comic_id=comicwork.comic_id,
artist_id=comicwork.artist_id,
work_type_id=comicwork.work_type_id,
)
return response
+38
View File
@@ -0,0 +1,38 @@
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
from src.db.models.comic import Issue
class IssueResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
issue_number: str
title: Optional[str]
published_on: Optional[datetime]
in_stock: bool
is_read: bool
comic_id: str
volume_id: Optional[str]
story_arc_id: Optional[str]
def issue_to_response(issue: Issue) -> IssueResponse:
response: IssueResponse = IssueResponse(
id=issue.id,
created_date=issue.created_date,
last_modified_date=issue.last_modified_date,
version=issue.version,
issue_number=issue.issue_number,
title=issue.title,
published_on=issue.published_on,
in_stock=issue.in_stock,
is_read=issue.is_read,
comic_id=issue.comic_id,
volume_id=issue.volume_id,
story_arc_id=issue.story_arc_id
)
return response
@@ -0,0 +1,14 @@
from pydantic import BaseModel
from src.schema.comics.comic import ComicResponse
from src.schema.comics.volume import VolumeResponse
class IssueDetailsResponse(BaseModel):
id: str
issue_number: str
in_stock: bool
is_read: bool
comic: ComicResponse
volume: VolumeResponse | None
+32
View File
@@ -0,0 +1,32 @@
"""
Model definitions for IssueWork.
"""
from datetime import datetime
from pydantic import BaseModel
from src.db.models.comic import IssueWork
class IssueWorkResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
issue_id: str
artist_id: str
work_type_id: str
def issuework_to_response(issuework: IssueWork) -> IssueWorkResponse:
response: IssueWorkResponse = IssueWorkResponse(
id=issuework.id,
created_date=issuework.created_date,
last_modified_date=issuework.last_modified_date,
version=issuework.version,
issue_id=issuework.issue_id,
artist_id=issuework.artist_id,
work_type_id=issuework.work_type_id,
)
return response
+30
View File
@@ -0,0 +1,30 @@
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
from src.db.models.comic import Publisher
class PublisherResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
weblink: Optional[str]
parent_publisher_id: Optional[str]
def publisher_to_response(publisher: Publisher) -> PublisherResponse:
response: PublisherResponse = PublisherResponse(
id=publisher.id,
created_date=publisher.created_date,
last_modified_date=publisher.last_modified_date,
version=publisher.version,
name=publisher.name,
weblink=publisher.weblink,
parent_publisher_id=publisher.parent_publisher_id
)
return response
@@ -0,0 +1,14 @@
from typing import List
from pydantic import BaseModel
from src.schema.comics.comic import ComicResponse
from src.schema.comics.publisher import PublisherResponse
class PublisherDetailsResponse(BaseModel):
id: str
name: str
parent_publisher: PublisherResponse | None
imprints: List[PublisherResponse]
comics: List[ComicResponse]
+30
View File
@@ -0,0 +1,30 @@
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
from src.db.models.comic import StoryArc
class StoryArcResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
comic_id: str
volume_id: Optional[str]
class AddLink(BaseModel):
url: str
def storyarc_to_response(storyarc: StoryArc) -> StoryArcResponse:
response: StoryArcResponse = StoryArcResponse(
id=storyarc.id,
created_date=storyarc.created_date,
last_modified_date=storyarc.last_modified_date,
version=storyarc.version,
name=storyarc.name,
comic_id=storyarc.comic_id,
volume_id=storyarc.volume_id
)
return response
+25
View File
@@ -0,0 +1,25 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.comic import Volume
class VolumeResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
comic_id: str
def volume_to_response(volume: Volume) -> VolumeResponse:
response: VolumeResponse = VolumeResponse(
id=volume.id,
created_date=volume.created_date,
last_modified_date=volume.last_modified_date,
version=volume.version,
name=volume.name,
comic_id=volume.comic_id
)
return response
+26
View File
@@ -0,0 +1,26 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.comic import WorkType
class AddWorkType(BaseModel):
worktype: str
class WorktypeResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
def worktype_to_response(worktype: WorkType) -> WorktypeResponse:
response: WorktypeResponse = WorktypeResponse(
id=worktype.id,
created_date=worktype.created_date,
last_modified_date=worktype.last_modified_date,
version=worktype.version,
name=worktype.name
)
return response
+34
View File
@@ -0,0 +1,34 @@
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
from src.db.models.media import MediaActor
class MediaActorResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: Optional[str]
url: Optional[str]
def actor_to_response(actor: MediaActor) -> MediaActorResponse:
response: MediaActorResponse = MediaActorResponse(
id=actor.id,
created_date=actor.created_date,
last_modified_date=actor.last_modified_date,
version=actor.version,
name=actor.name,
url=actor.url
)
return response
class MediaActorModel(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: Optional[str]
url: Optional[str]
+35
View File
@@ -0,0 +1,35 @@
from datetime import datetime
from typing import Optional
from src.db.models.media import MediaActorFile
from pydantic import BaseModel
class MediaActorFileResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
media_actor_id: str
media_file_id: Optional[str]
def actorfile_to_response(actorfile: MediaActorFile) -> MediaActorFileResponse:
response: MediaActorFileResponse = MediaActorFileResponse(
id=actorfile.id,
created_date=actorfile.created_date,
last_modified_date=actorfile.last_modified_date,
version=actorfile.version,
media_actor_id=actorfile.media_actor_id,
media_file_id=actorfile.media_file_id
)
return response
class MediaActorFileModel(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
media_actor_id: str
media_file_id: Optional[str]
+30
View File
@@ -0,0 +1,30 @@
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
from src.db.models.media import MediaArticle
class MediaArticleResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
review: bool = False
title: Optional[str] = None
url: Optional[str] = None
class AddLink(BaseModel):
url: str
def to_response(video: MediaArticle) -> MediaArticleResponse:
response: MediaArticleResponse = MediaArticleResponse(
id=video.id,
created_date=video.created_date,
last_modified_date=video.last_modified_date,
version=video.version,
review=video.review,
title=video.title,
url=video.url,
)
return response
+81
View File
@@ -0,0 +1,81 @@
from datetime import datetime
from typing import Optional
from src.db.models.media import MediaFile
from pydantic import BaseModel
class MediaFileResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
title: Optional[str]
file_name: Optional[str]
cloud_link: Optional[str]
url: Optional[str]
review: bool = False
should_download: bool = False
def file_to_response(mediafile: MediaFile) -> MediaFileResponse:
"""
Create MediaFileResponse from model.
"""
response: MediaFileResponse = MediaFileResponse(
id=mediafile.id,
created_date=mediafile.created_date,
last_modified_date=mediafile.last_modified_date,
version=mediafile.version,
title=mediafile.title,
file_name=mediafile.file_name,
cloud_link=mediafile.cloud_link,
url=mediafile.url,
review=mediafile.review,
should_download=mediafile.should_download,
)
return response
def file_to_model(model: MediaFileResponse, mediafile: MediaFile) -> MediaFile:
"""
Set data of response to model.
"""
mediafile.file_name = model.file_name
mediafile.cloud_link = model.cloud_link
if model.url is not None:
mediafile.url = model.url
else:
mediafile.url = ""
if model.title is not None:
mediafile.title = model.title
else:
mediafile.title = ""
mediafile.last_modified_date = datetime.now()
mediafile.review = model.review
mediafile.should_download = model.should_download
return mediafile
class MediaFileModel(BaseModel):
"""
Pydantic model to import MediaFile.
"""
id: str
created_date: Optional[datetime]
last_modified_date: Optional[datetime]
version: int = 0
title: Optional[str]
file_name: Optional[str]
cloud_link: Optional[str]
url: Optional[str]
review: bool = True
should_download: bool = True
class Link(BaseModel):
"""
PYdantic model for uploading url.
"""
url: str
+38
View File
@@ -0,0 +1,38 @@
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
from src.db.models.media import MediaVideo
class MediaVideoResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
cloud_link: Optional[str] = None
file_name: Optional[str] = None
path: Optional[str] = None
review: bool = False
title: Optional[str] = None
url: Optional[str] = None
should_download: bool = False
class AddLink(BaseModel):
url: str
def video_to_response(video: MediaVideo) -> MediaVideoResponse:
response: MediaVideoResponse = MediaVideoResponse(
id=video.id,
created_date=video.created_date,
last_modified_date=video.last_modified_date,
version=video.version,
cloud_link=video.cloud_link,
file_name=video.file_name,
path=video.path,
review=video.review,
title=video.title,
url=video.url,
should_download=video.should_download
)
return response
+31
View File
@@ -0,0 +1,31 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.tysc import Card
class CardResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
card_number: int
year: int
card_set_id: str
rooster_id: str
vendor_id: str
def to_response(card: Card) -> CardResponse:
response: CardResponse = CardResponse(
id=card.id,
created_date=card.created_date,
last_modified_date=card.last_modified_date,
version=card.version,
card_number=card.card_number,
year=card.year,
card_set_id=card.card_set_id,
rooster_id=card.rooster_id,
vendor_id=card.vendor_id
)
return response
+30
View File
@@ -0,0 +1,30 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.tysc import CardSet
class CardSetResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
parallel_set: bool
insert_set: bool
vendor_id: str
def to_response(cardset: CardSet) -> CardSetResponse:
response: CardSetResponse = CardSetResponse(
id=cardset.id,
created_date=cardset.created_date,
last_modified_date=cardset.last_modified_date,
version=cardset.version,
name=cardset.name,
parallel_set=cardset.parallel_set,
insert_set=cardset.insert_set,
vendor_id=cardset.vendor_id
)
return response
@@ -0,0 +1,28 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.tysc import FieldPosition
class FieldPositionResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
short_name: str
sport_id: str
def to_response(fieldposition: FieldPosition) -> FieldPositionResponse:
response: FieldPositionResponse = FieldPositionResponse(
id=fieldposition.id,
created_date=fieldposition.created_date,
last_modified_date=fieldposition.last_modified_date,
version=fieldposition.version,
name=fieldposition.name,
short_name=fieldposition.short_name,
sport_id=fieldposition.sport_id
)
return response
+25
View File
@@ -0,0 +1,25 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.tysc import Player
class PlayerResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
first_name: str
last_name: str
def to_response(player: Player) -> PlayerResponse:
response: PlayerResponse = PlayerResponse(
id=player.id,
created_date=player.created_date,
last_modified_date=player.last_modified_date,
version=player.version,
first_name=player.first_name,
last_name=player.last_name
)
return response
+36
View File
@@ -0,0 +1,36 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.tysc import Rooster
class RoosterResponse(BaseModel):
"""
Pydantic model for returning Rooster objects.
"""
id: str
created_date: datetime
last_modified_date: datetime
version: int
year: int
team_id: str
player_id: str
position_id: str
def to_response(rooster: Rooster) -> RoosterResponse:
"""
convert database object to response object (Pydantic).
"""
response: RoosterResponse = RoosterResponse(
id=rooster.id,
created_date=rooster.created_date,
last_modified_date=rooster.last_modified_date,
version=rooster.version,
year=rooster.year,
team_id=rooster.team_id,
player_id=rooster.player_id,
position_id=rooster.position_id
)
return response
+24
View File
@@ -0,0 +1,24 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.tysc import Sport
class SportResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
def to_response(sport: Sport) -> SportResponse:
response: SportResponse = SportResponse(
id=sport.id,
created_date=sport.created_date,
last_modified_date=sport.last_modified_date,
version=sport.version,
name=sport.name
)
return response
+28
View File
@@ -0,0 +1,28 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.tysc import Team
class TeamResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
name: str
short_name: str
sport_id: str
def to_response(team: Team) -> TeamResponse:
response: TeamResponse = TeamResponse(
id=team.id,
created_date=team.created_date,
last_modified_date=team.last_modified_date,
version=team.version,
name=team.name,
short_name=team.short_name,
sport_id=team.sport_id
)
return response

Some files were not shown because too many files have changed in this diff Show More