diff --git a/kontor-api/pyproject.toml b/kontor-api/pyproject.toml index 5714289..9ab9798 100644 --- a/kontor-api/pyproject.toml +++ b/kontor-api/pyproject.toml @@ -21,4 +21,5 @@ dependencies = [ "python-dotenv>=1.1.0", "python-jose>=3.4.0", "python-multipart>=0.0.20", + "natsort>=8.4.0", ] diff --git a/kontor-api/src/db/models/comic.py b/kontor-api/src/db/models/comic.py index e83d28b..423ad7c 100644 --- a/kontor-api/src/db/models/comic.py +++ b/kontor-api/src/db/models/comic.py @@ -1,3 +1,5 @@ +from typing import Dict, List +from natsort import natsorted from sqlalchemy import Column, ForeignKey, Integer, String from sqlalchemy.dialects.mysql import BIT from sqlalchemy.orm import relationship @@ -24,7 +26,7 @@ class Comic(Base, BaseMixin): publisher = relationship("Publisher", back_populates="comics") current_order = Column(BIT(1)) completed = Column(BIT(1)) - issues = relationship("Issue") + issues = relationship("Issue", order_by="Issue.issue_number") story_arcs = relationship("StoryArc") trade_paperbacks = relationship("TradePaperback") volumes = relationship("Volume") @@ -36,6 +38,21 @@ class Comic(Base, BaseMixin): def __str__(self): return f'{self.title}({self.id})' + def get_artists(self) -> Dict[str, List[str]]: + works: Dict[str, List[str]] = {} + for work in self.comic_works: + work_type = work.work_type.name + artist = work.artist + if work_type in works: + works[work_type].append(artist) + else: + works[work_type] = [artist] + return works + + def sorted_issues(self): + sorted_issues = natsorted(self.issues, key=lambda x: getattr(x, 'issue_number')) + return sorted_issues + class Volume(Base, BaseMixin): __tablename__ = "volume" @@ -77,6 +94,17 @@ class Artist(Base, BaseMixin): name = Column(String(length=255), nullable=False) comic_works = relationship("ComicWork") + def get_comics(self) -> Dict[str, List[str]]: + works: Dict[str, List[str]] = {} + for work in self.comic_works: + work_type = work.work_type.name + comic = work.comic + if work_type in works: + works[work_type].append(comic) + else: + works[work_type] = [comic] + return works + class WorkType(Base, BaseMixin): __tablename__ = "worktype" diff --git a/kontor-api/src/static/images/cross.png b/kontor-api/src/static/images/cross.png new file mode 100644 index 0000000..6b9fa6d Binary files /dev/null and b/kontor-api/src/static/images/cross.png differ diff --git a/kontor-api/src/static/images/tick.png b/kontor-api/src/static/images/tick.png new file mode 100644 index 0000000..2414885 Binary files /dev/null and b/kontor-api/src/static/images/tick.png differ diff --git a/kontor-api/src/templates/comic/artist_detail.html b/kontor-api/src/templates/comic/artist_detail.html index 2c69b0d..58ee61b 100644 --- a/kontor-api/src/templates/comic/artist_detail.html +++ b/kontor-api/src/templates/comic/artist_detail.html @@ -2,14 +2,14 @@ {% block title %} - Comic Detail + Artist Detail {% endblock %} {% block content %}
-

Comic Detail

+

Artist Detail

@@ -23,9 +23,14 @@ Works - {% for work in artist.comic_works %} + {% for work in artist.get_comics() %}

- {{work.work_type.name}}: {{work.comic.title}} + {{work}}: +

{% endfor %} diff --git a/kontor-api/src/templates/comic/comic_detail.html b/kontor-api/src/templates/comic/comic_detail.html index 57965fc..7a903e9 100644 --- a/kontor-api/src/templates/comic/comic_detail.html +++ b/kontor-api/src/templates/comic/comic_detail.html @@ -6,12 +6,7 @@ {% endblock %} {% block content %} -
-
-
-

Comic Detail

-
-
+
@@ -26,17 +21,26 @@ - + + @@ -46,6 +50,20 @@ + + + + + + + +
Completed{{comic.completed}} + {% with check=comic.completed %} + {% include "components/check.html" %} + {% endwith %} +
Works - {% for work in comic.comic_works %} + {% for work in comic.get_artists() %}

- {{work.work_type.name}}: {{work.artist.name}} + {{work}}: +

    + {% for artist in comic.get_artists()[work] %} +
  • {{artist.name}}
  • + {% endfor %} +

{% endfor %} -
Data CreatedData Modified {{comic.last_modified_date}}
Data Version{{comic.version}}
Issues + +
diff --git a/kontor-api/src/templates/comic/comics.html b/kontor-api/src/templates/comic/comics.html index 6da1b24..91b6513 100644 --- a/kontor-api/src/templates/comic/comics.html +++ b/kontor-api/src/templates/comic/comics.html @@ -19,8 +19,7 @@
{% with obj=comic %} {% include "components/comic_cards.html" %} - {% endwith %} - + {% endwith %} {% if loop.index %3 %}
{% else %} diff --git a/kontor-api/src/templates/comic/publisher_detail.html b/kontor-api/src/templates/comic/publisher_detail.html new file mode 100644 index 0000000..6429d58 --- /dev/null +++ b/kontor-api/src/templates/comic/publisher_detail.html @@ -0,0 +1,45 @@ +{% extends "shared/base.html" %} + + +{% block title %} + Publisher Detail +{% endblock %} + +{% block content %} +
+
+
+

Publisher Detail

+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
Publisher Name{{publisher.name}}
Comics + +
Data Created{{publisher.created_date}}
Data Modified{{publisher.last_modified_date}}
+
+
+{% endblock %} diff --git a/kontor-api/src/templates/comic/publishers.html b/kontor-api/src/templates/comic/publishers.html new file mode 100644 index 0000000..3eaedc8 --- /dev/null +++ b/kontor-api/src/templates/comic/publishers.html @@ -0,0 +1,31 @@ +{% extends "shared/base.html" %} + +{% block title %} + Publisher List +{% endblock %} + +{% block content %} + {% with msg=msg %} + {% include "components/alerts.html" %} + {% endwith %} +
+
+
+

Find Publishers..

+
+
+
+ {% for publisher in publishers %} +
+ {% with obj=publisher %} + {% include "components/publisher_cards.html" %} + {% endwith %} + {% if loop.index %3 %} +
+ {% else %} +

+ {% endif %} + {% endfor %} +
+
+{% endblock %} diff --git a/kontor-api/src/templates/components/actor_cards.html b/kontor-api/src/templates/components/actor_cards.html new file mode 100644 index 0000000..8678b0e --- /dev/null +++ b/kontor-api/src/templates/components/actor_cards.html @@ -0,0 +1,6 @@ +
+
+
{{obj.name}}
+ Read more +
+
diff --git a/kontor-api/src/templates/components/check.html b/kontor-api/src/templates/components/check.html new file mode 100644 index 0000000..b2b6263 --- /dev/null +++ b/kontor-api/src/templates/components/check.html @@ -0,0 +1,5 @@ +{% if check == 1 %} + +{% else %} + +{% endif %} diff --git a/kontor-api/src/templates/components/comic_cards.html b/kontor-api/src/templates/components/comic_cards.html index 4d0354f..2a1a5fc 100644 --- a/kontor-api/src/templates/components/comic_cards.html +++ b/kontor-api/src/templates/components/comic_cards.html @@ -2,7 +2,7 @@
{{obj.title}}

Publisher : {{obj.publisher.name}}

-

Completed : {{obj.completed}}

+

Completed : {% with check=obj.completed %}{% include "components/check.html" %}{% endwith %}

Read more
diff --git a/kontor-api/src/templates/components/navbar.html b/kontor-api/src/templates/components/navbar.html index 24f428f..3d4f974 100644 --- a/kontor-api/src/templates/components/navbar.html +++ b/kontor-api/src/templates/components/navbar.html @@ -16,6 +16,7 @@ diff --git a/kontor-api/src/templates/components/publisher_cards.html b/kontor-api/src/templates/components/publisher_cards.html new file mode 100644 index 0000000..e2a6050 --- /dev/null +++ b/kontor-api/src/templates/components/publisher_cards.html @@ -0,0 +1,6 @@ +
+
+
{{obj.name}}
+ Read more +
+
diff --git a/kontor-api/src/templates/media/actor_detail.html b/kontor-api/src/templates/media/actor_detail.html new file mode 100644 index 0000000..f163f73 --- /dev/null +++ b/kontor-api/src/templates/media/actor_detail.html @@ -0,0 +1,45 @@ +{% extends "shared/base.html" %} + + +{% block title %} + Actor Detail +{% endblock %} + +{% block content %} +
+
+
+

Actor Detail

+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
Actor Name{{actor.name}}
Works + +
Data Created{{actor.created_date}}
Data Modified{{actor.last_modified_date}}
+
+
+{% endblock %} diff --git a/kontor-api/src/templates/media/actors.html b/kontor-api/src/templates/media/actors.html new file mode 100644 index 0000000..836d614 --- /dev/null +++ b/kontor-api/src/templates/media/actors.html @@ -0,0 +1,32 @@ +{% extends "shared/base.html" %} + +{% block title %} + MediaFile Actors +{% endblock %} + +{% block content %} + {% with msg=msg %} + {% include "components/alerts.html" %} + {% endwith %} +
+
+
+

Actors..

+
+
+
+ {% for actor in actors %} +
+ {% with obj=actor %} + {% include "components/actor_cards.html" %} + {% endwith %} + + {% if loop.index %3 %} +
+ {% else %} +

+ {% endif %} + {% endfor %} +
+
+{% endblock %} diff --git a/kontor-api/src/templates/media/file_detail.html b/kontor-api/src/templates/media/file_detail.html new file mode 100644 index 0000000..186444b --- /dev/null +++ b/kontor-api/src/templates/media/file_detail.html @@ -0,0 +1,65 @@ +{% extends "shared/base.html" %} + + +{% block title %} + MediaFile Detail +{% endblock %} + +{% block content %} +
+
+
+

MediaFile Detail

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MediaFile Title{{mediafile.title}}
MediaFile URL{{mediafile.url}}
MediaFile Cloudlink{{mediafile.cloud_link}}
MediaFile Download?{{mediafile.should_download}}
MediaFile Review?{{mediafile.review}}
Actors + +
Data Created{{mediafile.created_date}}
Data Modified{{mediafile.last_modified_date}}
Data Version{{mediafile.version}}
+
+
+{% endblock %} diff --git a/kontor-api/src/webapps/comic/route_comics.py b/kontor-api/src/webapps/comic/route_comics.py index 524ea76..565bd26 100644 --- a/kontor-api/src/webapps/comic/route_comics.py +++ b/kontor-api/src/webapps/comic/route_comics.py @@ -4,8 +4,7 @@ from fastapi import APIRouter, Request from fastapi.templating import Jinja2Templates from src.apis.utils import SessionDep -from src.db.models.comic import Comic, Artist -from src.schema.comics.comic import get_comic_details +from src.db.models.comic import Comic, Artist, Publisher templates = Jinja2Templates(directory="src/templates") router = APIRouter(include_in_schema=False, prefix="/comic") @@ -29,3 +28,15 @@ def get_artists(db: SessionDep, request: Request, msg: str = None): def artist_detail(artist_id: UUID, request: Request, db: SessionDep): artist = db.get(Artist, artist_id) return templates.TemplateResponse("comic/artist_detail.html", {"request": request, "artist": artist}) + +@router.get("/publishers") +def get_publishers(db: SessionDep, request: Request, msg: str = None): + publishers = db.query(Publisher).all() + return templates.TemplateResponse("comic/publishers.html", {"request": request, "publishers": publishers}) + +@router.get("/publishers/{publisher_id}") +def publisher_details(publisher_id: UUID, request: Request, db: SessionDep, msg: str = None): + publisher = db.get(Publisher, publisher_id) + if publisher is None: + msg = "Could not find Publisher" + return templates.TemplateResponse("comic/publisher_detail.html", {"request": request, "msg": msg, "publisher": publisher}) diff --git a/kontor-api/src/webapps/media/route_media.py b/kontor-api/src/webapps/media/route_media.py index 602690f..b957f49 100644 --- a/kontor-api/src/webapps/media/route_media.py +++ b/kontor-api/src/webapps/media/route_media.py @@ -27,6 +27,6 @@ def get_actors(db: SessionDep, request: Request, msg: str = None): @router.get("/actors/{actor_id}") def artist_detail(actor_id: UUID, request: Request, db: SessionDep): - mediaactor = db.get(MediaActor, actor_id) - return templates.TemplateResponse("media/artist_detail.html", {"request": request, "mediaactor": mediaactor}) + actor = db.get(MediaActor, actor_id) + return templates.TemplateResponse("media/actor_detail.html", {"request": request, "actor": actor}) diff --git a/kontor-api/uv.lock b/kontor-api/uv.lock index 14578de..f12445d 100644 --- a/kontor-api/uv.lock +++ b/kontor-api/uv.lock @@ -284,6 +284,7 @@ dependencies = [ { name = "fastapi", extra = ["standard"] }, { name = "httpx" }, { name = "mariadb" }, + { name = "natsort" }, { name = "pathlib" }, { name = "platformdirs" }, { name = "pytest" }, @@ -302,6 +303,7 @@ requires-dist = [ { name = "fastapi", extras = ["standard"], specifier = ">=0.115.12" }, { name = "httpx", specifier = "==0.24.1" }, { name = "mariadb", specifier = ">=1.1.12" }, + { name = "natsort", specifier = ">=8.4.0" }, { name = "pathlib", specifier = ">=1.0.1" }, { name = "platformdirs", specifier = ">=4.3.7" }, { name = "pytest", specifier = "==7.4.0" }, @@ -376,6 +378,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload_time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "natsort" +version = "8.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575, upload_time = "2023-06-20T04:17:19.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268, upload_time = "2023-06-20T04:17:17.522Z" }, +] + [[package]] name = "packaging" version = "25.0"