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
1318 changed files with 196313 additions and 51023 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
-42
View File
@@ -1,42 +0,0 @@
package main
import (
"context"
"kontor-api-echo/internal/config"
"kontor-api-echo/internal/handlers"
"kontor-api-echo/internal/router"
"kontor-api-echo/pkg/schema"
"log"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"github.com/labstack/echo/v5"
)
func main() {
slog.Info("Kontor started")
db, _ := schema.GetDatabase()
if err := config.InitConfig(); err != nil {
log.Fatalf("Failed to initialize config: %v", err)
}
e := router.New(handlers.NewAdminHandler(db), handlers.NewMediaHandler(db))
// Cancel the context on SIGINT / SIGTERM
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
sc := echo.StartConfig{
Address: ":1323",
GracefulTimeout: 10 * time.Second,
}
if err := sc.Start(ctx, e); err != nil {
e.Logger.Error("server stopped", "error", err)
}
slog.Info("Kontor finished")
}
+17 -46
View File
@@ -1,68 +1,39 @@
module kontor-api-echo module kontor-api-echo
go 1.26.0 go 1.24.2
require (
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/google/uuid v1.6.0
github.com/labstack/echo-jwt/v4 v4.4.0
github.com/labstack/echo-jwt/v5 v5.0.2
github.com/labstack/echo/v4 v4.15.0
github.com/labstack/echo/v5 v5.4.4
github.com/stretchr/testify v1.11.1
github.com/uptrace/bun v1.3.0
github.com/uptrace/bun/dialect/pgdialect v1.2.16
github.com/uptrace/bun/driver/pgdriver v1.2.16
golang.org/x/crypto v0.54.0
)
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/mattn/go-sqlite3 v1.14.34 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect
modernc.org/libc v1.68.0 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.46.1 // indirect
)
require ( require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect github.com/fatih/color v1.18.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/labstack/echo-jwt/v4 v4.4.0 // indirect
github.com/labstack/echo/v4 v4.15.0 // indirect
github.com/labstack/gommon v0.4.2 // indirect github.com/labstack/gommon v0.4.2 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
github.com/pmezard/go-difflib v1.0.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/sagikazarmark/locafero v0.12.0 // indirect github.com/stretchr/testify v1.11.1 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/pflag v1.1.0 // indirect
github.com/spf13/viper v1.21.0 // indirect
github.com/subosito/gotenv v1.6.0 // 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/dialect/sqlitedialect v1.3.0 github.com/uptrace/bun v1.2.16 // indirect
github.com/uptrace/bun/driver/sqliteshim v1.3.0 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/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // 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/otel v1.39.0 // indirect go.opentelemetry.io/otel v1.39.0 // indirect
go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/otel/trace v1.39.0 // indirect
go.yaml.in/yaml/v3 v3.0.6 // indirect golang.org/x/crypto v0.46.0 // indirect
golang.org/x/net v0.57.0 // indirect golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.49.0 // indirect golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.43.0 // indirect golang.org/x/text v0.32.0 // indirect
golang.org/x/time v0.16.0 // indirect golang.org/x/time v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
mellium.im/sasl v0.3.2 // indirect mellium.im/sasl v0.3.2 // indirect
) )
+18 -82
View File
@@ -1,88 +1,43 @@
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 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/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/labstack/echo-jwt/v4 v4.4.0 h1:nrXaEnJupfc2R4XChcLRDyghhMZup77F8nIzHnBK19U= github.com/labstack/echo-jwt/v4 v4.4.0 h1:nrXaEnJupfc2R4XChcLRDyghhMZup77F8nIzHnBK19U=
github.com/labstack/echo-jwt/v4 v4.4.0/go.mod h1:kYXWgWms9iFqI3ldR+HAEj/Zfg5rZtR7ePOgktG4Hjg= github.com/labstack/echo-jwt/v4 v4.4.0/go.mod h1:kYXWgWms9iFqI3ldR+HAEj/Zfg5rZtR7ePOgktG4Hjg=
github.com/labstack/echo-jwt/v5 v5.0.2 h1:ECmHEjwbR30fv90LvpQ0XZbEJWhCF/c3Zp8ug/iVrCE=
github.com/labstack/echo-jwt/v5 v5.0.2/go.mod h1:jNxekWlI4+M+UoV8dozKwIHN9MJ2psUR+U1B0nEutIg=
github.com/labstack/echo/v4 v4.15.0 h1:hoRTKWcnR5STXZFe9BmYun9AMTNeSbjHi2vtDuADJ24= github.com/labstack/echo/v4 v4.15.0 h1:hoRTKWcnR5STXZFe9BmYun9AMTNeSbjHi2vtDuADJ24=
github.com/labstack/echo/v4 v4.15.0/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c= github.com/labstack/echo/v4 v4.15.0/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c=
github.com/labstack/echo/v5 v5.4.4 h1:Nag9Mee0M9sOcKjProYuDNiw60QisysgfbIgz5US5Cw=
github.com/labstack/echo/v5 v5.4.4/go.mod h1:4iEGNQiPPZnkfYpNR/L6fINd3NLiGWUD5+eBotFALas=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 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-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk=
github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.1.0 h1:6W6MbVUrnMb8PEhjkqwsVLY7ryuzRfFHF4mQd7L94ag=
github.com/spf13/pflag v1.1.0/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
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.3.0 h1:hUcbfRpbQk4/upFSI+uZf6jSJw5A0lkIKt0XdpvbUZo=
github.com/uptrace/bun v1.3.0/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/sqlitedialect v1.3.0 h1:XzxkORYksxkLsIQLJHFYUb3yDvqSQHzTungyKpJhHTw=
github.com/uptrace/bun/dialect/sqlitedialect v1.3.0/go.mod h1:x2D1sY50Itio0I/FVdNe30oMUT2ObiAS+oILcMR+Wys=
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/sqliteshim v1.3.0 h1:T3ybxgmP8ejA99YULje9e12h+FqKKAP/4xZo3+X3mXA= github.com/uptrace/bun/extra/bundebug v1.2.16 h1:3OXAfHTU4ydu2+4j05oB1BxPx6+ypdWIVzTugl/7zl0=
github.com/uptrace/bun/driver/sqliteshim v1.3.0/go.mod h1:MqvqMCAAKNn6M0HF9YK/Z6xrnCP6sih5OZ37AxdAlHw= github.com/uptrace/bun/extra/bundebug v1.2.16/go.mod h1:vk6R/1i67/S2RvUI5AH/m3P5e67mOkfDCmmCsAPUumo=
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/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
@@ -95,38 +50,19 @@ go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
go.yaml.in/yaml/v3 v3.0.6 h1:zcDfvjXEqTQmpjniUBLc91xYJMB2c4QOFxEF/LCEckM= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
go.yaml.in/yaml/v3 v3.0.6/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0=
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc=
golang.org/x/text v0.43.0/go.mod h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s=
golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE=
golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
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=
modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ=
modernc.org/libc v1.68.0/go.mod h1:NnKCYeoYgsEqnY3PgvNgAeaJnso968ygU8Z0DxjoEc0=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/sqlite v1.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU=
modernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=
-163
View File
@@ -1,163 +0,0 @@
package config
import (
"errors"
"fmt"
"log/slog"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var (
CfgFile string
Verbose int
Overwrite bool
ServerName string
Mediatype MediaType
Config CliConfig
ServerConfig ServerConfiguration
DryRun bool
FileName string
)
const (
mediaTypeMedia MediaType = "media"
mediaTypeVideo MediaType = "video"
mediaTypeLofi MediaType = "lofi"
)
type MediaType string
func (e *MediaType) String() string {
return string(*e)
}
func (e *MediaType) Set(v string) error {
switch v {
case "media", "video", "lofi":
*e = MediaType(v)
return nil
default:
return errors.New(`must be one of "media", "video", "lofi"`)
}
}
func (e *MediaType) Type() string {
return "MediaType"
}
func myEnumCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{
"media\thelp text for media",
"video\thelp text for video",
"lofi\thelp text for lofi",
}, cobra.ShellCompDirectiveDefault
}
type Server struct {
Url string `mapstructure:"url"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
}
type Database struct {
Type string `mapstructure:"type" validate:"required"`
Path string `mapstructure:"path" validate:"required"`
Host string `mapstructure:"host" validate:"required"`
Name string `mapstructure:"name" validate:"required"`
Port int `mapstructure:"port" validate:"required"`
Password string `mapstructure:"password" validate:"required"`
User string `mapstructure:"user" validate:"required"`
}
type CliConfig struct {
ApiVersion string
Server map[string]Server `mapstructure:"server"`
DB Database `mapstructure:"db"`
}
type ServerConfiguration struct {
Server struct {
Port int `mapstructure:"port" validate:"required"`
Host string `mapstructure:"host"`
} `mapstructure:"server"`
DB Database `mapstructure:"db"`
Gin struct {
Mode string `mapstructure:"mode" validate:"required"`
} `mapstructure:"gin"`
ApiSecret []byte `mapstructure:"api_secret"`
}
func InitCliConfig() {
slog.Info("InitCliConfig")
if CfgFile != "" {
viper.SetConfigFile(CfgFile)
} else {
viper.SetConfigName("kli") // without extension
viper.SetConfigType("yaml")
viper.AddConfigPath(".") // look for config in working directory
viper.AddConfigPath("/home/tpeetz/.config")
}
Mediatype = mediaTypeMedia
// Read the configuration file
if err := viper.ReadInConfig(); err != nil {
// Handle the case where config file is not found
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
slog.Info("No config file found, using defaults")
if err := viper.SafeWriteConfig(); err != nil {
slog.Info("error writing config file", "error", err.Error())
}
} else {
slog.Info("error reading config file", "error", err.Error())
}
} else {
slog.Info("InitCliConfig", "Using config file: ", viper.ConfigFileUsed())
if err := viper.Unmarshal(&Config); err != nil {
slog.Info("parsing of config file failed", "error", err.Error())
}
}
}
func InitConfig() error {
viper.SetConfigName("kontor-gin")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath("/home/tpeetz/.config")
viper.AddConfigPath("/etc/kontor")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv()
viper.SetDefault("db.type", "postgres")
viper.SetDefault("db.host", "localhost")
viper.SetDefault("db.port", 5432)
viper.SetDefault("db.name", "kontor")
viper.SetDefault("db.user", "kontor")
viper.SetDefault("db.password", "kontor")
viper.SetDefault("db.path", "data/kontor.db")
viper.SetDefault("server.port", 8550)
viper.SetDefault("gin.mode", "release")
// Read the config file
if err := viper.ReadInConfig(); err != nil {
// Handle the case where config file is not found
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
slog.Info("No config file found, using defaults")
if err := viper.SafeWriteConfig(); err != nil {
slog.Info("error writing config file", "error", err.Error())
return fmt.Errorf("error writing config file: %w", err)
}
} else {
return fmt.Errorf("error reading config file: %w", err)
}
} else {
slog.Info("InitConfig", "Using config file: ", viper.ConfigFileUsed())
if err := viper.Unmarshal(&ServerConfig); err != nil {
slog.Info("parsing of config file failed", "error", err.Error())
}
}
return nil
}
-54
View File
@@ -1,54 +0,0 @@
package config
import (
"database/sql"
"fmt"
"log/slog"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/dialect/sqlitedialect"
"github.com/uptrace/bun/driver/pgdriver"
"github.com/uptrace/bun/driver/sqliteshim"
)
func NewDB(db Database) (*bun.DB, error) {
db_type := db.Type
slog.Info("using database", "type", db_type)
switch db_type {
case "postgres":
dsn := fmt.Sprintf("postgres://%s:%s@%s:%d/%s", db.User, db.Password, db.Host, db.Port, db.Name)
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
db := bun.NewDB(sqldb, pgdialect.New())
return db, nil
case "sqlite":
sqldb, _ := sql.Open(sqliteshim.ShimName, "file::memory:?cache=shared")
db := bun.NewDB(sqldb, sqlitedialect.New())
return db, nil
default:
return nil, fmt.Errorf("unknown db.type=%s", db_type)
}
// Configure GORM with custom settings
// The logger helps with debugging SQL queries during development
// if err != nil {
// log.Fatal("Failed to connect to database:", err)
// }
// // Get the underlying SQL database connection for pool configuration
// sqlDB, err := db.DB()
// if err != nil {
// log.Fatal("Failed to get database instance:", err)
// }
// // Configure connection pool settings
// // MaxIdleConns: number of connections kept open when idle
// sqlDB.SetMaxIdleConns(10)
// // MaxOpenConns: maximum total connections to the database
// sqlDB.SetMaxOpenConns(100)
// // ConnMaxLifetime: how long a connection can be reused
// sqlDB.SetConnMaxLifetime(time.Hour)
// slog.Info("Database connected successfully")
}
-39
View File
@@ -1,39 +0,0 @@
package globals
import (
"fmt"
)
var (
Secret = []byte("secret")
Version = "unset"
Commit = "unset"
Date = "unset"
)
const (
UserKey = "user"
MediaFileLink = "/media/files"
MediaLofiLink = "/media/lofis"
MediaMusicLink = "/media/musics"
MediaVideoLink = "/media/videos"
MediaArticleLink = "/media/articles"
MediaActorLink = "/media/actors"
)
func GetDefaultValues(user interface{}, message string) map[string]any {
values := map[string]any{
"title": "Kontor",
"version": fmt.Sprintf("%s %s", Version, Commit),
"message": message,
"user": user,
"media_file_link": MediaFileLink,
"media_lofi_link": MediaLofiLink,
"media_music_link": MediaMusicLink,
"media_video_link": MediaVideoLink,
"media_article_link": MediaArticleLink,
"media_actor_link": MediaActorLink,
}
return values
}
-28
View File
@@ -1,28 +0,0 @@
package handlers
import (
"github.com/uptrace/bun"
)
type AdminHandler struct {
AuthHandler *AuthHandler
ProfileHandler *ProfileHandler
PermissionHandler *PermissionHandler
AssignmentHandler *AssignmentHandler
TokenHandler *TokenHandler
MailAccountHandler *MailAccountHandler
MailHandler *MailHandler
}
func NewAdminHandler(db *bun.DB) *AdminHandler {
adminHandler := &AdminHandler{
AuthHandler: NewAuthHandler(db),
ProfileHandler: NewProfileHandler(db),
PermissionHandler: NewPermissionHandler(db),
AssignmentHandler: NewAssignmentHandler(db),
TokenHandler: NewTokenHandler(db),
MailAccountHandler: NewMailAccountHandler(db),
MailHandler: NewMailHandler(db),
}
return adminHandler
}
@@ -1,30 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type AssignmentHandler struct {
Service *service.AssignmentService
}
func NewAssignmentHandler(db *bun.DB) *AssignmentHandler {
handler := &AssignmentHandler{Service: service.NewAssignmentService(repository.NewAssignmentRepository(db))}
return handler
}
func (handler *AssignmentHandler) List(c *echo.Context) {
assignments, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertAssignmentsToDtos(assignments)
c.JSON(http.StatusOK, dtos)
}
-26
View File
@@ -1,26 +0,0 @@
package handlers
import "github.com/uptrace/bun"
type MediaHandler struct {
MediaArticleHandler *MediaArticleHandler
MediaActorHandler *MediaActorHandler
MediaFileHandler *MediaFileHandler
MediaLoFiHandler *MediaLoFiHandler
MediaMusicHandler *MediaMusicHandler
MediaVideoHandler *MediaVideoHandler
MediaActorFileHandler *MediaActorFileHandler
}
func NewMediaHandler(db *bun.DB) *MediaHandler {
mediaHandler := &MediaHandler{
MediaArticleHandler: NewMediaArticleHandler(db),
MediaActorHandler: NewMediaActorHandler(db),
MediaFileHandler: NewMediaFileHandler(db),
MediaLoFiHandler: NewMediaLoFiHandler(db),
MediaMusicHandler: NewMediaMusicHandler(db),
MediaVideoHandler: NewMediaVideoHandler(db),
MediaActorFileHandler: NewMediaActorFileHandler(db),
}
return mediaHandler
}
@@ -1,137 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/globals"
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type MediaActorHandler struct {
Service *service.MediaActorService
}
func NewMediaActorHandler(db *bun.DB) *MediaActorHandler {
mediaActorHandler := &MediaActorHandler{
Service: service.NewMediaActorService(repository.NewMediaActorRepository(db)),
}
return mediaActorHandler
}
func (handler *MediaActorHandler) List(c *echo.Context) {
lofis, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertMediaActorsToDtos(lofis)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaActorHandler) Get(c *echo.Context) {
id := c.Param("id")
actor, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "sport not found"})
return
}
c.JSON(http.StatusOK, actor)
}
func (handler *MediaActorHandler) Add(c *echo.Context) {
var input models.MediaActorAdd
if err := c.Bind(&input); err != nil {
c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
actor, err := handler.Service.Add(c.Request().Context(), input.WebLink)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not added"})
return
}
c.JSON(http.StatusOK, actor)
}
func (handler *MediaActorHandler) Delete(c *echo.Context) {
id := c.Param("id")
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "sport not found"})
return
}
c.JSON(http.StatusOK, map[string]string{"ok": "true"})
}
func (handler *MediaActorHandler) ListPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
actors, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
data := globals.GetDefaultValues(user, "MediaActors...")
data["actors"] = actors
c.Render(http.StatusOK, "media_actors", data)
}
func (handler *MediaActorHandler) EditPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
//logger := slog.Get(c)
actor, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
data := globals.GetDefaultValues(user, "MediaActors...")
data["actor"] = actor
c.Render(http.StatusOK, "actor_detail", data)
}
func (handler *MediaActorHandler) UpdatePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
actor, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaActorHandler#UpdatePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
var form models.MediaActorForm
if err := c.Bind(&form); err != nil {
logger.Info("MediaActorHandler#UpdatePage", "error", err.Error())
data := globals.GetDefaultValues(user, "MediaActors...")
data["actor"] = actor
data["Form"] = form
data["Errors"] = err.Error()
c.Render(http.StatusBadRequest, "actor_detail", data)
return
}
logger.Info("MediaActorHandler#UpdatePage", "actor", actor)
//handler.Service.Update(c.Request.Context(), form.ConvertFormToMediaLofiDTO())
c.Redirect(http.StatusFound, globals.MediaActorLink)
}
func (handler *MediaActorHandler) DeletePage(c *echo.Context) {
//session := sessions.Default(c)
//user := session.Get(globals.UserKey)
id := c.Param("id")
logger := c.Logger()
//actor, err := handler.Service.Get(c.Request.Context(), id)
// if err != nil {
// logger.Info("MediaActorHandler#DeletePage", "error", err.Error())
// c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
// return
// }
logger.Info("MediaActorHandler#DeletePage", "actor", id)
c.Redirect(http.StatusFound, globals.MediaActorLink)
}
@@ -1,85 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/globals"
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type MediaActorFileHandler struct {
Service *service.MediaActorFileService
}
func NewMediaActorFileHandler(db *bun.DB) *MediaActorFileHandler {
mediaActorFileHandler := &MediaActorFileHandler{
Service: service.NewMediaActorFileService(repository.NewMediaActorFileRepository(db)),
}
return mediaActorFileHandler
}
func (handler *MediaActorFileHandler) List(c *echo.Context) {
media_actor_files, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertMediaActorFilesToDtos(media_actor_files)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaActorFileHandler) Get(c *echo.Context) {
id := c.Param("id")
actor, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "sport not found"})
return
}
c.JSON(http.StatusOK, actor)
}
func (handler *MediaActorFileHandler) Add(c *echo.Context) {
var input models.MediaActorFileAdd
if err := c.Bind(&input); err != nil {
c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
actorfile, err := handler.Service.Add(c.Request().Context(), input.MediaActorID, input.MediaFileID)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not added"})
return
}
c.JSON(http.StatusOK, actorfile)
}
func (handler *MediaActorFileHandler) Delete(c *echo.Context) {
id := c.Param("id")
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "sport not found"})
return
}
c.JSON(http.StatusOK, map[string]string{"ok": "true"})
}
func (handler *MediaActorFileHandler) ListPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
media_actor_files, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
c.Render(http.StatusOK, "mediaactorfiles", map[string]string{
"title": "Kontor MediaActorFiles",
"version": "0.4.0",
"message": "MediaActorFiles...",
"actors": media_actor_files,
"user": user,
})
}
@@ -1,115 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/globals"
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type MediaArticleHandler struct {
Service *service.MediaArticleService
}
func NewMediaArticleHandler(db *bun.DB) *MediaArticleHandler {
mediaFileHandler := &MediaArticleHandler{
Service: service.NewMediaArticleService(repository.NewMediaArticleRepository(db)),
}
return mediaFileHandler
}
func (handler *MediaArticleHandler) List(c *echo.Context) {
logger := c.Logger()
logger.Info("MediaArticleHandler#List")
articles, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertMediaArticlesToDtos(articles)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaArticleHandler) Delete(c *echo.Context) {
id := c.Param("id")
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not found"})
return
}
c.JSON(http.StatusOK, map[string]string{"ok": "true"})
}
func (handler *MediaArticleHandler) ListPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
files, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
data := globals.GetDefaultValues(user, "MediaArticles...")
data["title"] = "Kontor MediaArticles"
data["media_links"] = files
data["MediaLinksUrl"] = globals.MediaArticleLink
c.Render(http.StatusOK, "media_links", data)
}
func (handler *MediaArticleHandler) EditPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
media_file, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaArticleHandler#EditPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaArticleHandler#EditPage", "media_file", media_file)
data := globals.GetDefaultValues(user, "MediaArticle Details...")
data["lofi"] = media_file
c.Render(http.StatusOK, "lofi_detail", data)
}
func (handler *MediaArticleHandler) UpdatePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
media_article, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaArticleHandler#UpdatePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
var form models.MediaArticleForm
if err := c.Bind(&form); err != nil {
logger.Info("MediaArticleHandler#UpdatePage", "error", err.Error())
data := globals.GetDefaultValues(user, "MediaArticle Details...")
data["Form"] = form
data["Errors"] = err.Error()
c.Render(http.StatusBadRequest, "lofi_detail", data)
return
}
logger.Info("MediaArticleHandler#UpdatePage", "media_article", media_article)
//handler.Service.Update(c.Request.Context(), form.ConvertFormToMediaFileDTO())
c.Redirect(http.StatusFound, globals.MediaArticleLink)
}
func (handler *MediaArticleHandler) DeletePage(c *echo.Context) {
id := c.Param("id")
logger := c.Logger()
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
logger.Info("MediaArticleHandler#DeletePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaArticleHandler#DeletePage", "lofi", id)
c.Redirect(http.StatusFound, globals.MediaArticleLink)
}
-132
View File
@@ -1,132 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/globals"
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type MediaFileHandler struct {
Service *service.MediaFileService
}
func NewMediaFileHandler(db *bun.DB) *MediaFileHandler {
mediaFileHandler := &MediaFileHandler{
Service: service.NewMediaFileService(repository.NewMediaFileRepository(db)),
}
return mediaFileHandler
}
func (handler *MediaFileHandler) List(c *echo.Context) {
logger := c.Logger()
logger.Info("MediaFileHandler#List")
files, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertMediaFilesToDtos(files)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaFileHandler) Add(c *echo.Context) {
var input models.MediaFileAdd
if err := c.Bind(&input); err != nil {
c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
lofi, err := handler.Service.Add(c.Request().Context(), input.Url)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not added"})
return
}
c.JSON(http.StatusOK, lofi)
}
func (handler *MediaFileHandler) Delete(c *echo.Context) {
id := c.Param("id")
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not found"})
return
}
c.JSON(http.StatusOK, map[string]string{"ok": "true"})
}
func (handler *MediaFileHandler) ListPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
files, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
data := globals.GetDefaultValues(user, "MediaFiles...")
data["title"] = "Kontor MediaFiles"
data["media_links"] = files
data["MediaLinksUrl"] = globals.MediaVideoLink
c.Render(http.StatusOK, "media_links", data)
}
func (handler *MediaFileHandler) EditPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
media_file, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaLoFiHandler#EditPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaLoFiHandler#EditPage", "media_file", media_file)
data := globals.GetDefaultValues(user, "MediaFile Details...")
data["lofi"] = media_file
c.Render(http.StatusOK, "lofi_detail", data)
}
func (handler *MediaFileHandler) UpdatePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
media_file, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaFileHandler#UpdatePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
var form models.MediaFileForm
if err := c.Bind(&form); err != nil {
logger.Info("MediaFileHandler#UpdatePage", "error", err.Error())
data := globals.GetDefaultValues(user, "MediaFile Details...")
data["Form"] = form
data["Errors"] = err.Error()
c.Render(http.StatusBadRequest, "lofi_detail", data)
return
}
logger.Info("MediaFileHandler#UpdatePage", "media_file", media_file)
//handler.Service.Update(c.Request.Context(), form.ConvertFormToMediaFileDTO())
c.Redirect(http.StatusFound, globals.MediaFileLink)
}
func (handler *MediaFileHandler) DeletePage(c *echo.Context) {
//session := sessions.Default(c)
//user := session.Get(globals.UserKey)
id := c.Param("id")
logger := c.Logger()
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
logger.Info("MediaFileHandler#DeletePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaFileHandler#DeletePage", "lofi", id)
c.Redirect(http.StatusFound, globals.MediaFileLink)
}
-232
View File
@@ -1,232 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/globals"
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"time"
"github.com/google/uuid"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type MediaLoFiHandler struct {
Service *service.MediaLoFiService
}
func NewMediaLoFiHandler(db *bun.DB) *MediaLoFiHandler {
mediaLoFiHandler := &MediaLoFiHandler{
Service: service.NewMediaLoFiService(repository.NewMediaLoFiRepository(db)),
}
return mediaLoFiHandler
}
func (handler *MediaLoFiHandler) List(c *echo.Context) {
lofis, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertMediaLoFisToDtos(lofis)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaLoFiHandler) Get(c *echo.Context) {
id := c.Param("id")
lofi, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "Lofi not found"})
return
}
c.JSON(http.StatusOK, lofi)
}
func (handler *MediaLoFiHandler) Add(c *echo.Context) {
var input models.MediaLofiAdd
if err := c.Bind(&input); err != nil {
c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
lofi, err := handler.Service.Add(c.Request().Context(), input.Url)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not added"})
return
}
c.JSON(http.StatusOK, lofi)
}
func (handler *MediaLoFiHandler) Update(c *echo.Context) {
var input models.MediaLoFiDTO
if err := c.Bind(&input); err != nil {
c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
lofi, err := handler.Service.Update(c.Request().Context(), input)
if err != nil {
logger := c.Logger()
logger.Info("MediaLoFiHandler#Update", "error", err.Error())
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not updated"})
return
}
c.JSON(http.StatusOK, lofi)
}
func (handler *MediaLoFiHandler) Delete(c *echo.Context) {
id := c.Param("id")
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "lofi not found"})
return
}
c.JSON(http.StatusOK, map[string]string{"ok": "true"})
}
func (handler *MediaLoFiHandler) ListPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
logger := c.Logger()
var (
review bool
download bool
)
paramReview, err := echo.QueryParam[string](c, "review")
if err == nil {
if paramReview == "on" {
review = true
} else {
review = false
}
}
paramDownload, err := echo.QueryParam[string](c, "should_download")
if err == nil {
if paramDownload == "on" {
download = true
} else {
download = false
}
}
lofis, err := handler.Service.List(c.Request().Context())
if err != nil {
logger.Info("MediaLoFiHandler#ListPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaLoFiHandler#ListPage", "lofis count", len(lofis))
data := globals.GetDefaultValues(user, "MediaFiles...")
data["media_links"] = lofis
data["isReview"] = review
data["isDownload"] = download
data["MediaLinksUrl"] = globals.MediaLofiLink
c.Render(http.StatusOK, "media_links", data)
}
func (handler *MediaLoFiHandler) EditPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
var lofi *models.MediaLoFi
if id == "" {
// id is empty, adding is assumed
lofi = &models.MediaLoFi{
ID: uuid.NewString(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Version: 0,
Review: true,
ShouldDownload: true,
}
} else {
// id is set, fetch MediaLofi by ID
lofi, err = handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaLoFiHandler#EditPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
}
logger.Info("MediaLoFiHandler#EditPage", "lofi", lofi)
data := globals.GetDefaultValues(user, "MediaLofis...")
data["media"] = lofi
data["MediaLinksUrl"] = globals.MediaLofiLink
c.Render(http.StatusOK, "media_detail", data)
}
func (handler *MediaLoFiHandler) ChangeReviewPage(c *echo.Context) {
id := c.Param("id")
logger := c.Logger()
lofi, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaLoFiHandler#ChangeReviewPage", "error", err.Error())
c.Redirect(http.StatusNotFound, globals.MediaLofiLink)
return
}
lofi.Review = !lofi.Review
handler.Service.Update(c.Request().Context(), lofi.ConvertMediaLoFiToDTO())
logger.Info("MediaLoFiHandler#ChangeReviewPage", "lofi", lofi)
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
lofis, err := handler.Service.List(c.Request().Context())
if err != nil {
logger.Info("MediaLoFiHandler#ChangeReviewPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaLoFiHandler#ListPage", "lofis count", len(lofis))
data := globals.GetDefaultValues(user, "MediaLofis...")
data["lofis"] = lofis
//c.HTML(http.StatusOK, "lofi", data)
c.Redirect(http.StatusCreated, globals.MediaLofiLink)
}
func (handler *MediaLoFiHandler) UpdatePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
lofi, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaLoFiHandler#UpdatePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
var form models.MediaLoFiForm
if err := c.Bind(&form); err != nil {
logger.Info("MediaLoFiHandler#UpdatePage", "error", err.Error())
c.Render(http.StatusBadRequest, "lofi_detail", map[string]any{
"Form": form,
"Errors": err.Error(),
"user": user,
})
return
}
logger.Info("MediaLoFiHandler#UpdatePage", "lofi", lofi)
//handler.Service.Update(c.Request.Context(), form.ConvertFormToMediaLofiDTO())
c.Redirect(http.StatusFound, globals.MediaLofiLink)
}
func (handler *MediaLoFiHandler) DeletePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
lofi, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaLoFiHandler#DeletePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaLoFiHandler#DeletePage", "lofi", id)
c.Render(http.StatusOK, "lofi_delete", map[string]string{
"title": "Kontor MediaFiles",
"version": "0.4.0",
"message": "MediaFiles...",
"lofi": lofi,
"user": user,
})
}
@@ -1,181 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/globals"
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type MediaMusicHandler struct {
Service *service.MediaMusicService
}
func NewMediaMusicHandler(db *bun.DB) *MediaMusicHandler {
mediaMusicHandler := &MediaMusicHandler{
Service: service.NewMediaMusicService(repository.NewMediaMusicRepository(db)),
}
return mediaMusicHandler
}
func (handler *MediaMusicHandler) List(c *echo.Context) {
musics, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertMediaMusicsToDtos(musics)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaMusicHandler) Get(c *echo.Context) {
id := c.Param("id")
music, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "MediaMusic not found"})
return
}
c.JSON(http.StatusOK, music)
}
func (handler *MediaMusicHandler) Add(c *echo.Context) {
var input models.MediaLofiAdd
if err := c.Bind(&input); err != nil {
c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
music, err := handler.Service.Add(c.Request().Context(), input.Url)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "MediaMusic not added"})
return
}
c.JSON(http.StatusOK, music)
}
func (handler *MediaMusicHandler) Update(c *echo.Context) {
var input models.MediaMusicDTO
if err := c.Bind(&input); err != nil {
c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
music, err := handler.Service.Update(c.Request().Context(), input)
if err != nil {
logger := c.Logger()
logger.Info("MediaMusicHandler#Update", "error", err.Error())
c.JSON(http.StatusNotFound, map[string]string{"error": "MediaMusic not updated"})
return
}
c.JSON(http.StatusOK, music)
}
func (handler *MediaMusicHandler) Delete(c *echo.Context) {
id := c.Param("id")
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, map[string]string{"error": "MediaMusic not found"})
return
}
c.JSON(http.StatusOK, map[string]string{"ok": "true"})
}
func (handler *MediaMusicHandler) ListPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
logger := c.Logger()
var (
review bool
download bool
)
paramReview, err := echo.QueryParam[string](c, "review")
if err == nil {
if paramReview == "on" {
review = true
} else {
review = false
}
}
paramDownload, err := echo.QueryParam[string](c, "should_download")
if err == nil {
if paramDownload == "on" {
download = true
} else {
download = false
}
}
musics, err := handler.Service.List(c.Request().Context())
if err != nil {
logger.Info("MediaMusicHandler#ListPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaMusicHandler#ListPage", "MediaMusic count", len(musics))
data := globals.GetDefaultValues(user, "MediaMusic...")
data["media_links"] = musics
data["MediaLinksUrl"] = globals.MediaMusicLink
data["isReview"] = review
data["isDownload"] = download
c.Render(http.StatusOK, "media_links", data)
}
func (handler *MediaMusicHandler) EditPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
music, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaMusicHandler#EditPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaMusicHandler#EditPage", "music", music)
data := globals.GetDefaultValues(user, "MediaMusic...")
data["lofi"] = music
c.Render(http.StatusOK, "lofi_detail", data)
}
func (handler *MediaMusicHandler) UpdatePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
music, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaMusicHandler#UpdatePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
var form models.MediaMusicForm
if err := c.Bind(&form); err != nil {
logger.Info("MediaMusicHandler#UpdatePage", "error", err.Error())
data := globals.GetDefaultValues(user, "MediaMusic...")
data["Form"] = form
data["Errors"] = err.Error()
c.Render(http.StatusBadRequest, "lofi_detail", data)
return
}
logger.Info("MediaMusicHandler#UpdatePage", "music", music)
//handler.Service.Update(c.Request.Context(), form.ConvertFormToMediaLofiDTO())
c.Redirect(http.StatusFound, globals.MediaMusicLink)
}
func (handler *MediaMusicHandler) DeletePage(c *echo.Context) {
// session := sessions.Default(c)
// user := session.Get(globals.UserKey)
id := c.Param("id")
logger := c.Logger()
err := handler.Service.Delete(c.Request().Context(), id)
if err != nil {
logger.Info("MediaMusicHandler#DeletePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaMusicHandler#DeletePage", "music", id)
c.Redirect(http.StatusFound, globals.MediaMusicLink)
}
@@ -1,113 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/globals"
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type MediaVideoHandler struct {
Service *service.MediaVideoService
}
func NewMediaVideoHandler(db *bun.DB) *MediaVideoHandler {
handler := &MediaVideoHandler{Service: service.NewMediaVideoService(repository.NewMediaVideoRepository(db))}
return handler
}
func (handler *MediaVideoHandler) List(c *echo.Context) {
logger := c.Logger()
logger.Info("MediaVideoHandler#List")
videos, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertMediaVideosToDtos(videos)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaVideoHandler) ListPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
logger := c.Logger()
videos, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaVideoHandler#ListPage", "videos count", len(videos))
data := globals.GetDefaultValues(user, "MediaVideos...")
data["title"] = "Kontor MediaVideos"
data["media_links"] = videos
data["MediaLinksUrl"] = globals.MediaVideoLink
c.Render(http.StatusOK, "media_links", data)
}
func (handler *MediaVideoHandler) EditPage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
video, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaVideoHandler#EditPage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaVideoHandler#EditPage", "lofi", video)
data := globals.GetDefaultValues(user, "MediaLofis...")
data["lofi"] = video
c.Render(http.StatusOK, "lofi_detail", data)
}
func (handler *MediaVideoHandler) UpdatePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
video, err := handler.Service.Get(c.Request().Context(), id)
if err != nil {
logger.Info("MediaVideoHandler#UpdatePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
var form models.MediaVideoForm
if err := c.Bind(&form); err != nil {
logger.Info("MediaVideoHandler#UpdatePage", "error", err.Error())
c.Render(http.StatusBadRequest, "lofi_detail", map[string]any{
"Form": form,
"Errors": err.Error(),
"user": user,
})
return
}
logger.Info("MediaVideoHandler#UpdatePage", "lofi", video)
//handler.Service.Update(c.Request.Context(), form.ConvertFormToMediaLofiDTO())
c.Redirect(http.StatusFound, globals.MediaVideoLink)
}
func (handler *MediaVideoHandler) DeletePage(c *echo.Context) {
cookie, err := c.Cookie(globals.UserKey)
user := cookie.Value
id := c.Param("id")
logger := c.Logger()
err = handler.Service.Delete(c.Request().Context(), id)
if err != nil {
logger.Info("MediaVideoHandler#DeletePage", "error", err.Error())
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
logger.Info("MediaVideoHandler#DeletePage", "video", id)
c.Render(http.StatusOK, "lofi_delete", map[string]string{
"title": "Kontor MediaFiles",
"version": "0.4.0",
"message": "MediaFiles...",
"user": user,
})
}
@@ -1,28 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type PermissionHandler struct {
Service *service.PermissionService
}
func NewPermissionHandler(db *bun.DB) *PermissionHandler {
handler := &PermissionHandler{Service: service.NewPermissionService(repository.NewPermissionRepository(db))}
return handler
}
func (handler *PermissionHandler) List(c *echo.Context) {
permissions, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
c.JSON(http.StatusOK, permissions)
}
-30
View File
@@ -1,30 +0,0 @@
package handlers
import (
"kontor-api-echo/internal/models"
"kontor-api-echo/internal/repository"
"kontor-api-echo/internal/service"
"net/http"
"github.com/labstack/echo/v5"
"github.com/uptrace/bun"
)
type ProfileHandler struct {
Service *service.ProfileService
}
func NewProfileHandler(db *bun.DB) *ProfileHandler {
handler := &ProfileHandler{Service: service.NewProfileService(repository.NewProfileRepository(db))}
return handler
}
func (handler *ProfileHandler) List(c *echo.Context) {
profiles, err := handler.Service.List(c.Request().Context())
if err != nil {
c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
dtos := models.ConvertProfilesToDtos(profiles)
c.JSON(http.StatusOK, dtos)
}

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