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
1265 changed files with 196137 additions and 47054 deletions
-19
View File
@@ -1,19 +0,0 @@
name: Gitea Actions Demo
run-name: ${{ gitea.actor }} ist testing out Gitea Actions
on:
push:
branches:
- develop/0.4.0
jobs:
build-and-test:
runs-on: inky
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: List files in the directory
run: |
cd ${{ gitea.workspace }}/kontor-gin
go build -o /home/tpeetz/prod/kontor cmd/kontor/main.go
- name: List files in the directory
run: echo "The job's status is ${{ job.status }}."
-1
View File
@@ -11,4 +11,3 @@ kontor-robyn.bak
kontor-robyn.bak2 kontor-robyn.bak2
kontor-data/.gradle kontor-data/.gradle
kontor-data/build/ kontor-data/build/
/kontor-api/kontor-api.code-workspace
-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.4.0
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
-13
View File
@@ -1,13 +0,0 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-angular:$kontorVersion"
buildah build -t kontor-angular:$kontorVersion kontor-angular
+3 -2
View File
@@ -1,7 +1,7 @@
## ------------------------------- Builder Stage ------------------------------ ## ## ------------------------------- Builder Stage ------------------------------ ##
FROM python:3.13-bookworm AS builder FROM python:3.13-bookworm AS builder
RUN apt-get update && apt-get install --no-install-recommends -y build-essential libpq-dev && \ RUN apt-get update && apt-get install --no-install-recommends -y build-essential && \
apt-get clean && rm -rf /var/lib/apt/lists/* apt-get clean && rm -rf /var/lib/apt/lists/*
# Download the latest installer, install it and then remove it # Download the latest installer, install it and then remove it
@@ -14,12 +14,13 @@ ENV PATH="/root/.local/bin:${PATH}"
WORKDIR /app WORKDIR /app
COPY ./pyproject.toml . COPY ./pyproject.toml .
RUN uv sync RUN uv sync
# ------------------------------- Production Stage ------------------------------ ## # ------------------------------- Production Stage ------------------------------ ##
FROM python:3.13-slim-bookworm AS production FROM python:3.13-slim-bookworm AS production
RUN apt-get update && apt-get install --no-install-recommends -y curl libpq-dev RUN apt-get update && apt-get install --no-install-recommends -y curl
WORKDIR /app WORKDIR /app
-13
View File
@@ -1,13 +0,0 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-api:$kontorVersion"
buildah build -t kontor-api:$kontorVersion kontor-api
+3 -4
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "kontor-api" name = "kontor-api"
version = "0.4.0" version = "0.1.0"
description = "Add your description here" description = "Add your description here"
readme = "README.md" readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.13"
@@ -15,6 +15,7 @@ dependencies = [
"pytest==7.4.0", "pytest==7.4.0",
"pyyaml>=6.0.2", "pyyaml>=6.0.2",
"requests>=2.32.3", "requests>=2.32.3",
"sqlalchemy>=2.0.40",
"sqlmodel>=0.0.24", "sqlmodel>=0.0.24",
"python-dotenv>=1.1.0", "python-dotenv>=1.1.0",
"python-jose[cryptography]>=3.4.0", "python-jose[cryptography]>=3.4.0",
@@ -23,12 +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",
"sqlalchemy>=2.0.52",
"pydantic[email]>=2.13.4",
"psycopg>=3.3.6",
] ]
-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",
+1 -23
View File
@@ -4,12 +4,7 @@ from fastapi import APIRouter, status, HTTPException
from src.core.log_conf import logger from src.core.log_conf import logger
from src.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 src.schema.media.actor import ( from src.schema.media.actor import MediaActorModel, MediaActorResponse, actor_to_response
MediaActorModel,
MediaActorResponse,
actor_to_response,
actor_to_model
)
from src.db.models.media import MediaActor from src.db.models.media import MediaActor
router = APIRouter() router = APIRouter()
@@ -31,23 +26,6 @@ def get_actor(actor_id: str, db: SessionDep) -> MediaActorResponse:
response = actor_to_response(media_actor) response = actor_to_response(media_actor)
return response return response
@router.put("/actors/{actor_id}", response_model=MediaActorResponse)
def update_actor(actor_id: str, db:SessionDep, info: MediaActorResponse) -> MediaActorResponse:
"""
Update MediaActor with given id and data.
"""
media_actor = db.get(MediaActor, actor_id)
if not media_actor:
raise HTTPException(status_code=404, detail="MediaActor could not be found")
actor_to_model(info, media_actor)
db.add(media_actor)
db.commit()
mediaactor = db.get(MediaActor, actor_id)
if not mediaactor:
raise HTTPException(status_code=404, detail="MediaActor could not be found")
response = actor_to_response(mediaactor)
return response
@router.delete("/actors/{actor_id}", status_code=status.HTTP_204_NO_CONTENT) @router.delete("/actors/{actor_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_actor(actor_id: str, db: SessionDep): def delete_actor(actor_id: str, db: SessionDep):
media_actor = db.get(MediaActor, actor_id) media_actor = db.get(MediaActor, actor_id)
@@ -1,91 +0,0 @@
from typing import List
from fastapi import APIRouter, status, HTTPException
from src.db.models.media import MediaLofi
from src.db.session import SessionDep
from src.core.log_conf import logger
from src.schema.media.lofi import (
MediaLofiModel,
MediaLofiResponse,
lofi_to_response,
lofi_to_model
)
from src.db.repository.media.lofi import (
import_medialofi,
delete_medialofi
)
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
@router.delete("/lofi/{lofi_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_lofi(lofi_id: str, db: SessionDep):
"""
Delete MediaFile by given id.
"""
lofi = db.get(MediaLofi, lofi_id)
if not lofi:
raise HTTPException(status_code=404, detail="MediaLofi could not be found")
logger.info("delete MediaLofi: %s", lofi_id)
delete_medialofi(db=db, lofi_id=lofi.id)
@router.put("/lofi/{lofi_id}", response_model=MediaLofiResponse)
def update_lofi(lofi_id: str, db: SessionDep, info: MediaLofiResponse) -> MediaLofiResponse:
"""
Update MediaLofi with given id and data.
"""
media_lofi = db.get(MediaLofi, lofi_id)
if not media_lofi:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="MediaLofi could not be found")
lofi_to_model(info, media_lofi)
db.add(media_lofi)
db.commit()
media_lofi = db.get(MediaLofi, lofi_id)
if not media_lofi:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="MediaLofi could not be found")
response = lofi_to_response(media_lofi)
return response
@router.post("/lofi", status_code=status.HTTP_201_CREATED)
def add_lofi(new_lofi: MediaLofiModel, db: SessionDep) -> MediaLofiResponse:
logger.info("add medialofi %s", new_lofi)
try:
medialofi: MediaLofi = import_medialofi(db, new_lofi)
except:
raise HTTPException(status_code=409, detail="MediaLofi duplicate")
response = lofi_to_response(medialofi)
return response
+4 -8
View File
@@ -9,21 +9,17 @@ load_dotenv(dotenv_path=env_path)
class Settings: class Settings:
PROJECT_NAME: str = "Kontor" PROJECT_NAME: str = "Kontor"
PROJECT_VERSION: str = "0.4.0" PROJECT_VERSION: str = "0.3.0"
DB_USER: str = os.getenv("DB_USER", "kontor") DB_USER: str = os.getenv("DB_USER", "kontor")
DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor") DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor")
DB_SERVER: str = os.getenv("DB_SERVER", "postgres") DB_SERVER: str = os.getenv("DB_SERVER", "postgres")
DB_PORT: int = int(os.getenv("DB_PORT", 5432)) DB_PORT: int = int(os.getenv("DB_PORT", 5432))
DB_DBNAME: str = os.getenv("DB_DBNAME", "kontor") DB_DBNAME: str = os.getenv("DB_DBNAME", "kontor")
DATABASE_URL: str = ( DATABASE_URL: str = f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}"
f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}" SECRET_KEY: str = os.getenv("SECRET_KEY", "J6GOtcwC2NJI1l0VkHu20PacPFGTxpirBxWwynoHjsc=")
)
SECRET_KEY: str = os.getenv(
"SECRET_KEY", "J6GOtcwC2NJI1l0VkHu20PacPFGTxpirBxWwynoHjsc="
)
ALGORITHM = "HS256" ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60*24*7 # one week in mins ACCESS_TOKEN_EXPIRE_MINUTES = 60*24*7 # one week in mins
settings = Settings() settings = Settings()
+1 -1
View File
@@ -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
-86
View File
@@ -1,86 +0,0 @@
from typing import Any, Dict
from src.db.models.admin import (
Assignment,
Token,
Profile,
Permission,
MailAccount,
Mail,
)
from src.db.models.bookshelf import (
ArticleAuthor,
BookAuthor,
BookshelfPublisher,
Article,
Book,
Author,
)
from src.db.models.comic import (
Issue,
StoryArc,
TradePaperback,
Volume,
ComicWork,
IssueWork,
Artist,
Comic,
Publisher,
WorkType,
)
from src.db.models.media import (
MediaFile,
MediaActor,
MediaActorFile,
MediaArticle,
MediaVideo,
MediaLofi,
)
from src.db.models.tysc import (
Card,
CardSet,
Rooster,
Team,
FieldPosition,
Player,
Vendor,
Sport,
)
registry: Dict[str, Any] = {
Sport.__tablename__: Sport,
Player.__tablename__: Player,
Team.__tablename__: Team,
FieldPosition.__tablename__: FieldPosition,
Rooster.__tablename__: Rooster,
Vendor.__tablename__: Vendor,
CardSet.__tablename__: CardSet,
Card.__tablename__: Card,
Artist.__tablename__: Artist,
Publisher.__tablename__: Publisher,
WorkType.__tablename__: WorkType,
Comic.__tablename__: Comic,
Volume.__tablename__: Volume,
StoryArc.__tablename__: StoryArc,
Issue.__tablename__: Issue,
TradePaperback.__tablename__: TradePaperback,
ComicWork.__tablename__: ComicWork,
IssueWork.__tablename__: IssueWork,
Article.__tablename__: Article,
BookshelfPublisher.__tablename__: BookshelfPublisher,
Book.__tablename__: Book,
Author.__tablename__: Author,
ArticleAuthor.__tablename__: ArticleAuthor,
BookAuthor.__tablename__: BookAuthor,
MediaArticle.__tablename__: MediaArticle,
MediaVideo.__tablename__: MediaVideo,
MediaLofi.__tablename__: MediaLofi,
MediaFile.__tablename__: MediaFile,
MediaActor.__tablename__: MediaActor,
MediaActorFile.__tablename__: MediaActorFile,
Profile.__tablename__: Profile,
Permission.__tablename__: Permission,
Assignment.__tablename__: Assignment,
Token.__tablename__: Token,
MailAccount.__tablename__: MailAccount,
Mail.__tablename__: Mail
}
+35 -165
View File
@@ -1,7 +1,7 @@
from datetime import datetime from datetime import datetime
from typing import Any, Dict from typing import List
from sqlalchemy import Column, ForeignKey, Integer, String, Boolean from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, mapped_column, Mapped from sqlalchemy.orm import relationship, mapped_column, Mapped
from src.db.models.base import Base, BaseMixin from src.db.models.base import Base, BaseMixin
@@ -9,14 +9,14 @@ from src.db.models.base import Base, BaseMixin
class Profile(Base, BaseMixin): class Profile(Base, BaseMixin):
__tablename__ = 'profile' __tablename__ = 'profile'
first_name = Column(String) first_name: Mapped[str]
last_name = Column(String) last_name: Mapped[str]
user_name = Column(String, nullable=False) user_name: Mapped[str] = mapped_column(nullable=False)
email = Column(String) email: Mapped[str]
password = Column(String) password: Mapped[str]
enabled = Column(Boolean) enabled: Mapped[bool]
assignments = relationship("Assignment") assignments: Mapped[List["Assignment"]] = relationship(back_populates="profile")
tokens = relationship("Token") tokens: Mapped[List["Token"]] = relationship(back_populates="profile")
def get_full_name(self) -> str: def get_full_name(self) -> str:
full_name: str = "" full_name: str = ""
@@ -28,178 +28,48 @@ class Profile(Base, BaseMixin):
full_name += str(self.last_name) full_name += str(self.last_name)
return full_name return full_name
def import_dict(self, import_data: Dict[str, Any]): def __str__(self):
self.id = import_data['id'] return f"Profile({self.id} {self.user_name}, {self.email})"
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.first_name = import_data['first_name']
self.last_name = import_data['last_name']
self.user_name = import_data['user_name']
self.email = import_data['email']
self.password = import_data['password']
self.enabled = import_data['enabled']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['first_name'] = self.first_name
item['last_name'] = self.last_name
item['user_name'] = self.user_name
item['email'] = self.email
item['password'] = self.password
item['enabled'] = self.enabled
return item
class Token(Base, BaseMixin): class Token(Base, BaseMixin):
__tablename__ = "token" __tablename__ = "token"
token = Column(String, nullable=False, unique=True) token: Mapped[str] = mapped_column(nullable=False, unique=True)
name = Column(String) name: Mapped[str]
last_used_date: Mapped[datetime] = mapped_column() last_used_date: Mapped[datetime]
enabled = Column(Boolean) enabled: Mapped[bool]
profile_id = Column(String, ForeignKey("profile.id"), nullable=False) profile_id = mapped_column(ForeignKey("profile.id"), nullable=False)
profile = relationship("Profile", back_populates="tokens") profile: Mapped[Profile] = relationship(back_populates="tokens")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.token = import_data['token']
self.name = import_data['name']
self.last_used_date = import_data['last_used_date']
self.enabled = import_data['enabled']
self.profile_id = import_data['profile_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['token'] = self.token
item['name'] = self.name
item['last_used_date'] = self.last_used_date
item['enabled'] = self.enabled
item['profile_id'] = self.profile_id
return item
class Permission(Base, BaseMixin): class Permission(Base, BaseMixin):
__tablename__ = "permission" __tablename__ = "permission"
name = Column(String, nullable=False) name: Mapped[str] = mapped_column(nullable=False)
assignments = relationship("Assignment") assignments: Mapped[List["Assignment"]] = relationship(back_populates="permission")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
return item
class Assignment(Base, BaseMixin): class Assignment(Base, BaseMixin):
__tablename__ = "assignment" __tablename__ = "assignment"
profile_id = Column(String, ForeignKey("profile.id"), nullable=False) profile_id = mapped_column(ForeignKey("profile.id"), nullable=False)
profile = relationship("Profile", back_populates="assignments") profile: Mapped[Profile] = relationship(back_populates="assignments")
permission_id = Column(String, ForeignKey("permission.id"), nullable=False) permission_id = mapped_column(ForeignKey("permission.id"), nullable=False)
permission = relationship("Permission", back_populates="assignments") permission: Mapped[Permission] = relationship(back_populates="assignments")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.profile_id = import_data['profile_id']
self.permission_id = import_data['permission_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['profile_id'] = self.profile_id
item['permission_id'] = self.permission_id
return item
class MailAccount(Base, BaseMixin): class MailAccount(Base, BaseMixin):
__tablename__ = "mail_account" __tablename__ = "mail_account"
host = Column(String) host: Mapped[str]
port = Column(Integer) port: Mapped[int]
protocol = Column(String) protocol: Mapped[str]
user_name = Column(String) user_name: Mapped[str]
password = Column(String) password: Mapped[str]
start_tls = Column(Boolean) start_tls: Mapped[bool]
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.host = import_data['host']
self.port = import_data['port']
self.protocol = import_data['protocol']
self.user_name = import_data['user_name']
self.password = import_data['password']
self.start_tls = import_data['start_tls']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['host'] = self.host
item['port'] = self.port
item['protocol'] = self.protocol
item['user_name'] = self.user_name
item['password'] = self.password
item['start_tls'] = self.start_tls
return item
class Mail(Base, BaseMixin): class Mail(Base, BaseMixin):
__tablename__ = "mail" __tablename__ = "mail"
folder: Mapped[str] = mapped_column() folder: Mapped[str]
subject: Mapped[str] = mapped_column() subject: Mapped[str]
body: Mapped[str] = mapped_column() body: Mapped[str]
sent_date: Mapped[datetime] = mapped_column() sent_date: Mapped[datetime]
received_date: Mapped[datetime] = mapped_column() received_date: Mapped[datetime]
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.folder = import_data['folder']
self.subject = import_data['subject']
self.body = import_data['body']
self.sent_date = import_data['sent_date']
self.received_date = import_data['received_date']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['folder'] = self.folder
item['subject'] = self.subject
item['body'] = self.body
item['sent_date'] = str(self.sent_date)
item['received_date'] = str(self.received_date)
return item
+10 -13
View File
@@ -1,7 +1,8 @@
from typing import Optional
import uuid import uuid
from datetime import datetime from datetime import datetime
from sqlalchemy import func, Column, String, Boolean from sqlalchemy import func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
@@ -10,21 +11,17 @@ class Base(DeclarativeBase):
class BaseMixin: class BaseMixin:
#id = Column(String, primary_key=True, default=uuid.uuid4) id: Mapped[str] = mapped_column(primary_key=True, default=str(uuid.uuid4()))
id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4)
# created_date = Column(DateTime)
created_date: Mapped[datetime] = mapped_column(default=func.now()) created_date: Mapped[datetime] = mapped_column(default=func.now())
# last_modified_date = Column(DateTime)
last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) last_modified_date: Mapped[datetime] = mapped_column(default=func.now())
# version = Column(Integer)
version: Mapped[int] = mapped_column(default=0) version: Mapped[int] = mapped_column(default=0)
class BaseVideoMixin: class BaseVideoMixin:
cloud_link = Column(String, nullable=True) cloud_link: Mapped[Optional[str]]
file_name = Column(String, nullable=True) file_name: Mapped[Optional[str]]
path = Column(String) path: Mapped[str]
review = Column(Boolean) review: Mapped[bool]
title = Column(String) title: Mapped[str]
url = Column(String, nullable=True) url: Mapped[str]
should_download = Column(Boolean) should_download: Mapped[bool]
+24 -131
View File
@@ -1,159 +1,52 @@
from typing import Any, Dict from typing import List
from sqlalchemy import Column, ForeignKey, Integer, String from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.db.models.base import Base, BaseMixin from src.db.models.base import Base, BaseMixin
class Article(Base, BaseMixin): class Article(Base, BaseMixin):
__tablename__ = 'article' __tablename__ = 'article'
title = Column(String, unique=True) title: Mapped[str] = mapped_column(unique=True)
article_authors = relationship("ArticleAuthor") article_authors = relationship("ArticleAuthor")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.title = import_data['title']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['title'] = self.title
return item
class Author(Base, BaseMixin): class Author(Base, BaseMixin):
__tablename__ = 'author' __tablename__ = 'author'
first_name = Column(String) first_name: Mapped[str]
last_name = Column(String) last_name: Mapped[str]
article_authors = relationship("ArticleAuthor") article_authors: Mapped[List["ArticleAuthor"]] = relationship(back_populates="author")
book_authors = relationship("BookAuthor") book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="author")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.first_name = import_data['first_name']
self.last_name = import_data['last_name']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['first_name'] = self.first_name
item['last_name'] = self.last_name
return item
class BookshelfPublisher(Base, BaseMixin): class BookshelfPublisher(Base, BaseMixin):
__tablename__ = 'bookshelf_publisher' __tablename__ = 'bookshelf_publisher'
name = Column(String, unique=True) name: Mapped[str] = mapped_column(unique=True)
books = relationship("Book", back_populates="publisher") books: Mapped[List["Book"]] = relationship(back_populates="publisher")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
return item
class Book(Base, BaseMixin): class Book(Base, BaseMixin):
__tablename__ = 'book' __tablename__ = 'book'
isbn = Column(String, unique=True) isbn: Mapped[str] = mapped_column(unique=True)
title = Column(String) title: Mapped[str]
year = Column(Integer, nullable=False) year: Mapped[int] = mapped_column(nullable=False)
publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False) publisher_id: Mapped[str] = mapped_column(ForeignKey("bookshelf_publisher.id"), nullable=False)
publisher = relationship('BookshelfPublisher', back_populates="books") publisher: Mapped[BookshelfPublisher] = relationship(back_populates="books")
book_authors = relationship("BookAuthor") book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="book")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.isbn = import_data['isbn']
self.title = import_data['title']
self.year = import_data['year']
self.publisher_id = import_data['publisher_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['isbn'] = self.isbn
item['title'] = self.title
item['year'] = self.year
item['publisher_id'] = self.publisher_id
return item
class ArticleAuthor(Base, BaseMixin): class ArticleAuthor(Base, BaseMixin):
__tablename__ = 'article_author' __tablename__ = 'article_author'
article_id = Column(String, ForeignKey('article.id'), nullable=False) article_id: Mapped[str] = mapped_column(ForeignKey("article.id"), nullable=False)
article = relationship('Article', back_populates="article_authors") article: Mapped[Article] = relationship(back_populates="article_authors")
author_id = Column(String, ForeignKey('author.id'), nullable=False) author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False)
author = relationship('Author', back_populates="article_authors") author: Mapped[Author] = relationship(back_populates="article_authors")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.article_id = import_data['article_id']
self.author_id = import_data['author_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['article_id'] = self.article_id
item['author_id'] = self.author_id
return item
class BookAuthor(Base, BaseMixin): class BookAuthor(Base, BaseMixin):
__tablename__ = 'book_author' __tablename__ = 'book_author'
author_id = Column(String, ForeignKey('author.id'), nullable=False) author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False)
author = relationship('Author', back_populates="book_authors") author: Mapped[Author] = relationship(back_populates="book_authors")
book_id = Column(String, ForeignKey('book.id'), nullable=False) book_id: Mapped[str] = mapped_column(ForeignKey("book.id"), nullable=False)
book = relationship('Book', back_populates="book_authors") book: Mapped[Book] = relationship(back_populates="book_authors")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.author_id = import_data['author_id']
self.book_id = import_data['book_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['author_id'] = self.author_id
item['book_id'] = self.book_id
return item
+114 -278
View File
@@ -1,7 +1,8 @@
import uuid import uuid
from datetime import datetime from datetime import datetime
from typing import Dict, List, Optional, Any from typing import Dict, List, Optional, Any
from sqlalchemy import Column, ForeignKey, Integer, String, Boolean, func from natsort import natsorted
from sqlalchemy import ForeignKey, func
from sqlalchemy.orm import relationship, Mapped, mapped_column from sqlalchemy.orm import relationship, Mapped, mapped_column
from src.db.models.base import Base, BaseMixin from src.db.models.base import Base, BaseMixin
@@ -13,12 +14,12 @@ class Publisher(Base):
created_date: Mapped[datetime] = mapped_column(default=func.now()) created_date: Mapped[datetime] = mapped_column(default=func.now())
last_modified_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) version: Mapped[int] = mapped_column(default=0)
name = Column(String, unique=True) name: Mapped[str] = mapped_column(unique=True)
weblink = Column(String, nullable=True) weblink: Mapped[Optional[str]]
parent_publisher_id: Mapped[Optional[str]] = mapped_column(ForeignKey('publisher.id')) parent_publisher_id: Mapped[Optional[str]] = mapped_column(ForeignKey('publisher.id'))
parent_publisher: Mapped[Optional['Publisher']] = relationship("Publisher", back_populates="imprints", remote_side=[id]) parent_publisher: Mapped[Optional['Publisher']] = relationship(back_populates="imprints", remote_side=[id])
imprints: Mapped[List['Publisher']] = relationship('Publisher', back_populates="parent_publisher") imprints: Mapped[List['Publisher']] = relationship(back_populates="parent_publisher")
comics = relationship("Comic") comics: Mapped[List["Comic"]] = relationship(back_populates="publisher")
def __repr__(self): def __repr__(self):
return f'Publisher({self.id} {self.name})' return f'Publisher({self.id} {self.name})'
@@ -26,40 +27,20 @@ class Publisher(Base):
def __str__(self): def __str__(self):
return self.__repr__() return self.__repr__()
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.parent_publisher_id = import_data['parent_publisher_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {
'id': self.id,
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'name': self.name,
'weblink': self.weblink,
'parent_publisher_id': self.parent_publisher_id
}
return item
class Comic(Base, BaseMixin): class Comic(Base, BaseMixin):
__tablename__ = 'comic' __tablename__ = 'comic'
title = Column(String, unique=True) title: Mapped[str] = mapped_column(unique=True)
publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) publisher_id: Mapped[str] = mapped_column(ForeignKey('publisher.id'), nullable=False)
publisher = relationship("Publisher", back_populates="comics") publisher: Mapped[Publisher] = relationship(back_populates="comics")
current_order = Column(Boolean) current_order: Mapped[bool]
completed = Column(Boolean) completed: Mapped[bool]
weblink = Column(String, nullable=True) weblink: Mapped[Optional[str]]
issues = relationship("Issue") issues: Mapped[List["Issue"]] = relationship(back_populates="comic", order_by="Issue.issue_number")
story_arcs = relationship("StoryArc") story_arcs: Mapped[List["StoryArc"]] = relationship(back_populates="comic")
trade_paperbacks = relationship("TradePaperback") trade_paperbacks: Mapped[List["TradePaperback"]] = relationship(back_populates="comic")
volumes = relationship("Volume") volumes: Mapped[List["Volume"]] = relationship(back_populates="comic")
comic_works = relationship("ComicWork") comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="comic")
def __repr__(self): def __repr__(self):
return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})' return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})'
@@ -67,204 +48,118 @@ class Comic(Base, BaseMixin):
def __str__(self): def __str__(self):
return f'{self.title}({self.id})' return f'{self.title}({self.id})'
def import_dict(self, import_data: Dict[str, Any]): def get_artists(self) -> Dict[Any, List[Any]]:
self.id = import_data['id'] works: Dict[Any, List[Any]] = {}
self.created_date = import_data['created_date'] for work in self.comic_works:
self.last_modified_date = import_data['last_modified_date'] work_type = work.work_type
self.version = import_data['version'] artist = work.artist
self.title = import_data['title'] if work_type in works:
self.publisher_id = import_data['publisher_id'] works[work_type].append(artist)
self.current_order = import_data['current_order'] else:
self.completed = import_data['completed'] works[work_type] = [artist]
if 'weblink' in import_data: return works
self.weblink = import_data['weblink']
def export_dict(self) -> Dict[str, Any]: def sorted_issues(self):
item: Dict[str, Any] = { sorted_issues = natsorted(self.issues, key=lambda x: getattr(x, 'issue_number'))
'id': self.id, return sorted_issues
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'title': self.title,
'publisher_id': self.publisher_id,
'current_order': self.current_order,
'completed': self.completed,
'weblink': self.weblink
}
return item
class Volume(Base, BaseMixin): class Volume(Base, BaseMixin):
__tablename__ = "volume" __tablename__ = "volume"
name = Column(String, nullable=False) name: Mapped[str] = mapped_column(nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="volumes") comic: Mapped[Comic] = relationship(back_populates="volumes")
story_arcs = relationship("StoryArc") story_arcs: Mapped[List["StoryArc"]] = relationship(back_populates="volume")
issues = relationship("Issue") issues: Mapped[List["Issue"]] = relationship(back_populates="volume")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.comic_id = import_data['comic_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
item['comic_id'] = self.comic_id
return item
class TradePaperback(Base, BaseMixin): class TradePaperback(Base, BaseMixin):
__tablename__ = "trade_paperback" __tablename__ = "trade_paperback"
name = Column(String, nullable=False) name: Mapped[str] = mapped_column(nullable=False)
issue_start = Column(Integer) issue_start: Mapped[int]
issue_end = Column(Integer) issue_end: Mapped[int]
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="trade_paperbacks") comic: Mapped[Comic] = relationship(back_populates="trade_paperbacks")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.issue_start = import_data['issue_start']
self.issue_end = import_data['issue_end']
self.comic_id = import_data['comic_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
item['issue_start'] = self.issue_start
item['issue_end'] = self.issue_end
item['comic_id'] = self.comic_id
return item
class StoryArc(Base, BaseMixin): class StoryArc(Base, BaseMixin):
__tablename__ = "story_arc" __tablename__ = "story_arc"
name = Column(String, nullable=False) name: Mapped[str] = mapped_column(nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="story_arcs") comic: Mapped[Comic] = relationship(back_populates="story_arcs")
volume_id = Column(String, ForeignKey("volume.id"), nullable=True) volume_id: Mapped[str] = mapped_column(ForeignKey("volume.id"), nullable=True)
volume = relationship("Volume", back_populates="story_arcs") volume: Mapped[Volume] = relationship(back_populates="story_arcs")
issues = relationship("Issue") issues: Mapped[List["Issue"]] = relationship(back_populates="story_arc")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.comic_id = import_data['comic_id']
self.volume_id = import_data['volume_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {
'id': self.id,
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'name': self.name,
'comic_id': self.comic_id,
'volume_id': self.volume_id
}
return item
class Issue(Base, BaseMixin): class Issue(Base, BaseMixin):
__tablename__ = "issue" __tablename__ = "issue"
issue_number = Column(String) issue_number: Mapped[str]
title = Column(String, nullable=True) title: Mapped[Optional[str]]
published_on: Mapped[datetime] = mapped_column(nullable=True) published_on: Mapped[Optional[datetime]]
in_stock = Column(Boolean) in_stock: Mapped[bool]
is_read = Column(Boolean) is_read: Mapped[bool]
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="issues") comic: Mapped[Comic] = relationship(back_populates="issues")
volume_id = Column(String, ForeignKey("volume.id"), nullable=True) volume_id: Mapped[str] = mapped_column(ForeignKey("volume.id"), nullable=True)
volume = relationship("Volume", back_populates="issues") volume: Mapped[Volume] = relationship(back_populates="issues")
story_arc_id = Column(String, ForeignKey("story_arc.id"), nullable=True) story_arc_id: Mapped[str] = mapped_column(ForeignKey("story_arc.id"), nullable=True)
story_arc = relationship("StoryArc", back_populates="issues") story_arc: Mapped[StoryArc] = relationship(back_populates="issues")
issue_works = relationship("IssueWork") issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="issue")
def import_dict(self, import_data: Dict[str, Any]): def get_full_title(self) -> str:
self.id = import_data['id'] full_title: str = str(self.issue_number)
self.created_date = import_data['created_date'] if self.title:
self.last_modified_date = import_data['last_modified_date'] full_title += str(": " + self.title)
self.version = import_data['version'] return full_title
self.issue_number = import_data['issue_number']
self.title = import_data['title'] def get_artists(self) -> Dict[Any, List[Any]]:
if import_data['published_on'] == 'None': works: Dict[Any, List[Any]] = {}
self.published_on = None # type: ignore 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: else:
self.published_on = import_data['published_on'] works[work_type] = [artist]
self.in_stock = import_data['in_stock'] return works
self.is_read = import_data['is_read']
self.comic_id = import_data['comic_id']
self.volume_id = import_data['volume_id']
self.story_arc_id = import_data['story_arc_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {
'id': self.id,
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'issue_number': self.issue_number,
'title': self.title,
'published_on': str(self.published_on),
'in_stock': self.in_stock,
'is_read': self.is_read,
'comic_id': self.comic_id,
'volume_id': self.volume_id,
'story_arc_id': self.story_arc_id
}
return item
class Artist(Base, BaseMixin): class Artist(Base, BaseMixin):
__tablename__ = "artist" __tablename__ = "artist"
name = Column(String, nullable=False) name: Mapped[str] = mapped_column(nullable=False)
weblink = Column(String, nullable=True) weblink: Mapped[str] = mapped_column(nullable=True)
comic_works = relationship("ComicWork") comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="artist")
issue_works = relationship("IssueWork") issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="artist")
def import_dict(self, import_data: Dict[str, Any]): def get_comics(self) -> Dict[Any, List[Comic]]:
self.id = import_data['id'] works: Dict[Any, List[Comic]] = {}
self.created_date = import_data['created_date'] for work in self.comic_works:
self.last_modified_date = import_data['last_modified_date'] work_type = work.work_type
self.version = import_data['version'] comic = work.comic
self.name = import_data['name'] if work_type in works:
if 'weblink' in import_data: works[work_type].append(comic)
self.weblink = import_data['weblink'] else:
works[work_type] = [comic]
def export_dict(self) -> Dict[str, Any]: return works
item: Dict[str, Any] = {
'id': self.id,
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'name': self.name,
'weblink': self.weblink
}
return item
class WorkType(Base, BaseMixin): class WorkType(Base, BaseMixin):
__tablename__ = "worktype" __tablename__ = "worktype"
name = Column(String, nullable=False, unique=True) name: Mapped[str] = mapped_column(nullable=False, unique=True)
comic_works = relationship("ComicWork") comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="work_type")
issue_works = relationship("IssueWork") 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): def __repr__(self):
return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})' return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})'
@@ -272,81 +167,22 @@ class WorkType(Base, BaseMixin):
def __str__(self): def __str__(self):
return f'{self.name}({self.id})' return f'{self.name}({self.id})'
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {
'id': self.id,
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'name': self.name
}
return item
class ComicWork(Base, BaseMixin): class ComicWork(Base, BaseMixin):
__tablename__ = "comic_work" __tablename__ = "comic_work"
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="comic_works") comic: Mapped[Comic] = relationship(back_populates="comic_works")
artist_id = Column(String, ForeignKey("artist.id"), nullable=False) artist_id: Mapped[str] = mapped_column(ForeignKey("artist.id"), nullable=False)
artist = relationship("Artist", back_populates="comic_works") artist: Mapped[Artist] = relationship(back_populates="comic_works")
work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) work_type_id: Mapped[str] = mapped_column(ForeignKey("worktype.id"), nullable=False)
work_type = relationship("WorkType", back_populates="comic_works") work_type: Mapped[WorkType] = relationship(back_populates="comic_works")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.comic_id = import_data['comic_id']
self.artist_id = import_data['artist_id']
self.work_type_id = import_data['work_type_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {
'id': self.id,
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'comic_id': self.comic_id,
'artist_id': self.artist_id,
'work_type_id': self.work_type_id
}
return item
class IssueWork(Base, BaseMixin): class IssueWork(Base, BaseMixin):
__tablename__ = "issue_work" __tablename__ = "issue_work"
issue_id = Column(String, ForeignKey("issue.id"), nullable=False) issue_id: Mapped[str] = mapped_column(ForeignKey("issue.id"), nullable=False)
issue = relationship("Issue", back_populates="issue_works") issue: Mapped[Issue] = relationship(back_populates="issue_works")
artist_id = Column(String, ForeignKey("artist.id"), nullable=False) artist_id: Mapped[str] = mapped_column(ForeignKey("artist.id"), nullable=False)
artist = relationship("Artist", back_populates="issue_works") artist: Mapped[Artist] = relationship(back_populates="issue_works")
work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) work_type_id: Mapped[str] = mapped_column(ForeignKey("worktype.id"), nullable=False)
work_type = relationship("WorkType", back_populates="issue_works") work_type: Mapped[WorkType] = relationship(back_populates="issue_works")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.issue_id = import_data['issue_id']
self.artist_id = import_data['artist_id']
self.work_type_id = import_data['work_type_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {
'id': self.id,
'created_date': str(self.created_date),
'last_modified_date': str(self.last_modified_date),
'version': self.version,
'issue_id': self.issue_id,
'artist_id': self.artist_id,
'work_type_id': self.work_type_id
}
return item
+65 -175
View File
@@ -1,207 +1,97 @@
from typing import Any, Dict import logging
from sqlalchemy import Boolean, Column, String, ForeignKey import re
from sqlalchemy.orm import relationship 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 from src.db.models.base import Base, BaseMixin, BaseVideoMixin
class MediaFile(Base, BaseMixin, BaseVideoMixin): class MediaFile(Base, BaseMixin, BaseVideoMixin):
__tablename__ = 'media_file' """
media_actor_files = relationship("MediaActorFile") MediaFile represents video link.
"""
__tablename__ = "media_file"
media_actor_files: Mapped[List["MediaActorFile"]] = relationship(
back_populates="media_file"
)
def __repr__(self): def __repr__(self):
return f'MediaFile(\n\tID: {self.id}\n\tTitle: {self.title}\n\tURL: {self.url}\n\tReview: {self.review}\n\tDownload: {self.should_download}\n\tPath: {self.path}\n\tCloudlink: {self.cloud_link})' return f"MediaFile({self.id} {self.title} {self.title})"
def __str__(self): def __str__(self):
return f'{self.title}({self.id})' return f"{self.title}({self.id})"
def update_title(self): def update_title(self):
pass """
Update title from url.
def import_dict(self, import_data: Dict[str, Any]): """
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.cloud_link = import_data['cloud_link']
self.file_name = import_data['file_name']
self.path = import_data['path']
self.review = import_data['review']
self.title = import_data['title']
self.url = import_data['url']
self.should_download = import_data['should_download']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['cloud_link'] = self.cloud_link
item['file_name'] = self.file_name
item['path'] = self.path
item['review'] = self.review
item['title'] = self.title
item['url'] = self.url
item['should_download'] = self.should_download
return item
class MediaActor(Base, BaseMixin): class MediaActor(Base, BaseMixin):
__tablename__ = 'media_actor' __tablename__ = "media_actor"
name = Column(String) name: Mapped[str]
url = Column(String, unique=True) url: Mapped[Optional[str]] = mapped_column(unique=True)
media_actor_files = relationship("MediaActorFile") media_actor_files = relationship("MediaActorFile")
def __repr__(self): def __repr__(self) -> str:
return f'MediaActor(\n\tID: {self.id}\n\tName: {self.name}\n\tURL: {self.url})' return f"MediaActor({self.id} {self.name} {self.url})"
def __str__(self): def __str__(self) -> str:
return f'{self.name}({self.id})' return f"{self.url}({self.id})"
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.url = import_data['url']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
item['url'] = self.url
return item
class MediaActorFile(Base, BaseMixin): class MediaActorFile(Base, BaseMixin):
__tablename__ = 'media_actor_file' __tablename__ = "media_actor_file"
media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False) media_actor_id: Mapped[str] = mapped_column(
media_actor = relationship("MediaActor", back_populates="media_actor_files") ForeignKey("media_actor.id"), nullable=False
media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True) )
media_file = relationship("MediaFile", back_populates="media_actor_files") 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): def __repr__(self):
return f'MediaActorFile(\n\tID: {self.id}\n\tMediaActor: {self.media_actor_id}\n\tMediaFile: {self.media_file_id})' return f"MediaActorFile({self.id} {self.media_actor_id} {self.media_file_id})"
def __str__(self): def __str__(self) -> str:
return f'{self.id}: MediaActor: {self.media_actor_id} - MediaFile: {self.media_file_id}' return f"{self.id} {self.media_actor_id} {self.media_file_id}"
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.media_actor_id = import_data['media_actor_id']
self.media_file_id = import_data['media_file_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['media_actor_id'] = self.media_actor_id
item['media_file_id'] = self.media_file_id
return item
class MediaArticle(Base, BaseMixin): class MediaArticle(Base, BaseMixin):
__tablename__ = 'media_article' __tablename__ = "media_article"
review = Column(Boolean) review: Mapped[bool]
title = Column(String) title: Mapped[str]
url = Column(String, unique=True) url: Mapped[str] = mapped_column(unique=True)
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.review = import_data['review']
self.title = import_data['title']
self.url = import_data['url']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['review'] = self.review
item['title'] = self.title
item['url'] = self.url
return item
class MediaVideo(Base, BaseMixin): class MediaVideo(Base, BaseMixin):
__tablename__ = 'media_video' """
cloud_link = Column(String) MediaFile represents video link.
file_name = Column(String) """
path = Column(String)
review = Column(Boolean)
title = Column(String)
url = Column(String, unique=True)
should_download = Column(Boolean)
def import_dict(self, import_data: Dict[str, Any]): __tablename__ = "media_video"
self.id = import_data['id'] cloud_link: Mapped[str]
self.created_date = import_data['created_date'] file_name: Mapped[str]
self.last_modified_date = import_data['last_modified_date'] path: Mapped[str]
self.version = import_data['version'] review: Mapped[bool]
self.cloud_link = import_data['cloud_link'] title: Mapped[str]
self.file_name = import_data['file_name'] url: Mapped[str] = mapped_column(unique=True)
self.path = import_data['path'] should_download: Mapped[bool]
self.review = import_data['review']
self.title = import_data['title']
self.url = import_data['url']
self.should_download = import_data['should_download']
def export_dict(self) -> Dict[str, Any]: def __repr__(self):
item: Dict[str, Any] = {} return f"MediaFile({self.id} {self.title} {self.url})"
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['cloud_link'] = self.cloud_link
item['file_name'] = self.file_name
item['path'] = self.path
item['review'] = self.review
item['title'] = self.title
item['url'] = self.url
item['should_download'] = self.should_download
return item
class MediaLofi(Base, BaseMixin): def __str__(self):
__tablename__ = 'media_lofi' if self.title is None:
file_name = Column(String) return f"{self.url}({self.id})"
review = Column(Boolean) else:
should_download = Column(Boolean) return f"{self.title}({self.id})"
title = Column(String)
url = Column(String, unique=True)
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.file_name = import_data['file_name']
self.review = import_data['review']
self.should_download = import_data['should_download']
self.title = import_data['title']
self.url = import_data['url']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['file_name'] = self.file_name
item['review'] = self.review
item['should_download'] = self.should_download
item['title'] = self.title
item['url'] = self.url
return item
+44 -203
View File
@@ -1,6 +1,6 @@
from typing import Dict, Any from typing import List
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Boolean from sqlalchemy import ForeignKey, UniqueConstraint
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship, mapped_column, Mapped
from src.db.models.base import Base, BaseMixin from src.db.models.base import Base, BaseMixin
@@ -10,56 +10,19 @@ class Sport(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("name"), UniqueConstraint("name"),
) )
name = Column(String, nullable=False, index=True, unique=True) name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True)
teams = relationship("Team") teams: Mapped[List["Team"]] = relationship(back_populates="sport")
positions = relationship("FieldPosition") positions: Mapped[List["FieldPosition"]] = relationship(back_populates="sport")
def __repr__(self):
return f"Sport(id={self.id}, name={self.name}, created_date={self.created_date})"
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
return item
class Team(Base, BaseMixin): class Team(Base, BaseMixin):
__tablename__ = "team" __tablename__ = "team"
name = Column(String, nullable=False, index=True, unique=True) name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True)
short_name = Column(String, nullable=False, ) short_name: Mapped[str] = mapped_column(nullable=False)
sport_id = Column(String, ForeignKey("sport.id"), nullable=False) sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False)
sport = relationship("Sport", back_populates="teams") sport: Mapped[Sport] = relationship(back_populates="teams")
roosters = relationship("Rooster") roosters: Mapped[List["Rooster"]] = relationship(back_populates="team")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.short_name = import_data['short_name']
self.sport_id = import_data['sport_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
item['short_name'] = self.short_name
item['sport_id'] = self.sport_id
return item
class FieldPosition(Base, BaseMixin): class FieldPosition(Base, BaseMixin):
__tablename__ = "field_position" __tablename__ = "field_position"
@@ -67,31 +30,11 @@ class FieldPosition(Base, BaseMixin):
UniqueConstraint("name", "sport_id"), UniqueConstraint("name", "sport_id"),
UniqueConstraint("short_name", "sport_id"), UniqueConstraint("short_name", "sport_id"),
) )
name = Column(String, nullable=False, index=True) name: Mapped[str] = mapped_column(nullable=False, index=True)
short_name = Column(String, nullable=False) short_name: Mapped[str] = mapped_column(nullable=False)
sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False, index=True)
sport = relationship("Sport", back_populates="positions") sport: Mapped[Sport] = relationship(back_populates="positions")
roosters = relationship("Rooster") roosters: Mapped[List["Rooster"]] = relationship(back_populates="position")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.short_name = import_data['short_name']
self.sport_id = import_data['sport_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
item['short_name'] = self.short_name
item['sport_id'] = self.sport_id
return item
class Player(Base, BaseMixin): class Player(Base, BaseMixin):
@@ -99,90 +42,34 @@ class Player(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("first_name", "last_name"), UniqueConstraint("first_name", "last_name"),
) )
first_name = Column(String, nullable=False, index=True) first_name: Mapped[str] = mapped_column(nullable=False, index=True)
last_name = Column(String, nullable=False, index=True) last_name: Mapped[str] = mapped_column(nullable=False, index=True)
roosters = relationship("Rooster") roosters: Mapped[List["Rooster"]] = relationship(back_populates="player")
def get_full_name(self) -> str: def get_full_name(self) -> str:
return f"{self.last_name}, {self.first_name}" return f"{self.last_name}, {self.first_name}"
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.first_name = import_data['first_name']
self.last_name = import_data['last_name']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['first_name'] = self.first_name
item['last_name'] = self.last_name
return item
class Rooster(Base, BaseMixin): class Rooster(Base, BaseMixin):
__tablename__ = "rooster" __tablename__ = "rooster"
__table_args__ = ( __table_args__ = (
UniqueConstraint("year", "team_id", "player_id", "position_id"), UniqueConstraint("year", "team_id", "player_id", "position_id"),
) )
year = Column(Integer) year: Mapped[int]
team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True) team_id: Mapped[str] = mapped_column(ForeignKey("team.id"), nullable=False, index=True)
team = relationship("Team", back_populates="roosters") team: Mapped[Team] = relationship(back_populates="roosters")
player_id = Column(String, ForeignKey("player.id"), nullable=False, index=True) player_id: Mapped[str] = mapped_column(ForeignKey("player.id"), nullable=False, index=True)
player = relationship("Player", back_populates="roosters") player: Mapped[Player] = relationship(back_populates="roosters")
position_id = Column(String, ForeignKey("field_position.id"), nullable=False, index=True) position_id: Mapped[str] = mapped_column(ForeignKey("field_position.id"), nullable=False, index=True)
position = relationship("FieldPosition", back_populates="roosters") position: Mapped[FieldPosition] = relationship(back_populates="roosters")
cards = relationship("Card") cards: Mapped[List["Card"]] = relationship(back_populates="rooster")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.year = import_data['year']
self.team_id = import_data['team_id']
self.player_id = import_data['player_id']
self.position_id = import_data['position_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['year'] = self.year
item['team_id'] = self.team_id
item['player_id'] = self.player_id
item['position_id'] = self.position_id
return item
class Vendor(Base, BaseMixin): class Vendor(Base, BaseMixin):
__tablename__ = "vendor" __tablename__ = "vendor"
name = Column(String, nullable=False, unique=True, index=True) name: Mapped[str] = mapped_column(nullable=False, unique=True, index=True)
card_sets = relationship("CardSet") card_sets: Mapped[List["CardSet"]] = relationship(back_populates="vendor")
cards = relationship("Card") cards: Mapped[List["Card"]] = relationship(back_populates="vendor")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
return item
class CardSet(Base, BaseMixin): class CardSet(Base, BaseMixin):
@@ -190,34 +77,12 @@ class CardSet(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("name", "vendor_id"), UniqueConstraint("name", "vendor_id"),
) )
name = Column(String, index=True) name: Mapped[str] = mapped_column(index=True)
parallel_set = Column(Boolean) parallel_set: Mapped[bool]
insert_set = Column(Boolean) insert_set: Mapped[bool]
vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False, index=True)
vendor = relationship("Vendor", back_populates="card_sets") vendor: Mapped[Vendor] = relationship(back_populates="card_sets")
cards = relationship("Card") cards: Mapped[List["Card"]] = relationship(back_populates="card_set")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.parallel_set = import_data['parallel_set']
self.insert_set = import_data['insert_set']
self.vendor_id = import_data['vendor_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
item['parallel_set'] = self.parallel_set
item['insert_set'] = self.insert_set
item['vendor_id'] = self.vendor_id
return item
class Card(Base, BaseMixin): class Card(Base, BaseMixin):
@@ -225,35 +90,11 @@ class Card(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"),
) )
card_number = Column(Integer, index=True) card_number: Mapped[int] = mapped_column(index=True)
year = Column(Integer, index=True) year: Mapped[int] = mapped_column(index=True)
card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False) card_set_id: Mapped[str] = mapped_column(ForeignKey("card_set.id"), nullable=False)
card_set = relationship("CardSet", back_populates="cards") card_set: Mapped[CardSet] = relationship(back_populates="cards")
rooster_id = Column(String, ForeignKey("rooster.id"), nullable=False) rooster_id: Mapped[str] = mapped_column(ForeignKey("rooster.id"), nullable=False)
rooster = relationship("Rooster", back_populates="cards") rooster: Mapped[Rooster] = relationship(back_populates="cards")
vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False) vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False)
vendor = relationship("Vendor", back_populates="cards") vendor: Mapped[Vendor] = relationship(back_populates="cards")
def import_dict(self, import_data: Dict[str, Any]):
self.id = import_data['id']
self.created_date = import_data['created_date']
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.card_number = import_data['card_number']
self.year = import_data['year']
self.card_set_id = import_data['card_set_id']
self.rooster_id = import_data['rooster_id']
self.vendor_id = import_data['vendor_id']
def export_dict(self) -> Dict[str, Any]:
item: Dict[str, Any] = {}
item['id'] = self.id
item['created_date'] = str(self.created_date)
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['card_number'] = self.card_number
item['year'] = self.year
item['card_set_id'] = self.card_set_id
item['rooster_id'] = self.rooster_id
item['vendor_id'] = self.vendor_id
return item
+4 -11
View File
@@ -1,7 +1,9 @@
import uuid
from typing import List, Optional from typing import List, Optional
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.comic import Artist from src.db.models.comic import Artist
from src.schema.comics.artist import AddArtist from src.schema.comics.artist import AddArtist
from src.schema.comics.artist_details import ArtistDetailResponse, ArtistWorktypeComicResponse, ArtistWorktypeIssueResponse from src.schema.comics.artist_details import ArtistDetailResponse, ArtistWorktypeComicResponse, ArtistWorktypeIssueResponse
@@ -15,17 +17,7 @@ def get_artist_details(artist: Artist) -> ArtistDetailResponse:
for work in artist.comic_works: for work in artist.comic_works:
worktype_id = work.work_type.id worktype_id = work.work_type.id
if worktype_id in comic_works_map: if worktype_id in comic_works_map:
comic = ComicResponse( comic = ComicResponse(id=work.comic.id, title=work.comic.title, completed=work.comic.completed)
id=work.comic.id,
created_date=work.comic.created_date,
last_modified_date=work.comic.last_modified_date,
version=work.comic.version,
publisher_id=work.comic.publisher_id,
current_order=work.comic.current_order,
weblink=work.comic.weblink,
title=work.comic.title,
completed=work.comic.completed
)
comic_works_map[worktype_id].comics.append(comic) comic_works_map[worktype_id].comics.append(comic)
else: else:
comic_works_map[worktype_id] = ArtistWorktypeComicResponse( comic_works_map[worktype_id] = ArtistWorktypeComicResponse(
@@ -45,6 +37,7 @@ def get_artist_details(artist: Artist) -> ArtistDetailResponse:
return response return response
def update_artist(add_artist: AddArtist, artist_id: str, db: Session) -> Optional[Artist]: 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) artist: Optional[Artist] = db.get(Artist, artist_id)
if artist is not None: if artist is not None:
artist.name = add_artist.name artist.name = add_artist.name
@@ -2,6 +2,7 @@ from typing import Dict, List, Optional
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.comic import Comic, Issue from src.db.models.comic import Comic, Issue
from src.schema.comics.artist import artist_to_response from src.schema.comics.artist import artist_to_response
from src.schema.comics.comic import ComicSchema, comic_to_response from src.schema.comics.comic import ComicSchema, comic_to_response
@@ -29,6 +30,7 @@ def get_issue_details(issue: Issue) -> IssueDetailsResponse:
def update_comic(new_comic: ComicSchema, comic_id: str, db: Session) -> Optional[Comic]: 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) comic: Optional[Comic] = db.get(Comic, comic_id)
return comic return comic
@@ -46,6 +48,7 @@ def get_comic_details(comic: Comic) -> ComicDetailsResponse:
if worktype_id in works_map: if worktype_id in works_map:
artist = artist_to_response(work.artist) artist = artist_to_response(work.artist)
works_map[worktype_id].artists.append(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}") print(f"add artist to response map: {artist} -> {works_map}")
else: else:
works_map[worktype_id] = ComicWorktypeArtistResponse( works_map[worktype_id] = ComicWorktypeArtistResponse(
@@ -9,43 +9,15 @@ from src.schema.comics.publisher_details import PublisherDetailsResponse
def get_publisher_details(publisher: Publisher) -> PublisherDetailsResponse: def get_publisher_details(publisher: Publisher) -> PublisherDetailsResponse:
imprints: List[PublisherResponse] = [] imprints: List[PublisherResponse] = []
for imprint in publisher.imprints: for imprint in publisher.imprints:
imprints.append( imprints.append(PublisherResponse(id=imprint.id, name=str(imprint.name)))
PublisherResponse(
id=imprint.id,
created_date=imprint.created_date,
last_modified_date=imprint.last_modified_date,
version=imprint.version,
weblink=str(imprint.weblink),
parent_publisher_id=imprint.parent_publisher_id,
name=str(imprint.name)
)
)
comics: List[ComicResponse] = [] comics: List[ComicResponse] = []
for comic in publisher.comics: for comic in publisher.comics:
comics.append( comics.append(
ComicResponse( ComicResponse(id=comic.id, title=comic.title, completed=comic.completed)
id=comic.id,
created_date=comic.created_date,
last_modified_date=comic.last_modified_date,
version=comic.version,
publisher_id=comic.publisher_id,
current_order=comic.current_order,
weblink=comic.weblink,
title=comic.title,
completed=comic.completed
)
) )
parent_publisher: PublisherResponse | None = None parent_publisher: PublisherResponse | None = None
if publisher.parent_publisher: if publisher.parent_publisher:
parent_publisher = PublisherResponse( parent_publisher = PublisherResponse(id=publisher.parent_publisher.id, name=str(publisher.parent_publisher.name))
id=publisher.parent_publisher.id,
created_date=publisher.parent_publisher.created_date,
last_modified_date=publisher.parent_publisher.last_modified_date,
version=publisher.parent_publisher.version,#
weblink=str(publisher.parent_publisher.weblink),
parent_publisher_id=publisher.parent_publisher.parent_publisher_id,
name=str(publisher.parent_publisher.name)
)
response: PublisherDetailsResponse = PublisherDetailsResponse( response: PublisherDetailsResponse = PublisherDetailsResponse(
id=publisher.id, name=str(publisher.name), parent_publisher=parent_publisher, imprints=imprints, comics=comics id=publisher.id, name=str(publisher.name), parent_publisher=parent_publisher, imprints=imprints, comics=comics
) )
@@ -4,6 +4,7 @@ from typing import AnyStr, Optional
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.comic import WorkType from src.db.models.comic import WorkType
from src.schema.comics.worktype import AddWorkType from src.schema.comics.worktype import AddWorkType
@@ -17,10 +18,12 @@ def create_new_worktype(work: AddWorkType, db: Session) -> WorkType:
db.add(worktype) db.add(worktype)
db.commit() db.commit()
db.refresh(worktype) db.refresh(worktype)
logger.info(f"create_new_worktype: {worktype}")
return worktype return worktype
def update_worktype(work: AddWorkType, worktype_id: AnyStr, db: Session) -> Optional[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) worktype: Optional[WorkType] = db.get(WorkType, worktype_id)
if worktype is not None: if worktype is not None:
worktype.name = work.worktype worktype.name = work.worktype
+5 -4
View File
@@ -3,13 +3,14 @@ import uuid
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.media import MediaActor from src.db.models.media import MediaActor
from src.db.repository.media.actorfile import delete_mediaactorfile from src.db.repository.media.actorfile import delete_mediaactorfile
from src.schema.media.actor import MediaActorModel from src.schema.media.actor import MediaActorModel
def create_new_mediaactor(new_actor: MediaActorModel, db: Session) -> MediaActor: def create_new_mediaactor(new_actor: MediaActorModel, db: Session) -> MediaActor:
print(f"create MediaActor with url {new_actor.url}") logger.info(f"create MediaActor with url {new_actor.url}")
media_actor: MediaActor = MediaActor() media_actor: MediaActor = MediaActor()
media_actor.id = str(uuid.uuid4()) media_actor.id = str(uuid.uuid4())
if new_actor.name is not None: if new_actor.name is not None:
@@ -21,11 +22,11 @@ def create_new_mediaactor(new_actor: MediaActorModel, db: Session) -> MediaActor
db.add(media_actor) db.add(media_actor)
db.commit() db.commit()
db.refresh(media_actor) db.refresh(media_actor)
print(f"created {media_actor}") logger.info(f"created {media_actor}")
return media_actor return media_actor
def delete_mediaactor(db: Session, actor_id: str): def delete_mediaactor(db: Session, actor_id: str):
print(f"delete MediaActor with id {actor_id}") logger.info(f"delete MediaActor with id {actor_id}")
media_actor = db.get(MediaActor, actor_id) media_actor = db.get(MediaActor, actor_id)
if media_actor is not None: if media_actor is not None:
actor_files = media_actor.media_actor_files actor_files = media_actor.media_actor_files
@@ -39,7 +40,7 @@ def import_mediaactor(db: Session, new_actor: MediaActorModel) -> MediaActor:
""" """
import MediaFile and set missing values with default ones. import MediaFile and set missing values with default ones.
""" """
print("import MediaActor with %s", new_actor) logger.info("import MediaActor with %s", new_actor)
media_actor: MediaActor = MediaActor() media_actor: MediaActor = MediaActor()
media_actor.id = new_actor.id media_actor.id = new_actor.id
if new_actor.created_date: if new_actor.created_date:
@@ -3,6 +3,7 @@ import uuid
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.media import MediaActorFile from src.db.models.media import MediaActorFile
from src.schema.media.actorfile import MediaActorFileModel from src.schema.media.actorfile import MediaActorFileModel
@@ -13,7 +14,7 @@ def create_new_mediaactorfile(
""" """
Create relation for MediaFile and MediaActor Create relation for MediaFile and MediaActor
""" """
print("create MediaActorFile with actor %s and file %s", actor_id, file_id) logger.info("create MediaActorFile with actor %s and file %s", actor_id, file_id)
media_actor_file: MediaActorFile = MediaActorFile() media_actor_file: MediaActorFile = MediaActorFile()
media_actor_file.id = str(uuid.uuid4()) media_actor_file.id = str(uuid.uuid4())
media_actor_file.created_date = datetime.now() media_actor_file.created_date = datetime.now()
@@ -31,7 +32,7 @@ def delete_mediaactorfile(db: Session, actorfile_id: str):
""" """
Delete relation between MediaFile and MediaActor. Delete relation between MediaFile and MediaActor.
""" """
print("delete MediaActorFile with id %s", actorfile_id) logger.info("delete MediaActorFile with id %s", actorfile_id)
media_actorfile = db.get(MediaActorFile, actorfile_id) media_actorfile = db.get(MediaActorFile, actorfile_id)
db.delete(media_actorfile) db.delete(media_actorfile)
db.commit() db.commit()
@@ -43,7 +44,7 @@ def import_mediaactorfile(
""" """
Import MediaFile and set missing values with default ones. Import MediaFile and set missing values with default ones.
""" """
print("import MediaActorFile with %s", new_actorfile) logger.info("import MediaActorFile with %s", new_actorfile)
media_actor_file: MediaActorFile = MediaActorFile() media_actor_file: MediaActorFile = MediaActorFile()
media_actor_file.id = new_actorfile.id media_actor_file.id = new_actorfile.id
if new_actorfile.created_date: if new_actorfile.created_date:
+5 -4
View File
@@ -3,6 +3,7 @@ import uuid
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.core.log_conf import logger
from src.db.models.media import MediaFile from src.db.models.media import MediaFile
from src.schema.media.file import MediaFileModel from src.schema.media.file import MediaFileModel
@@ -11,7 +12,7 @@ def create_new_mediafile(link: str, db: Session) -> MediaFile:
""" """
Create MediaFile with gievne URL. Create MediaFile with gievne URL.
""" """
print("create MediaFile with url {link}") logger.info("create MediaFile with url {link}")
media_file: MediaFile = MediaFile() media_file: MediaFile = MediaFile()
media_file.id = str(uuid.uuid4()) media_file.id = str(uuid.uuid4())
media_file.url = link media_file.url = link
@@ -23,7 +24,7 @@ def create_new_mediafile(link: str, db: Session) -> MediaFile:
db.add(media_file) db.add(media_file)
db.commit() db.commit()
db.refresh(media_file) db.refresh(media_file)
print("created %s", media_file) logger.info("created %s", media_file)
return media_file return media_file
@@ -31,7 +32,7 @@ def delete_mediafile(db: Session, media_file_id: str):
""" """
Delete MediaFile with given ID from db. Delete MediaFile with given ID from db.
""" """
print("delete MediaFile with id %s", media_file_id) logger.info("delete MediaFile with id %s", media_file_id)
media_file = db.get(MediaFile, media_file_id) media_file = db.get(MediaFile, media_file_id)
db.delete(media_file) db.delete(media_file)
db.commit() db.commit()
@@ -41,7 +42,7 @@ def import_mediafile(db: Session, new_file: MediaFileModel) -> MediaFile:
""" """
import MediaActor and set missing values with defautl ones. import MediaActor and set missing values with defautl ones.
""" """
print("import MediaFile with %s", new_file) logger.info("import MediaFile with %s", new_file)
media_file: MediaFile = MediaFile() media_file: MediaFile = MediaFile()
media_file.id = new_file.id media_file.id = new_file.id
if new_file.created_date: if new_file.created_date:
@@ -1,69 +0,0 @@
from datetime import datetime
import uuid
from sqlalchemy.orm import Session
from src.db.models.media import MediaLofi
from src.schema.media.lofi import MediaLofiModel
def create_new_lofi(url: str, db: Session) -> MediaLofi:
"""
Create MediaLofi with given URL.
"""
print("create MediaLofi with url %s", url)
media_lofi = MediaLofi()
media_lofi.id = str(uuid.uuid4())
media_lofi.url = url
media_lofi.created_date = datetime.now()
media_lofi.last_modified_date = datetime.now()
media_lofi.review = True
media_lofi.should_download = False
db.add(media_lofi)
db.commit()
db.refresh(media_lofi)
print(media_lofi)
return media_lofi
def import_medialofi(db: Session, new_lofi: MediaLofiModel) -> MediaLofi:
"""
import MediaLofi and set missing values with default ones.
"""
print("import MediaLofi with %s", new_lofi)
media_lofi: MediaLofi = MediaLofi()
media_lofi.id = new_lofi.id
if new_lofi.created_date:
media_lofi.created_date = new_lofi.created_date
else:
media_lofi.created_date = datetime.now()
if new_lofi.last_modified_date:
media_lofi.last_modified_date = new_lofi.last_modified_date
else:
media_lofi.last_modified_date = datetime.now()
media_lofi.version = new_lofi.version
if new_lofi.title:
media_lofi.title = new_lofi.title
else:
media_lofi.title = ""
if new_lofi.url:
media_lofi.url = new_lofi.url
else:
# TODO shoud exeception be raised when url is missing?
media_lofi.url = ""
media_lofi.review = new_lofi.review
media_lofi.should_download = new_lofi.should_download
db.add(media_lofi)
db.commit()
db.refresh(media_lofi)
return media_lofi
def delete_medialofi(db: Session, lofi_id: str):
"""
Delete MediaLofi with given ID from db.
"""
print("delete MediaLofi with id %s", lofi_id)
lofi = db.get(MediaLofi, lofi_id)
db.delete(lofi)
db.commit()
+4 -3
View File
@@ -4,13 +4,14 @@ import uuid
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.db.models.media import MediaVideo from src.db.models.media import MediaVideo
from src.webapps.media.forms import AddLinkForm
def create_new_video(url: str, db: Session) -> MediaVideo: def create_new_video(video: AddLinkForm, db: Session) -> MediaVideo:
print(url) print(video.url)
media_video = MediaVideo() media_video = MediaVideo()
media_video.id = str(uuid.uuid4()) media_video.id = str(uuid.uuid4())
media_video.url = url media_video.url = str(video.url)
media_video.created_date = datetime.now() media_video.created_date = datetime.now()
media_video.last_modified_date = datetime.now() media_video.last_modified_date = datetime.now()
media_video.review = True media_video.review = True
+5 -4
View File
@@ -1,6 +1,7 @@
from datetime import datetime 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.db.models.admin import Assignment, Profile from src.db.models.admin import Assignment, Profile
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -8,7 +9,7 @@ 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:
print(f"create Profile with username {new_profile.username}") logger.info(f"create MediaActor with url {new_profile.username}")
profile: Profile = Profile() profile: Profile = Profile()
profile.id = str(uuid.uuid4()) profile.id = str(uuid.uuid4())
profile.user_name = new_profile.username profile.user_name = new_profile.username
@@ -20,11 +21,11 @@ def create_new_profile(new_profile: ProfileModel, db: Session) -> Profile:
db.add(profile) db.add(profile)
db.commit() db.commit()
db.refresh(profile) db.refresh(profile)
print(f"created {profile}") logger.info(f"created {profile}")
return profile return profile
def delete_profile(db: Session, profile_id: str): def delete_profile(db: Session, profile_id: str):
print(f"delete Profile with id {profile_id}") logger.info(f"delete Profile with id {profile_id}")
profile: Optional[Profile] = db.get(Profile, profile_id) profile: Optional[Profile] = db.get(Profile, profile_id)
if profile is not None: if profile is not None:
assignments = profile.assignments assignments = profile.assignments
@@ -34,7 +35,7 @@ def delete_profile(db: Session, profile_id: str):
db.commit() db.commit()
def delete_assignment(db: Session, assignment_id: str) -> None: def delete_assignment(db: Session, assignment_id: str) -> None:
print(f"delete Assignment with id {assignment_id}") logger.info(f"delete Assignment with id {assignment_id}")
assignment: Optional[Assignment] = db.get(Assignment, assignment_id) assignment: Optional[Assignment] = db.get(Assignment, assignment_id)
if assignment is not None: if assignment is not None:
db.delete(assignment) db.delete(assignment)
+5 -5
View File
@@ -24,11 +24,11 @@ def to_response(account: MailAccount) -> MailAccountResponse:
created_date=account.created_date, created_date=account.created_date,
last_modified_date=account.last_modified_date, last_modified_date=account.last_modified_date,
version=account.version, version=account.version,
host=str(account.host), host=account.host,
port=account.port, port=account.port,
protocol=str(account.protocol), protocol=account.protocol,
user_name=str(account.user_name), user_name=account.user_name,
password=str(account.password), password=account.password,
start_tls=bool(account.start_tls), start_tls=account.start_tls,
) )
return response return response
+1 -1
View File
@@ -18,6 +18,6 @@ def to_response(article: Article) -> ArticleResponse:
created_date=article.created_date, created_date=article.created_date,
last_modified_date=article.last_modified_date, last_modified_date=article.last_modified_date,
version=article.version, version=article.version,
title=str(article.title) title=article.title
) )
return response return response
@@ -19,7 +19,7 @@ def to_response(articleauthor: ArticleAuthor) -> ArticleAuthorResponse:
created_date=articleauthor.created_date, created_date=articleauthor.created_date,
last_modified_date=articleauthor.last_modified_date, last_modified_date=articleauthor.last_modified_date,
version=articleauthor.version, version=articleauthor.version,
article_id=str(articleauthor.article_id), article_id=articleauthor.article_id,
author_id=str(articleauthor.author_id) author_id=articleauthor.author_id
) )
return response return response
+2 -2
View File
@@ -19,7 +19,7 @@ def to_response(author: Author) -> AuthorResponse:
created_date=author.created_date, created_date=author.created_date,
last_modified_date=author.last_modified_date, last_modified_date=author.last_modified_date,
version=author.version, version=author.version,
first_name=str(author.first_name), first_name=author.first_name,
last_name=str(author.last_name) last_name=author.last_name
) )
return response return response
+3 -3
View File
@@ -21,9 +21,9 @@ def to_response(book: Book) -> BookResponse:
created_date=book.created_date, created_date=book.created_date,
last_modified_date=book.last_modified_date, last_modified_date=book.last_modified_date,
version=book.version, version=book.version,
isbn=str(book.isbn), isbn=book.isbn,
title=str(book.title), title=book.title,
year=book.year, year=book.year,
publisher_id=str(book.publisher_id) publisher_id=book.publisher_id
) )
return response return response
@@ -19,7 +19,7 @@ def to_response(bookauthor: BookAuthor) -> BookAuthorResponse:
created_date=bookauthor.created_date, created_date=bookauthor.created_date,
last_modified_date=bookauthor.last_modified_date, last_modified_date=bookauthor.last_modified_date,
version=bookauthor.version, version=bookauthor.version,
author_id=str(bookauthor.author_id), author_id=bookauthor.author_id,
book_id=str(bookauthor.book_id) book_id=bookauthor.book_id
) )
return response return response
+1 -1
View File
@@ -18,6 +18,6 @@ def to_response(publisher: BookshelfPublisher) -> PublisherResponse:
created_date=publisher.created_date, created_date=publisher.created_date,
last_modified_date=publisher.last_modified_date, last_modified_date=publisher.last_modified_date,
version=publisher.version, version=publisher.version,
name=str(publisher.name) name=publisher.name
) )
return response return response
+5 -5
View File
@@ -28,11 +28,11 @@ def comic_to_response(comic: Comic) -> ComicResponse:
created_date=comic.created_date, created_date=comic.created_date,
last_modified_date=comic.last_modified_date, last_modified_date=comic.last_modified_date,
version=comic.version, version=comic.version,
title=str(comic.title), title=comic.title,
publisher_id=str(comic.publisher_id), publisher_id=comic.publisher_id,
current_order=bool(comic.current_order), current_order=comic.current_order,
completed=bool(comic.completed), completed=comic.completed,
weblink=str(comic.weblink) weblink=comic.weblink
) )
return response return response
+3 -3
View File
@@ -25,8 +25,8 @@ def comicwork_to_response(comicwork: ComicWork) -> ComicWorkResponse:
created_date=comicwork.created_date, created_date=comicwork.created_date,
last_modified_date=comicwork.last_modified_date, last_modified_date=comicwork.last_modified_date,
version=comicwork.version, version=comicwork.version,
comic_id=str(comicwork.comic_id), comic_id=comicwork.comic_id,
artist_id=str(comicwork.artist_id), artist_id=comicwork.artist_id,
work_type_id=str(comicwork.work_type_id), work_type_id=comicwork.work_type_id,
) )
return response return response
+7 -7
View File
@@ -26,13 +26,13 @@ def issue_to_response(issue: Issue) -> IssueResponse:
created_date=issue.created_date, created_date=issue.created_date,
last_modified_date=issue.last_modified_date, last_modified_date=issue.last_modified_date,
version=issue.version, version=issue.version,
issue_number=str(issue.issue_number), issue_number=issue.issue_number,
title=str(issue.title), title=issue.title,
published_on=issue.published_on, published_on=issue.published_on,
in_stock=bool(issue.in_stock), in_stock=issue.in_stock,
is_read=bool(issue.is_read), is_read=issue.is_read,
comic_id=str(issue.comic_id), comic_id=issue.comic_id,
volume_id=str(issue.volume_id), volume_id=issue.volume_id,
story_arc_id=str(issue.story_arc_id) story_arc_id=issue.story_arc_id
) )
return response return response
+3 -3
View File
@@ -25,8 +25,8 @@ def issuework_to_response(issuework: IssueWork) -> IssueWorkResponse:
created_date=issuework.created_date, created_date=issuework.created_date,
last_modified_date=issuework.last_modified_date, last_modified_date=issuework.last_modified_date,
version=issuework.version, version=issuework.version,
issue_id=str(issuework.issue_id), issue_id=issuework.issue_id,
artist_id=str(issuework.artist_id), artist_id=issuework.artist_id,
work_type_id=str(issuework.work_type_id), work_type_id=issuework.work_type_id,
) )
return response return response
+2 -2
View File
@@ -22,8 +22,8 @@ def publisher_to_response(publisher: Publisher) -> PublisherResponse:
created_date=publisher.created_date, created_date=publisher.created_date,
last_modified_date=publisher.last_modified_date, last_modified_date=publisher.last_modified_date,
version=publisher.version, version=publisher.version,
name=str(publisher.name), name=publisher.name,
weblink=str(publisher.weblink), weblink=publisher.weblink,
parent_publisher_id=publisher.parent_publisher_id parent_publisher_id=publisher.parent_publisher_id
) )
return response return response
+3 -3
View File
@@ -23,8 +23,8 @@ def storyarc_to_response(storyarc: StoryArc) -> StoryArcResponse:
created_date=storyarc.created_date, created_date=storyarc.created_date,
last_modified_date=storyarc.last_modified_date, last_modified_date=storyarc.last_modified_date,
version=storyarc.version, version=storyarc.version,
name=str(storyarc.name), name=storyarc.name,
comic_id=str(storyarc.comic_id), comic_id=storyarc.comic_id,
volume_id=str(storyarc.volume_id) volume_id=storyarc.volume_id
) )
return response return response
+2 -2
View File
@@ -19,7 +19,7 @@ def volume_to_response(volume: Volume) -> VolumeResponse:
created_date=volume.created_date, created_date=volume.created_date,
last_modified_date=volume.last_modified_date, last_modified_date=volume.last_modified_date,
version=volume.version, version=volume.version,
name=str(volume.name), name=volume.name,
comic_id=str(volume.comic_id) comic_id=volume.comic_id
) )
return response return response
+1 -1
View File
@@ -21,6 +21,6 @@ def worktype_to_response(worktype: WorkType) -> WorktypeResponse:
created_date=worktype.created_date, created_date=worktype.created_date,
last_modified_date=worktype.last_modified_date, last_modified_date=worktype.last_modified_date,
version=worktype.version, version=worktype.version,
name=str(worktype.name) name=worktype.name
) )
return response return response
+2 -26
View File
@@ -19,8 +19,8 @@ def actor_to_response(actor: MediaActor) -> MediaActorResponse:
created_date=actor.created_date, created_date=actor.created_date,
last_modified_date=actor.last_modified_date, last_modified_date=actor.last_modified_date,
version=actor.version, version=actor.version,
name=str(actor.name), name=actor.name,
url=str(actor.url) url=actor.url
) )
return response return response
@@ -32,27 +32,3 @@ class MediaActorModel(BaseModel):
version: int version: int
name: Optional[str] name: Optional[str]
url: Optional[str] url: Optional[str]
def actor_to_model(model: MediaActorResponse, media_actor: MediaActor) -> MediaActor:
"""
Set data of response to model
"""
media_actor.file_name = model.file_name
if model.url is not None:
media_actor.url = model.url
else:
media_actor.url = ""
media_actor.last_modified_date = datetime.now()
return media_actor
def actor_to_response(media_actor: MediaActor) -> MediaActorResponse:
response: MediaActorResponse = MediaActorResponse(
id=media_actor.id,
created_date=media_actor.created_date,
last_modified_date=media_actor.last_modified_date,
version=media_actor.version,
name=str(media_actor.name),
url=str(media_actor.url),
)
return response
+2 -2
View File
@@ -19,8 +19,8 @@ def actorfile_to_response(actorfile: MediaActorFile) -> MediaActorFileResponse:
created_date=actorfile.created_date, created_date=actorfile.created_date,
last_modified_date=actorfile.last_modified_date, last_modified_date=actorfile.last_modified_date,
version=actorfile.version, version=actorfile.version,
media_actor_id=str(actorfile.media_actor_id), media_actor_id=actorfile.media_actor_id,
media_file_id=str(actorfile.media_file_id) media_file_id=actorfile.media_file_id
) )
return response return response
+3 -3
View File
@@ -23,8 +23,8 @@ def to_response(video: MediaArticle) -> MediaArticleResponse:
created_date=video.created_date, created_date=video.created_date,
last_modified_date=video.last_modified_date, last_modified_date=video.last_modified_date,
version=video.version, version=video.version,
review=bool(video.review), review=video.review,
title=str(video.title), title=video.title,
url=str(video.url), url=video.url,
) )
return response return response
-67
View File
@@ -1,67 +0,0 @@
from datetime import datetime
from pydantic import BaseModel
from src.db.models.media import MediaLofi
class MediaLofiResponse(BaseModel):
id: str
created_date: datetime
last_modified_date: datetime
version: int
title: str = ""
file_name: str = ""
url: str = ""
review: bool = False
should_download: bool = False
class AddLofi(BaseModel):
url: str
class MediaLofiModel(BaseModel):
"""
Pydantic Model to import MediaLofi.
"""
id: str
created_date: datetime
last_modified_date: datetime
version: int = 0
title: str = ""
file_name: str = ""
url: str = ""
review: bool = False
should_download: bool = False
def lofi_to_model(model: MediaLofiResponse, medialofi: MediaLofi) -> MediaLofi:
"""
Set data of response to model
"""
medialofi.file_name = model.file_name
if model.url is not None:
medialofi.url = model.url
else:
medialofi.url = ""
if model.title is not None:
medialofi.title = model.title
else:
medialofi.title = ""
medialofi.last_modified_date = datetime.now()
medialofi.review = model.review
medialofi.should_download = model.should_download
return medialofi
def lofi_to_response(lofi: MediaLofi) -> MediaLofiResponse:
response: MediaLofiResponse = MediaLofiResponse(
id=lofi.id,
created_date=lofi.created_date,
last_modified_date=lofi.last_modified_date,
version=lofi.version,
file_name=str(lofi.file_name),
review=bool(lofi.review),
should_download=bool(lofi.should_download),
title=str(lofi.title),
url=str(lofi.url),
)
return response
+7 -7
View File
@@ -27,12 +27,12 @@ def video_to_response(video: MediaVideo) -> MediaVideoResponse:
created_date=video.created_date, created_date=video.created_date,
last_modified_date=video.last_modified_date, last_modified_date=video.last_modified_date,
version=video.version, version=video.version,
cloud_link=str(video.cloud_link), cloud_link=video.cloud_link,
file_name=str(video.file_name), file_name=video.file_name,
path=str(video.path), path=video.path,
review=bool(video.review), review=video.review,
title=str(video.title), title=video.title,
url=str(video.url), url=video.url,
should_download=bool(video.should_download) should_download=video.should_download
) )
return response return response
+3 -3
View File
@@ -24,8 +24,8 @@ def to_response(card: Card) -> CardResponse:
version=card.version, version=card.version,
card_number=card.card_number, card_number=card.card_number,
year=card.year, year=card.year,
card_set_id=str(card.card_set_id), card_set_id=card.card_set_id,
rooster_id=str(card.rooster_id), rooster_id=card.rooster_id,
vendor_id=str(card.vendor_id) vendor_id=card.vendor_id
) )
return response return response
+4 -4
View File
@@ -22,9 +22,9 @@ def to_response(cardset: CardSet) -> CardSetResponse:
created_date=cardset.created_date, created_date=cardset.created_date,
last_modified_date=cardset.last_modified_date, last_modified_date=cardset.last_modified_date,
version=cardset.version, version=cardset.version,
name=str(cardset.name), name=cardset.name,
parallel_set=bool(cardset.parallel_set), parallel_set=cardset.parallel_set,
insert_set=bool(cardset.insert_set), insert_set=cardset.insert_set,
vendor_id=str(cardset.vendor_id) vendor_id=cardset.vendor_id
) )
return response return response
+3 -3
View File
@@ -21,8 +21,8 @@ def to_response(fieldposition: FieldPosition) -> FieldPositionResponse:
created_date=fieldposition.created_date, created_date=fieldposition.created_date,
last_modified_date=fieldposition.last_modified_date, last_modified_date=fieldposition.last_modified_date,
version=fieldposition.version, version=fieldposition.version,
name=str(fieldposition.name), name=fieldposition.name,
short_name=str(fieldposition.short_name), short_name=fieldposition.short_name,
sport_id=str(fieldposition.sport_id) sport_id=fieldposition.sport_id
) )
return response return response
+2 -2
View File
@@ -19,7 +19,7 @@ def to_response(player: Player) -> PlayerResponse:
created_date=player.created_date, created_date=player.created_date,
last_modified_date=player.last_modified_date, last_modified_date=player.last_modified_date,
version=player.version, version=player.version,
first_name=str(player.first_name), first_name=player.first_name,
last_name=str(player.last_name) last_name=player.last_name
) )
return response return response
+3 -3
View File
@@ -29,8 +29,8 @@ def to_response(rooster: Rooster) -> RoosterResponse:
last_modified_date=rooster.last_modified_date, last_modified_date=rooster.last_modified_date,
version=rooster.version, version=rooster.version,
year=rooster.year, year=rooster.year,
team_id=str(rooster.team_id), team_id=rooster.team_id,
player_id=str(rooster.player_id), player_id=rooster.player_id,
position_id=str(rooster.position_id) position_id=rooster.position_id
) )
return response return response
+1 -1
View File
@@ -19,6 +19,6 @@ def to_response(sport: Sport) -> SportResponse:
created_date=sport.created_date, created_date=sport.created_date,
last_modified_date=sport.last_modified_date, last_modified_date=sport.last_modified_date,
version=sport.version, version=sport.version,
name=str(sport.name) name=sport.name
) )
return response return response
+3 -3
View File
@@ -21,8 +21,8 @@ def to_response(team: Team) -> TeamResponse:
created_date=team.created_date, created_date=team.created_date,
last_modified_date=team.last_modified_date, last_modified_date=team.last_modified_date,
version=team.version, version=team.version,
name=str(team.name), name=team.name,
short_name=str(team.short_name), short_name=team.short_name,
sport_id=str(team.sport_id) sport_id=team.sport_id
) )
return response return response
+1 -1
View File
@@ -27,6 +27,6 @@ def to_response(vendor: Vendor) -> VendorResponse:
created_date=vendor.created_date, created_date=vendor.created_date,
last_modified_date=vendor.last_modified_date, last_modified_date=vendor.last_modified_date,
version=vendor.version, version=vendor.version,
name=str(vendor.name) name=vendor.name
) )
return reponse return reponse
+2 -2
View File
@@ -20,7 +20,7 @@ def to_response(assignment: Assignment) -> AssignmentResponse:
created_date=assignment.created_date, created_date=assignment.created_date,
last_modified_date=assignment.last_modified_date, last_modified_date=assignment.last_modified_date,
version=assignment.version, version=assignment.version,
profile_id=str(assignment.profile_id), profile_id=assignment.profile_id,
permission_id=str(assignment.permission_id) permission_id=assignment.permission_id
) )
return response return response
+1 -1
View File
@@ -19,6 +19,6 @@ def to_response(permission: Permission) -> PermissionResponse:
created_date=permission.created_date, created_date=permission.created_date,
last_modified_date=permission.last_modified_date, last_modified_date=permission.last_modified_date,
version=permission.version, version=permission.version,
name=str(permission.name) name=permission.name
) )
return response return response
+6 -6
View File
@@ -23,12 +23,12 @@ def to_response(profile: Profile) -> ProfileResponse:
created_date=profile.created_date, created_date=profile.created_date,
last_modified_date=profile.last_modified_date, last_modified_date=profile.last_modified_date,
version=profile.version, version=profile.version,
first_name=str(profile.first_name), first_name=profile.first_name,
last_name=str(profile.last_name), last_name=profile.last_name,
user_name=str(profile.user_name), user_name=profile.user_name,
email=str(profile.email), email=profile.email,
password=str(profile.password), password=profile.password,
enabled=bool(profile.enabled) enabled=profile.enabled
) )
return response return response
+4 -4
View File
@@ -23,10 +23,10 @@ def to_response(token: Token) -> TokenResponse:
created_date=token.created_date, created_date=token.created_date,
last_modified_date=token.last_modified_date, last_modified_date=token.last_modified_date,
version=token.version, version=token.version,
token=str(token.token), token=token.token,
name=str(token.name), name=token.name,
last_used_date=token.last_used_date, last_used_date=token.last_used_date,
enabled=bool(token.enabled), enabled=token.enabled,
profile_id=str(token.profile_id) profile_id=token.profile_id
) )
return response return response
@@ -1,8 +1 @@
<footer class="mt-auto py-3 bg-light fixed-bottom"> <h2>Footer</h2>
<div class="container text-center">
<span class="text-muted">{{ version }}</span>
</div>
</footer>
<!-- Bootstrap JS einbinden -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="{{ url_for('static', path='js/autocomplete.js') }}"></script>
@@ -1,49 +1,10 @@
<!-- <div class="topnav"> <div class="topnav">
<a href="/">Kontor</a> <a href="/">Kontor</a>
<a href="/comic/comics">Comics</a> <a href="/comic/comics">Comics</a>
<a href="/media/files">Media</a> <a href="/media/files">Media</a>
<a style="float:right" href="/login/">Login</a></li> <a style="float:right" href="/login/">Login</a></li>
</div> -->
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color:darkgrey;">
<div class="container-fluid">
<a class="navbar-brand" href="#">Kontor</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarComicsMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Comics</a>
<div class="dropdown-menu" aria-labelledby="navbarComicsMenuLink">
<a class="dropdown-item" href="/comic/comics">Comics</a>
<a class="dropdown-item" href="/comic/publishers">Publisher</a>
<a class="dropdown-item" href="/comic/artists">Artist</a>
<a class="dropdown-item" href="/comic/issues">Issue</a>
</div> </div>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarWebMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Media</a>
<div class="dropdown-menu" aria-labelledby="navbarWebMenuLink">
<a class="dropdown-item" href="/media/files">Media Files</a>
<a class="dropdown-item" href="/media/actors">Media Actors</a>
<a class="dropdown-item" href="/media/lofis">Lofi</a>
<a class="dropdown-item" href="/media/articles">Artikel</a>
</div>
</li>
{% if user %}
<li class="nav-item">
<a class="nav-link" href="/logout">Logout</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
<!-- <nav class="navbar navbar-expand-lg navbar-light bg-light px-5"> <!-- <nav class="navbar navbar-expand-lg navbar-light bg-light px-5">
<div class="container-fluid"> <div class="container-fluid">
@@ -1,29 +0,0 @@
{% extends "shared/base.html" %}
{% block title %}
<title>Add a Lofi Link</title>
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="text-danger font-weight-bold">
{% for error in errors %}
<li>{{error}}</li>
{% endfor %}
</div>
</div>
<div class="row my-5">
<h3 class="text-center display-4">Add a Lofi Link</h3>
<form method="POST">
<div class="mb-3">
<input type="text" required class="form-control" name="url" value="{{url}}" placeholder="Lofi Link here">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
{% endblock %}
@@ -1,51 +0,0 @@
{% extends "shared/base.html" %}
{% block title %}
<title>MediaLofi Detail</title>
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<h1 class="display-5">MediaLofi Detail</h1>
</div>
</div>
<div class="row">
<table class="table table-striped table-hover">
<tbody>
<tr>
<th scope="row">MediaLofi Title</th>
<td colspan="2">{{medialofi.title}}</td>
</tr>
<tr>
<th scope="row">MediaLofi URL</th>
<td colspan="2">{{medialofi.url}}</td>
</tr>
<tr>
<th scope="row">MediaLofi Download?</th>
<td colspan="2">{{medialofi.should_download}}</td>
</tr>
<tr>
<th scope="row">MediaLofi Review?</th>
<td colspan="2">{{medialofi.review}}</td>
</tr>
<tr>
<th scope="row">Data Created</th>
<td colspan="2">{{medialofi.created_date}}</td>
</tr>
<tr>
<th scope="row">Data Modified</th>
<td colspan="2">{{medialofi.last_modified_date}}</td>
</tr>
<tr>
<th scope="row">Data Version</th>
<td colspan="2">{{medialofi.version}}</td>
</tr>
</tbody>
</table>
</div>
</div>
{% endblock %}
@@ -1,62 +0,0 @@
{% extends "shared/base.html" %}
{% block title %}
<title>Lofi Links</title>
{% endblock %}
{% block content %}
{% with msg=msg %}
{% include "components/alerts.html" %}
{% endwith %}
<div class="row">
<div class="col-md-8">
<h1>Media Lofi</h1>
<p>Hier steht der wesentliche Inhalt der Seite.</p>
</div>
<div class="col-md-4">
<aside class="bg-light p-3">
<h3>Seitenbereich</h3>
<p>Optionale Sidebar oder Zusatzinformationen.</p>
</aside>
</div>
</div>
<div class="row">
<form class="form-inline" action="/media/lofis">
<input type="text" placeholder="Search" name="query">
<label>
<input type="checkbox" name="review" {% if review %}checked{% endif %}>Review
</label>
<label>
<input type="checkbox" name="should_download" {% if download %}checked{% endif %}>Download
</label>
<button type="submit">Search</button>
<div class="pill-nav"><a href="/media/lofis/add">Add Lofi</a></div>
</form>
</div>
<div class="row">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Weblink</th>
<th scope="col">Review</th>
<th colspan="2">Actions</th>
</tr>
</thead>
<tbody>
{% for medialofi in medialofis %}
<tr>
<th scope="row"><a href="/media/lofi/{{medialofi.id}}">{{medialofi.title}}</a></th>
<td><a href="{{medialofi.url}}">{{medialofi.url}}</a></td>
<td>{% with check=medialofi.review %}{% include "components/check.html" %}{% endwith %}</td>
<td>{% with check=medialofi.should_download %}{% include "components/check.html" %}{% endwith %}</td>
<td><a href="/media/lofi/{{medialofi.id}}/edit" class="btn btn-outline-primary btn-sm active" role="button" aria-pressed="true">Edit</a></td>
<td><a href="/media/lofi/{{medialofi.id}}/delete" class="btn btn-outline-danger btn-sm active" role="button" aria-pressed="true">Delete</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
@@ -2,5 +2,4 @@
<a href="/media/files/">MediaFiles</a> <a href="/media/files/">MediaFiles</a>
<a href="/media/actors/">MediaActors</a> <a href="/media/actors/">MediaActors</a>
<a href="/media/videos/">MediaVideos</a> <a href="/media/videos/">MediaVideos</a>
<a href="/media/lofi/">MediaLofi</a>
</div> </div>
+55 -15
View File
@@ -1,35 +1,75 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="de-DE"> <html lang="de-DE">
<head> <head>
<meta charset="UTF-8" /> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ url_for('static', path='style.css') }}"> <link rel="stylesheet" href="{{ url_for('static', path='style.css') }}">
{% block title %} {% block title %}
{% endblock %} {% endblock %}
</head> </head>
<body class="d-flex flex-column h-100"> <body>
<header> <div class="header">
{% block header %} {% block header %}
{% endblock %} {% endblock %}
</div>
{% include "components/navbar.html" %} {% include "components/navbar.html" %}
{% block subnav %} {% block subnav %}
{% endblock %} {% endblock %}
</header> <!-- <div class="topnav">
<main class="flex-shrink-0"> <a href="#">Link</a>
<div class="container my-4"> <a href="#">Link</a>
<a href="#">Link</a>
<a href="#" style="float:right">Link</a>
</div> -->
{% block content %} {% block content %}
{% endblock %} {% endblock %}
</div>
</main>
{% include "components/footer.html" %} <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
<script src="{{ url_for('static', path='js/autocomplete.js') }}"></script>
{% block scripts %} {% block scripts %}
{% endblock %} {% endblock %}
<!-- <div class="row">
<div class="leftcolumn">
<div class="card">
<h2>TITLE HEADING</h2>
<h5>Title description, Dec 7, 2017</h5>
<div class="fakeimg" style="height:200px;">Image</div>
<p>Some text..</p>
<p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
</div>
<div class="card">
<h2>TITLE HEADING</h2>
<h5>Title description, Sep 2, 2017</h5>
<div class="fakeimg" style="height:200px;">Image</div>
<p>Some text..</p>
<p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
</div>
</div>
<div class="rightcolumn">
<div class="card">
<h2>About Me</h2>
<div class="fakeimg" style="height:100px;">Image</div>
<p>Some text about me in culpa qui officia deserunt mollit anim..</p>
</div>
<div class="card">
<h3>Popular Post</h3>
<div class="fakeimg"><p>Image</p></div>
<div class="fakeimg"><p>Image</p></div>
<div class="fakeimg"><p>Image</p></div>
</div>
<div class="card">
<h3>Follow Me</h3>
<p>Some text..</p>
</div>
</div>
</div> -->
<div class="footer">
{% include "components/footer.html" %}
</div>
</body> </body>
</html> </html>
+1 -2
View File
@@ -4,7 +4,7 @@ from fastapi.templating import Jinja2Templates
from src.webapps.admin import route_admin from src.webapps.admin import route_admin
from src.webapps.auth import route_login from src.webapps.auth import route_login
from src.webapps.comic import route_comics, route_worktype, route_artists from src.webapps.comic import route_comics, route_worktype, route_artists
from src.webapps.media import route_actors, route_lofi, route_media, route_videos from src.webapps.media import route_actors, route_media, route_videos
templates = Jinja2Templates(directory="src/templates") templates = Jinja2Templates(directory="src/templates")
@@ -15,7 +15,6 @@ api_router.include_router(route_worktype.router, tags=["webapp"])
api_router.include_router(route_media.router, tags=["webapp"]) api_router.include_router(route_media.router, tags=["webapp"])
api_router.include_router(route_actors.router, tags=["webapp"]) api_router.include_router(route_actors.router, tags=["webapp"])
api_router.include_router(route_videos.router, tags=["webapp"]) api_router.include_router(route_videos.router, tags=["webapp"])
api_router.include_router(route_lofi.router, tags=["webapp"])
api_router.include_router(route_login.router, tags=["webapp"]) api_router.include_router(route_login.router, tags=["webapp"])
api_router.include_router(route_admin.router, tags=["webapp"]) api_router.include_router(route_admin.router, tags=["webapp"])
@@ -8,6 +8,7 @@ from typing import AnyStr
from src.db.repository.comics.artist import update_artist from src.db.repository.comics.artist import update_artist
from src.db.session import SessionDep from src.db.session import SessionDep
#from src.db.repository.comic import create_new_worktype, update_worktype #from src.db.repository.comic import create_new_worktype, update_worktype
from src.main import logger
from src.schema.comics.artist import AddArtist from src.schema.comics.artist import AddArtist
from src.webapps.comic.forms.artist import AddArtistForm from src.webapps.comic.forms.artist import AddArtistForm
@@ -34,7 +35,7 @@ def edit_artist(db: SessionDep, request: Request, artist_id: str):
return templates.TemplateResponse("comic/artist_edit.html", {"request": request, "artist_name": artist.name, "artist_link": artist.weblink}) return templates.TemplateResponse("comic/artist_edit.html", {"request": request, "artist_name": artist.name, "artist_link": artist.weblink})
@router.post("/artist/edit/{artist_id}") @router.post("/artist/edit/{artist_id}")
async def edit_artist_post(request: Request, db: SessionDep, artist_id: str, action: str = Form(...), artist_name: str = Form(...), artist_link: str = Form(...)): async def edit_artist(request: Request, db: SessionDep, artist_id: str, action: str = Form(...), artist_name: str = Form(...), artist_link: str = Form(...)):
if action == "cancel": if action == "cancel":
return RedirectResponse(f"/comic/artists/{artist_id}", status_code=status.HTTP_303_SEE_OTHER) return RedirectResponse(f"/comic/artists/{artist_id}", status_code=status.HTTP_303_SEE_OTHER)
form = AddArtistForm(request, artist_id, artist_name, artist_link) form = AddArtistForm(request, artist_id, artist_name, artist_link)
@@ -1,61 +0,0 @@
from typing import Optional
from fastapi import APIRouter, Request, status, responses, Query
from fastapi.security.utils import get_authorization_scheme_param
from fastapi.templating import Jinja2Templates
from src.core.config import Settings
from src.core.security import get_current_user_from_token
from src.db.models.media import MediaLofi
from src.db.models.admin import Profile
from src.db.repository.media.lofi import create_new_lofi
from src.db.session import SessionDep
from src.webapps.media.forms import AddLinkForm
templates = Jinja2Templates(directory="src/templates")
router = APIRouter(include_in_schema=False, prefix="/media")
@router.get("/lofis")
def get_medialofis(db: SessionDep, request: Request, msg: Optional[str] = None, review: Optional[bool] = Query(default=False), download: Optional[bool] = Query(default=False)):
medialofis = db.query(MediaLofi).all()
try:
token = request.cookies.get("access_token")
_, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value
current_user: Profile = get_current_user_from_token(token=param)
request.params.get("review")
return templates.TemplateResponse("media/lofi_list.html", {
"request": request,
"msg": msg,
"user": current_user,
"version": Settings.PROJECT_VERSION,
"review": review,
"download": download,
"medialofis": medialofis,
})
except Exception as e:
print(e)
return templates.TemplateResponse("media/lofi_list.html", {"request": request, "msg": msg, "user": None, "medialofis": medialofis})
@router.get("/lofis/{lofi_id}")
def lofi_details(lofi_id: str, request: Request, db: SessionDep):
medialofi = db.get(MediaLofi, lofi_id)
return templates.TemplateResponse("media/lofi_detail.html", {"request": request, "medialofi":medialofi})
@router.get("/lofis/add")
def add_lofi_link(request: Request, db: SessionDep):
return templates.TemplateResponse("media/add_lofi_link.html", {"request": request})
@router.post("/lofis/add")
async def post_lofi_link(request: Request, db: SessionDep):
form = AddLinkForm(request)
await form.load_data()
if form.is_valid():
try:
#video = AddLink(**form.__dict__)
medialofi = create_new_lofi(url=str(form.url), db=db)
return responses.RedirectResponse(f"media/lofi/{medialofi.id}", status_code=status.HTTP_302_FOUND)
except Exception as e:
print(e)
form.__dict__.get("errors").append("Link already added")
return templates.TemplateResponse("media/add_lofi_link.html", form.__dict__)
return templates.TemplateResponse("media/add_lofi_link.html", form.__dict__)
+1 -1
View File
@@ -37,7 +37,7 @@ def get_mediafiles(db: SessionDep, request: Request, msg: str | None = None):
try: try:
token = request.cookies.get("access_token") token = request.cookies.get("access_token")
scheme, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value scheme, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value
#current_user: Profile = get_current_user_from_token(token=param) current_user: Profile = get_current_user_from_token(token=param)
return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": mediafiles}) return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": mediafiles})
except Exception as e: except Exception as e:
print(e) print(e)
+3 -5
View File
@@ -1,5 +1,3 @@
from typing import Optional
from fastapi import APIRouter, Request, status, responses from fastapi import APIRouter, Request, status, responses
from fastapi.security.utils import get_authorization_scheme_param from fastapi.security.utils import get_authorization_scheme_param
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
@@ -15,12 +13,12 @@ templates = Jinja2Templates(directory="src/templates")
router = APIRouter(include_in_schema=False, prefix="/media") router = APIRouter(include_in_schema=False, prefix="/media")
@router.get("/videos") @router.get("/videos")
def get_mediavideos(db: SessionDep, request: Request, msg: Optional[str] = None): def get_mediavideos(db: SessionDep, request: Request, msg: str = None):
mediavideos = db.query(MediaVideo).all() mediavideos = db.query(MediaVideo).all()
try: try:
token = request.cookies.get("access_token") token = request.cookies.get("access_token")
_, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value _, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value
current_user: Profile = get_current_user_from_token(token=param) current_user: Profile = get_current_user_from_token(token=param, db=db)
return templates.TemplateResponse("media/videos.html", {"request": request, "msg": msg, "user": current_user, "mediavideos": mediavideos}) return templates.TemplateResponse("media/videos.html", {"request": request, "msg": msg, "user": current_user, "mediavideos": mediavideos})
except Exception as e: except Exception as e:
print(e) print(e)
@@ -42,7 +40,7 @@ async def post_video_link(request: Request, db: SessionDep):
if form.is_valid(): if form.is_valid():
try: try:
#video = AddLink(**form.__dict__) #video = AddLink(**form.__dict__)
mediavideo = create_new_video(url=str(form.url), db=db) mediavideo = create_new_video(video=form, db=db)
return responses.RedirectResponse(f"media/videos/{mediavideo.id}", status_code=status.HTTP_302_FOUND) return responses.RedirectResponse(f"media/videos/{mediavideo.id}", status_code=status.HTTP_302_FOUND)
except Exception as e: except Exception as e:
print(e) print(e)
+460 -1130
View File
File diff suppressed because it is too large Load Diff
+73
View File
@@ -0,0 +1,73 @@
[versions]
gradle = "8.6"
args4j = "2.33"
commonscli = "1.5.0"
junit = "5.8.2"
logback = "1.1.2"
mockito = "1.9.5"
picoli = "4.7.0"
slf4j = "1.7.22"
hsqldb = "2.7.1"
sqlite = "3.25.2"
spotbugs = "6.0.7"
asciidoctor = "4.0.2"
rouge = "3.15.0"
#diagram = "2.2.2"
diagram = "2.3.1"
sonarqube = "3.3"
cimtConventions = "1.0.0-SNAPSHOT"
springboot = "3.2.5"
springdependencies = "1.1.4"
vaadin = "24.3.8"
camel = "4.10.6"
artemis = "2.41.0"
lombok = "8.6"
gson = "2.9.0"
jackson = "2.16.1"
json_simple = "1.1.1"
mail = "1.6.2"
hypersistence = "3.9.10"
[libraries]
args4j = { module = "args4j:args4j", version.ref = "args4j" }
commonscli = { module = "commons-cli:commons-cli", version.ref = "commonscli" }
junit = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
logbackCore = { module = "ch.qos.logback:logback-core", version.ref = "logback" }
logbackClassic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
mockito = { module = "org.mockito:mockito-all", version.ref = "mockito" }
picocli = { module = "info.picocli:picocli", version.ref = "picoli" }
slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
jackson = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
json = { module = "com.googlecode.json-simple:json-simple", version.ref ="json_simple" }
mail = { module = "com.sun.mail:javax.mail", version.ref ="mail" }
sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" }
hypersistence = { module = "io.hypersistence:hypersistence-utils-hibernate-63", version.ref = "hypersistence" }
vaadin-bom = { module = "com.vaadin:vaadin-bom", version.ref = "vaadin" }
camel-bom = { module = "org.apache.camel.springboot:camel-spring-boot-bom", version.ref = "camel"}
spring-data = { module = "org.springframework.data:spring-data-jpa", version.ref = "springboot" }
artemis = { module = "org.apache.activemq:artemis-jms-server", version.ref = "artemis" }
asciidoctorGradleJvmGems = { module = "org.asciidoctor:asciidoctor-gradle-jvm-gems", version.ref= "asciidoctor" }
asciidoctorGradleJvm = { module = "org.asciidoctor:asciidoctor-gradle-jvm", version.ref= "asciidoctor" }
asciidoctorGradleJvmPdf = { module = "org.asciidoctor:asciidoctor-gradle-jvm-pdf", version.ref= "asciidoctor" }
rouge = { module = "rubygems:rouge", version.ref = "rouge" }
diagram = { module = "rubygems:asciidoctor-diagram", version.ref = "diagram" }
[bundles]
logback = ["logbackCore", "logbackClassic"]
[plugins]
spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugs" }
sonarqube = { id = "org.sonarqube", version.ref = "sonarqube" }
asciidoctorPdf = { id = "org.asciidoctor.jvm.pdf", version.ref = "asciidoctor" }
asciidoctorConvert = { id = "org.asciidoctor.jvm.convert", version.ref = "asciidoctor" }
asciidoctorGems = { id = "org.asciidoctor.jvm.gems", version.ref = "asciidoctor" }
javaConvention = { id = "de.cimt.java-conventions", version.ref = "cimtConventions" }
applicationConvention = { id = "de.cimt.application-conventions", version.ref = "cimtConventions" }
libraryConvention = { id = "de.cimt.library-conventions", version.ref = "cimtConventions" }
asciidoctorConvention = { id = "de.cimt.asciidoctor-conventions", version.ref = "cimtConventions" }
spring-boot = { id = "org.springframework.boot", version.ref = "springboot"}
spring-dependencies = { id = "io.spring.dependency-management", version.ref = "springdependencies" }
vaadin = { id = "com.vaadin", version.ref = "vaadin" }
lombok = { id = "io.freefair.lombok", version.ref = "lombok" }
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+248
View File
@@ -0,0 +1,248 @@
#!/bin/sh
#
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored Executable
+82
View File
@@ -0,0 +1,82 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables, and ensure extensions are enabled
setlocal EnableExtensions
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
"%COMSPEC%" /c exit 1
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
"%COMSPEC%" /c exit 1
:execute
@rem Setup the command line
@rem Execute Gradle
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:exitWithErrorLevel
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
"%COMSPEC%" /c exit %ERRORLEVEL%
+24
View File
@@ -0,0 +1,24 @@
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == 'org.springframework.boot') {
useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}")
}
if (requested.id.id == 'org.gradle.toolchains.foojay-resolver') {
useModule("org.gradle.toolchains.foojay-resolver-convention:0.4.0")
}
}
}
repositories {
gradlePluginPortal()
mavenCentral()
maven { setUrl("https://maven.vaadin.com/vaadin-prereleases") }
maven { setUrl("https://repo.spring.io/milestone") }
maven { url 'https://plugins.gradle.org/m2/' }
}
// plugins {
// id 'com.vaadin' version "${vaadinVersion}"
// }
}
rootProject.name = 'kontor-spring'
+1 -1
View File
@@ -1,7 +1,7 @@
# This file was generated by the Gradle 'init' task. # This file was generated by the Gradle 'init' task.
# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties # https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties
description='Kontor Documentation' description='Kontor Documentation'
version=0.4.0-SNAPSHOT version=0.3.0-SNAPSHOT
group=de.thpeetz group=de.thpeetz
org.gradle.configuration-cache=true org.gradle.configuration-cache=true
-13
View File
@@ -1,13 +0,0 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-echo:$kontorVersion"
buildah build -t kontor-echo:$kontorVersion kontor-echo
+1 -3
View File
@@ -1,5 +1,5 @@
# ---------- Stage 1: Build ---------- # ---------- Stage 1: Build ----------
FROM docker.io/library/golang:1.26-alpine AS builder FROM docker.io/library/golang:1.25-alpine AS builder
# Set the working directory # Set the working directory
WORKDIR /app WORKDIR /app
# Ensure a portable, static-ish binary # Ensure a portable, static-ish binary
@@ -20,7 +20,5 @@ WORKDIR /app
RUN apk add --no-cache ca-certificates tzdata curl RUN apk add --no-cache ca-certificates tzdata curl
# Copy the binary and set ownership # Copy the binary and set ownership
COPY --from=builder /app/kontor /app/kontor COPY --from=builder /app/kontor /app/kontor
COPY --from=builder /app/views /app/views
COPY --from=builder /app/static /app/static
# Set the entrypoint command # Set the entrypoint command
ENTRYPOINT ["/app/kontor"] ENTRYPOINT ["/app/kontor"]
-13
View File
@@ -1,13 +0,0 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-fiber:$kontorVersion"
buildah build -t kontor-fiber:$kontorVersion kontor-fiber
+9 -28
View File
@@ -3,15 +3,11 @@ package main
import ( import (
"kontor-api-fiber/pkg/handler" "kontor-api-fiber/pkg/handler"
"kontor-api-fiber/pkg/schema" "kontor-api-fiber/pkg/schema"
"kontor-api-fiber/pkg/web"
"log" "log"
"time"
jwtware "github.com/gofiber/contrib/v3/jwt" jwtware "github.com/gofiber/contrib/jwt"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v3/middleware/logger" "github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v3/middleware/static"
"github.com/gofiber/template/html/v3"
) )
func main() { func main() {
@@ -20,39 +16,24 @@ func main() {
if err := schema.Connect(); err != nil { if err := schema.Connect(); err != nil {
log.Fatal(err) log.Fatal(err)
} }
// Create a new engine
engine := html.New("./views", ".html")
app := fiber.New(fiber.Config{ app := fiber.New()
Views: engine,
ViewsLayout: "layouts/main", // app.Use(jwtware.New(jwtware.Config{
}) // SigningKey: jwtware.SigningKey{Key: []byte("secret")},
// }))
//app.Use(logger.New()) //app.Use(logger.New())
app.Get("/health", handler.GetHealth) app.Get("/health", handler.GetHealth)
app.Post("/login", handler.Login) app.Post("/login", handler.Login)
web.SetupRoutes(app)
//api := app.Group("/api/v1") api := app.Group("/api", logger.New(), jwtware.New(jwtware.Config{
api := app.Group("/api/v1", logger.New(), jwtware.New(jwtware.Config{
SigningKey: jwtware.SigningKey{Key: []byte("secret")}, SigningKey: jwtware.SigningKey{Key: []byte("secret")},
})) }))
api.Use(logger.New()) api.Use(logger.New())
handler.SetupComicRoutes(api) handler.SetupComicRoutes(api)
handler.SetupMediaRoutes(api) handler.SetupMediaRoutes(api)
app.Get("/*", static.New("./static", static.Config{
Browse: false,
MaxAge: 3600,
CacheDuration: 10 * time.Second,
NotFoundHandler: func(c fiber.Ctx) error {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
"error": "asset not found",
"path": c.Path(),
})
},
}))
// Listen on port 8900 // Listen on port 8900
app.Listen(":8500") app.Listen(":8500")
+28 -45
View File
@@ -1,59 +1,42 @@
module kontor-api-fiber module kontor-api-fiber
go 1.26.0 go 1.24.2
require (
github.com/gofiber/contrib/jwt v1.1.2
github.com/gofiber/fiber/v3 v3.5.0
github.com/gofiber/template/html/v3 v3.0.9
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/google/uuid v1.6.0
github.com/stretchr/testify v1.12.1
github.com/uptrace/bun v1.2.18
github.com/uptrace/bun/dialect/pgdialect v1.2.18
github.com/uptrace/bun/driver/pgdriver v1.2.18
github.com/uptrace/bun/extra/bundebug v1.2.18
golang.org/x/crypto v0.57.0
)
require ( require (
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
github.com/andybalholm/brotli v1.2.4 // indirect github.com/andybalholm/brotli v1.2.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/fatih/color v1.19.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.4.4 // indirect github.com/fatih/color v1.18.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/gofiber/contrib/jwt v1.1.2 // indirect
github.com/gofiber/contrib/v3/jwt v1.2.4 // indirect github.com/gofiber/fiber/v2 v2.52.10 // indirect
github.com/gofiber/fiber/v2 v2.52.15 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/gofiber/schema v1.8.7 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gofiber/template/v2 v2.1.2 // indirect
github.com/gofiber/utils/v2 v2.5.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/klauspost/compress v1.20.0 // indirect github.com/joho/godotenv v1.5.1 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect github.com/klauspost/compress v1.18.1 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-runewidth v0.0.30 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/molecule-man/go-brrr v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/philhofer/fwd v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
github.com/tinylib/msgp v1.6.4 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/uptrace/bun v1.2.16 // indirect
github.com/uptrace/bun/dialect/pgdialect v1.2.16 // indirect
github.com/uptrace/bun/driver/pgdriver v1.2.16 // indirect
github.com/uptrace/bun/extra/bundebug v1.2.16 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.74.0 // indirect github.com/valyala/fasthttp v1.68.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.38.0 // indirect
go.opentelemetry.io/otel v1.46.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect
go.opentelemetry.io/otel/metric v1.46.0 // indirect golang.org/x/crypto v0.45.0 // indirect
go.opentelemetry.io/otel/trace v1.46.0 // indirect golang.org/x/sys v0.39.0 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
golang.org/x/mod v0.41.0 // indirect
golang.org/x/net v0.59.0 // indirect
golang.org/x/sync v0.23.0 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.42.0 // indirect
golang.org/x/tools v0.49.0 // indirect
mellium.im/sasl v0.3.2 // indirect mellium.im/sasl v0.3.2 // indirect
) )
+56 -102
View File
@@ -1,144 +1,98 @@
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k= github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k= github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k=
github.com/andybalholm/brotli v1.2.2 h1:HzTuoo2ErYQqf5qvcJInB8uvqSVxRttzkFexPWtnceM= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.2.2/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
github.com/andybalholm/brotli v1.2.4 h1:649LN6qF+/7JJYNN3Wdu4Dt5PS6eC/yP/Go3Bb0/AHI= github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/andybalholm/brotli v1.2.4/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q=
github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/gofiber/contrib/jwt v1.1.2 h1:GmWnOqT4A15EkA8IPXwSpvNUXZR4u5SMj+geBmyLAjs= github.com/gofiber/contrib/jwt v1.1.2 h1:GmWnOqT4A15EkA8IPXwSpvNUXZR4u5SMj+geBmyLAjs=
github.com/gofiber/contrib/jwt v1.1.2/go.mod h1:CpIwrkUQ3Q6IP8y9n3f0wP9bOnSKx39EDp2fBVgMFVk= github.com/gofiber/contrib/jwt v1.1.2/go.mod h1:CpIwrkUQ3Q6IP8y9n3f0wP9bOnSKx39EDp2fBVgMFVk=
github.com/gofiber/contrib/v3/jwt v1.2.4 h1:0cApE/65Nb+AV49zMjun2+vXE1pCdZWLdg1z3IxmrPI= github.com/gofiber/fiber v1.14.6 h1:QRUPvPmr8ijQuGo1MgupHBn8E+wW0IKqiOvIZPtV70o=
github.com/gofiber/contrib/v3/jwt v1.2.4/go.mod h1:ARfFxE8uxUeV5hzq9qUaSCBWkpYmGpvAL/XU3NBpkRA= github.com/gofiber/fiber v1.14.6/go.mod h1:Yw2ekF1YDPreO9V6TMYjynu94xRxZBdaa8X5HhHsjCM=
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI= github.com/gofiber/fiber/v2 v2.52.10 h1:jRHROi2BuNti6NYXmZ6gbNSfT3zj/8c0xy94GOU5elY=
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= github.com/gofiber/fiber/v2 v2.52.10/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
github.com/gofiber/fiber/v2 v2.52.15 h1:Cov1uKeVPyu9q0jSrN60W+A8XNX+/WK8J7cy5osHLIk= github.com/gofiber/utils v0.0.10/go.mod h1:9J5aHFUIjq0XfknT4+hdSMG6/jzfaAgCu4HEbWDeBlo=
github.com/gofiber/fiber/v2 v2.52.15/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
github.com/gofiber/fiber/v3 v3.5.0 h1:dk7TOUH6DXJGtOLsN2XEG+0ZML7cznzHILTVozbNEK8= github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
github.com/gofiber/fiber/v3 v3.5.0/go.mod h1:GOVDTW+gjJvfe0iJyVujbQ1Lnx+JUjFySJRI/9/xX/w=
github.com/gofiber/schema v1.8.3 h1:06ZedxIYjngzc0095PYy7uWnFnbRflWFpikvZH61fDc=
github.com/gofiber/schema v1.8.3/go.mod h1:jWnnZdhcW1mHyV+VnfRxKJDPNcepJsTZ9RIWxrr32Ng=
github.com/gofiber/schema v1.8.7 h1:7cSagr2ObiUVFuitCOqjKMqIhV+oVbkanP4Ge/wHsnI=
github.com/gofiber/schema v1.8.7/go.mod h1:fBz4T6uOepH3L+dYlz/yzQ0bFHPnfExkp/B3Qrk2VBI=
github.com/gofiber/template/html/v3 v3.0.9 h1:oVgrQIGSe7DcufnD823KwLsUnIgtCDGhznj1kMfNB2I=
github.com/gofiber/template/html/v3 v3.0.9/go.mod h1:Nk2HJlZYaCd0oVEwQd8v+1M+gmweub6dEAeS07WhL6o=
github.com/gofiber/template/v2 v2.1.2 h1:fZTpavK0Yi1ehJGrL9UXzBrOnowZfPpIZwxfiIftXBs=
github.com/gofiber/template/v2 v2.1.2/go.mod h1:h8vOKQkwFUFRNTvRcIvt/OgVUOVqHsaEviWTOAh2JqQ=
github.com/gofiber/utils/v2 v2.5.2 h1:bX+iACKsCGm2+dW7jvkYSiWIsBaKqFy5slFSxJSIL/s=
github.com/gofiber/utils/v2 v2.5.2/go.mod h1:EaVDjy4JJv0m0lg6x4owJ1GG8j1pMO8XriqCgVns1ZQ=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-runewidth v0.0.30 h1:+KUuiDA4fF0R1p5FeueHefjDm+GIM+kWfFnDjybOPgk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/mattn/go-runewidth v0.0.30/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/molecule-man/go-brrr v1.0.1 h1:cEjgx8hgNw6UGdhQ94SPDbPkKuRbkUcxBO3IzbGpA/o=
github.com/molecule-man/go-brrr v1.0.1/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4=
github.com/molecule-man/go-brrr v1.1.0 h1:rLBGSXA393y+5ttCBLkW34CHESop5tahrOFxVv/XDEU=
github.com/molecule-man/go-brrr v1.1.0/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4=
github.com/molecule-man/go-brrr v1.1.1 h1:KYwusQhjtV3smALnhmafZf4OBrh7vP4p8O47DyUmmuY=
github.com/molecule-man/go-brrr v1.1.1/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4=
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg= github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/shamaton/msgpack/v3 v3.2.3 h1:0r0aZtrXDFOPpwWJTEOpFq+Ih/JmMLm0pqLN5mSilrw= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/shamaton/msgpack/v3 v3.2.3/go.mod h1:sgBYvEiyz8JR1NC3yGRoPVME9xXovpnh3l/plW1nfRo= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ=
github.com/tinylib/msgp v1.6.4/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
github.com/uptrace/bun v1.2.16 h1:QlObi6ZIK5Ao7kAALnh91HWYNZUBbVwye52fmlQM9kc= github.com/uptrace/bun v1.2.16 h1:QlObi6ZIK5Ao7kAALnh91HWYNZUBbVwye52fmlQM9kc=
github.com/uptrace/bun v1.2.16/go.mod h1:jMoNg2n56ckaawi/O/J92BHaECmrz6IRjuMWqlMaMTM= github.com/uptrace/bun v1.2.16/go.mod h1:jMoNg2n56ckaawi/O/J92BHaECmrz6IRjuMWqlMaMTM=
github.com/uptrace/bun v1.2.18 h1:3HnRcMfS6OBPMG1eSOzlbFJ/X/AyMEJb7rMxE6VQvDU=
github.com/uptrace/bun v1.2.18/go.mod h1:wNltaKJk4JtOt4SG5I5zmA7v0/Mzjh1+/S906Rayd3Y=
github.com/uptrace/bun/dialect/pgdialect v1.2.16 h1:KFNZ0LxAyczKNfK/IJWMyaleO6eI9/Z5tUv3DE1NVL4= github.com/uptrace/bun/dialect/pgdialect v1.2.16 h1:KFNZ0LxAyczKNfK/IJWMyaleO6eI9/Z5tUv3DE1NVL4=
github.com/uptrace/bun/dialect/pgdialect v1.2.16/go.mod h1:IJdMeV4sLfh0LDUZl7TIxLI0LipF1vwTK3hBC7p5qLo= github.com/uptrace/bun/dialect/pgdialect v1.2.16/go.mod h1:IJdMeV4sLfh0LDUZl7TIxLI0LipF1vwTK3hBC7p5qLo=
github.com/uptrace/bun/dialect/pgdialect v1.2.18 h1:IZ6nM2+OYrL8lkEAy7UkSEZvoa3vluTAUlZfPtlRB2k=
github.com/uptrace/bun/dialect/pgdialect v1.2.18/go.mod h1:Tqdf4QP1okrGYpXfodXvCOK6Ob1OOTwSaoAzCgBB3IU=
github.com/uptrace/bun/driver/pgdriver v1.2.16 h1:b1kpXKUxtTSGYow5Vlsb+dKV3z0R7aSAJNfMfKp61ZU= github.com/uptrace/bun/driver/pgdriver v1.2.16 h1:b1kpXKUxtTSGYow5Vlsb+dKV3z0R7aSAJNfMfKp61ZU=
github.com/uptrace/bun/driver/pgdriver v1.2.16/go.mod h1:H6lUZ9CBfp1X5Vq62YGSV7q96/v94ja9AYFjKvdoTk0= github.com/uptrace/bun/driver/pgdriver v1.2.16/go.mod h1:H6lUZ9CBfp1X5Vq62YGSV7q96/v94ja9AYFjKvdoTk0=
github.com/uptrace/bun/driver/pgdriver v1.2.18 h1:Zojuc83ulApocXomBLEcx1DqCZweREafHCjPfyXo88I=
github.com/uptrace/bun/driver/pgdriver v1.2.18/go.mod h1:ZRJcARw93nxbQ5WawTrc5EO+F+GygkcYgDLEnT17CcE=
github.com/uptrace/bun/extra/bundebug v1.2.16 h1:3OXAfHTU4ydu2+4j05oB1BxPx6+ypdWIVzTugl/7zl0= github.com/uptrace/bun/extra/bundebug v1.2.16 h1:3OXAfHTU4ydu2+4j05oB1BxPx6+ypdWIVzTugl/7zl0=
github.com/uptrace/bun/extra/bundebug v1.2.16/go.mod h1:vk6R/1i67/S2RvUI5AH/m3P5e67mOkfDCmmCsAPUumo= github.com/uptrace/bun/extra/bundebug v1.2.16/go.mod h1:vk6R/1i67/S2RvUI5AH/m3P5e67mOkfDCmmCsAPUumo=
github.com/uptrace/bun/extra/bundebug v1.2.18 h1:5cgkqdvhpSHIEONazSytm4RWYFneNtcznaWLt6r8m4M=
github.com/uptrace/bun/extra/bundebug v1.2.18/go.mod h1:M+U9YJVJcmk0RrszCb2Q1oskJiJ0LuC44FxDhZLP1ws=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.73.0 h1:ocTOORnBWtJ+P8t/6wAjdkchMzdfHmWx2VD/DPbgZ7s= github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
github.com/valyala/fasthttp v1.73.0/go.mod h1:EtXQDHaR+5P18p8wqDRFpUhxr108Ga9mXvVJXHRrN2k= github.com/valyala/fasthttp v1.68.0 h1:v12Nx16iepr8r9ySOwqI+5RBJ/DqTxhOy1HrHoDFnok=
github.com/valyala/fasthttp v1.74.0 h1:wMS9fnO2QTALozYx5pId2Vi7ZwU/epUkY8i/KPWCHoU= github.com/valyala/fasthttp v1.68.0/go.mod h1:5EXiRfYQAoiO/khu4oU9VISC/eVY6JqmSpPJoHCKsz4=
github.com/valyala/fasthttp v1.74.0/go.mod h1:3ARmLamUcw7ElxVtC8PXaGzQ6VEuvnetlkrwIklQBSE= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc=
go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE=
go.opentelemetry.io/otel/metric v1.46.0/go.mod h1:iPmdWqifKUdzziPkvvzIJXITl56fQx2mGM/DHLB3/2o=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.opentelemetry.io/otel/trace v1.46.0 h1:OULy7ccdJnZtJ0UDYFOIGaCmiWzJ8Vi2G/Rsu60qs1c= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
go.opentelemetry.io/otel/trace v1.46.0/go.mod h1:J7GAXweO77XSFkB/rmAqk9D6ihszhFjLU+d9WuUxDLI= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0= mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0=
mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY= mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY=
+3 -3
View File
@@ -5,12 +5,12 @@ import (
"kontor-api-fiber/pkg/schema" "kontor-api-fiber/pkg/schema"
"kontor-api-fiber/pkg/utils" "kontor-api-fiber/pkg/utils"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v2"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
func Login(c fiber.Ctx) error { func Login(c *fiber.Ctx) error {
user := c.FormValue("user") user := c.FormValue("user")
pass := c.FormValue("pass") pass := c.FormValue("pass")
@@ -39,7 +39,7 @@ func Login(c fiber.Ctx) error {
return c.JSON(fiber.Map{"token": token}) return c.JSON(fiber.Map{"token": token})
} }
func Restricted(c fiber.Ctx) error { func Restricted(c *fiber.Ctx) error {
user := c.Locals("user").(*jwt.Token) user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims) claims := user.Claims.(jwt.MapClaims)
name := claims["name"].(string) name := claims["name"].(string)
+4 -4
View File
@@ -5,7 +5,7 @@ import (
"kontor-api-fiber/pkg/schema" "kontor-api-fiber/pkg/schema"
"log" "log"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v2"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
@@ -16,7 +16,7 @@ func SetupComicRoutes(api fiber.Router) {
comics.Get("/comicworks", GetAllComicWorks) comics.Get("/comicworks", GetAllComicWorks)
} }
func GetAllComics(c fiber.Ctx) error { func GetAllComics(c *fiber.Ctx) error {
var comics []schema.Comic var comics []schema.Comic
var err error var err error
var db *bun.DB var db *bun.DB
@@ -36,7 +36,7 @@ func GetAllComics(c fiber.Ctx) error {
return c.JSON(comics) return c.JSON(comics)
} }
func GetAllPublishers(c fiber.Ctx) error { func GetAllPublishers(c *fiber.Ctx) error {
var publishers []schema.Publisher var publishers []schema.Publisher
var err error var err error
var db *bun.DB var db *bun.DB
@@ -56,7 +56,7 @@ func GetAllPublishers(c fiber.Ctx) error {
return c.JSON(publishers) return c.JSON(publishers)
} }
func GetAllComicWorks(c fiber.Ctx) error { func GetAllComicWorks(c *fiber.Ctx) error {
var comic_works []schema.ComicWork var comic_works []schema.ComicWork
var err error var err error
var db *bun.DB var db *bun.DB
+2 -2
View File
@@ -1,8 +1,8 @@
package handler package handler
import "github.com/gofiber/fiber/v3" import "github.com/gofiber/fiber/v2"
func GetHealth(c fiber.Ctx) error { func GetHealth(c *fiber.Ctx) error {
return c.Status(200).JSON(&fiber.Map{ return c.Status(200).JSON(&fiber.Map{
"status": "ok", "status": "ok",
}) })
+3 -3
View File
@@ -8,7 +8,7 @@ import (
"log" "log"
"time" "time"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v2"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
@@ -19,7 +19,7 @@ func SetupMediaRoutes(api fiber.Router) {
media.Post("/files", AddFile) media.Post("/files", AddFile)
} }
func GetAllFiles(c fiber.Ctx) error { func GetAllFiles(c *fiber.Ctx) error {
var files []schema.MediaFile var files []schema.MediaFile
var err error var err error
var db *bun.DB var db *bun.DB
@@ -38,7 +38,7 @@ func GetAllFiles(c fiber.Ctx) error {
return c.JSON(files) return c.JSON(files)
} }
func AddFile(c fiber.Ctx) error { func AddFile(c *fiber.Ctx) error {
var err error var err error
var db *bun.DB var db *bun.DB
ctx := context.Background() ctx := context.Background()
-14
View File
@@ -24,20 +24,6 @@ type MediaFile struct {
MediaActorFiles []MediaActorFile `bun:"rel:has-many,join:id=media_file_id"` MediaActorFiles []MediaActorFile `bun:"rel:has-many,join:id=media_file_id"`
} }
type MediaLoFi struct {
bun.BaseModel `bun:"table:media_lofi"`
ID string `bun:"id,pk"`
CreatedAt time.Time `bun:"created_date,nullzero,notnull,default:current_timestamp"`
UpdatedAt time.Time `bun:"last_modified_date,nullzero,notnull,default:current_timestamp"`
Version int `bun:"version,default:0"`
WebLink string `bun:"url,unique:url"`
Review bool `bun:"review"`
ShouldDownload bool `bun:"should_download"`
Title string `bun:"title"`
FileName string `bun:"file_name"`
}
type MediaActor struct { type MediaActor struct {
bun.BaseModel `bun:"table:media_actor"` bun.BaseModel `bun:"table:media_actor"`
-9
View File
@@ -1,9 +0,0 @@
package web
import "github.com/gofiber/fiber/v3"
func Mainpage(c fiber.Ctx) error {
return c.Render("index", fiber.Map{
"Title": "Kontor Fiber",
})
}
-12
View File
@@ -1,12 +0,0 @@
package web
import (
"github.com/gofiber/fiber/v3"
)
func SetupRoutes(app *fiber.App) {
app.Get("/", Mainpage)
app.Get("/comic/comics", Mainpage)
app.Get("/media/files", Mainpage)
}
-172
View File
@@ -1,172 +0,0 @@
* {
box-sizing: border-box;
}
body {
font-family: Arial;
padding: 10px;
background: lightgrey;
}
/* Header/Blog Title */
.header {
padding: 30px;
text-align: center;
background-color: lightblue;
}
.header h1 {
font-size: 50px;
}
/* Style the top navigation bar */
.topnav {
overflow: hidden;
background-color: darkgrey;
}
/* Style the topnav links */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
/* Change color on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
.subnav {
overflow: hidden;
background-color: grey;
}
.subnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center;
padding-top: 10px;
padding-left: 20px;
}
.form-inline label {
margin: 5px 10px 5px 0;
}
.form-inline input {
padding-right: 50px;
margin-right: 10px;
}
.form-inline button {
padding: 10px 20px;
background-color: dodgerblue;
border: 1px solid #ddd;
color: white;
border-radius: 10px;
}
.form-inline button:hover {
background-color: royalblue;
}
.pill-nav a {
display: inline-block;
color: white;
background-color: dodgerblue;
text-align: center;
padding: 10px;
text-decoration: none;
border-radius: 10px;
margin-left: 20px;
}
/* Change the color of links on mouse-over */
.pill-nav a:hover {
background-color: royalblue;
color: white;
}
/* Add a color to the active/current link */
.pill-nav a.active {
background-color: royalblue;
color: white;
}
.maincolumn {
float:left;
width: 100%;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
float: left;
width: 75%;
}
/* Right column */
.rightcolumn {
float: left;
width: 25%;
background-color: #f1f1f1;
padding-left: 20px;
}
/* Fake image */
.fakeimg {
background-color: #aaa;
width: 100%;
padding: 20px;
}
/* Add a card effect for articles */
.card {
background-color: white;
padding: 20px;
margin-top: 20px;
}
/* Clear floats after the columns */
.row::after {
content: "";
display: table;
clear: both;
}
/* Footer */
.footer {
padding: 20px;
text-align: center;
background: #ddd;
margin-top: 20px;
}
/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 800px) {
.leftcolumn, .rightcolumn {
width: 100%;
padding: 0;
}
}
/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */
@media screen and (max-width: 400px) {
.topnav a {
float: none;
width: 100%;
}
}
-1
View File
@@ -1 +0,0 @@
<h1>{{.Title}}</h1>
-22
View File
@@ -1,22 +0,0 @@
<!doctype html>
<html lang="de-DE">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="/style/main.css" />
<title>{{.Title}}</title>
</head>
<body>
<div class="header">{{template "partials/header" .}}</div>
{{template "partials/navbar" .}}
<div class="content">{{embed}}</div>
<div class="footer">{{template "partials/footer" .}}</div>
</body>
</html>
-1
View File
@@ -1 +0,0 @@
<h2>Footer</h2>
-1
View File
@@ -1 +0,0 @@
<h2>Header</h2>
@@ -1,6 +0,0 @@
<div class="subnav">
<a href="/media/files/">MediaFiles</a>
<a href="/media/actors/">MediaActors</a>
<a href="/media/videos/">MediaVideos</a>
<a href="/media/lofi/">MediaLofi</a>
</div>

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