From abdf1fea0fbc86b0c9e46073ab2c862507b0d000 Mon Sep 17 00:00:00 2001 From: SouthFox Date: Sun, 30 Jul 2023 20:48:50 +0800 Subject: [PATCH] [feat] show note in index --- app/ap_object.py | 18 ++++++++++++++++++ app/main.py | 23 +++++++++++++++++++++-- app/models.py | 5 +++-- templates/index.html | 11 +++++++++++ templates/utils.html | 25 +++++++++++++++++++++++++ tests/test_main.py | 4 +++- 6 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 app/ap_object.py create mode 100644 templates/index.html create mode 100644 templates/utils.html diff --git a/app/ap_object.py b/app/ap_object.py new file mode 100644 index 0000000..9e75fc9 --- /dev/null +++ b/app/ap_object.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +from app import activitypub as ap + +from functools import cached_property + + +class BaseObject: + @property + def ap_object(self) -> ap.RawObject: + raise NotImplementedError + + @cached_property + def content(self) -> str | None: + content = self.ap_object.get("content") + if not content: + return None + + return content diff --git a/app/main.py b/app/main.py index 03ac834..99675ac 100644 --- a/app/main.py +++ b/app/main.py @@ -9,6 +9,7 @@ from fastapi import Depends from fastapi import Request from fastapi import Response from fastapi.exceptions import HTTPException +from fastapi.templating import Jinja2Templates from starlette.responses import JSONResponse from loguru import logger @@ -43,6 +44,8 @@ app = FastAPI( dependencies=[Depends(_check_0rtt_early_data)] ) +templates = Jinja2Templates(directory="templates") + logger.remove() logger.add(sys.stdout, level="DEBUG" if DEBUG else "INFO") logger.add("output.log", level="DEBUG") @@ -71,13 +74,29 @@ def is_ap_requested(req: Request) -> bool: @app.get("/") async def index( - request: Request + request: Request, + db_session: AsyncSession = Depends(get_db_session), ): """Return index page.""" if is_ap_requested(request): return ActivityPubResponse(ME) - return ME + statues = ( + await db_session.scalars( + select(models.OutboxObject).where( + models.OutboxObject.ap_type == "Note", + models.OutboxObject.is_deleted.is_(False), + ) + ) + ).all() + + return templates.TemplateResponse( + "index.html", + { + "request": request, + "statues": statues, + } + ) @app.post("/inbox") diff --git a/app/models.py b/app/models.py index eb5bfc0..553295b 100644 --- a/app/models.py +++ b/app/models.py @@ -8,6 +8,7 @@ from app import activitypub as ap from app.database import Base from app.database import metadata_obj from app.activitypub import BaseActor +from app.ap_object import BaseObject from sqlalchemy import Column from sqlalchemy import Boolean @@ -42,7 +43,7 @@ class Actor(Base, BaseActor): is_blocked = Column(Boolean, nullable=False, default=False, server_default="0") is_deleted = Column(Boolean, nullable=False, default=False, server_default="0") -class InboxObject(Base): +class InboxObject(Base, BaseObject): __tablename__ = "inbox" id = Column(Integer, primary_key=True, index=True) @@ -89,7 +90,7 @@ class InboxObject(Base): uselist=False, ) -class OutboxObject(Base): +class OutboxObject(Base, BaseObject): __tablename__ = "outbox" id = Column(Integer, primary_key=True, index=True) diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..72e58c8 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,11 @@ + + + Index + + +

Test

+ {% for status in statues recursive%} + {{ status.content | safe }} + {% endfor %} + + diff --git a/templates/utils.html b/templates/utils.html new file mode 100644 index 0000000..332dc7e --- /dev/null +++ b/templates/utils.html @@ -0,0 +1,25 @@ + + + + + + Untitled + + + + + + + + + + + + + diff --git a/tests/test_main.py b/tests/test_main.py index 5fcb45a..0db7cfa 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -13,10 +13,12 @@ _ACCEPTED_AP_HEADERS = [ 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', ] + def test_index__html(client: TestClient): response = client.get("/") assert response.status_code == 200 - assert response.headers["content-type"] == "application/json" + assert response.headers["content-type"].startswith("text/html") + @pytest.mark.parametrize("accept", _ACCEPTED_AP_HEADERS) def test_index__ap(db: Session, client: TestClient, accept: str):