HTML page to show tagged objects

This commit is contained in:
Thomas Sileo 2022-07-03 19:17:19 +02:00
parent 4a4c78bf64
commit 1acefc679d
2 changed files with 86 additions and 21 deletions

View file

@ -64,22 +64,13 @@ _RESIZED_CACHE: MutableMapping[tuple[str, int], tuple[bytes, str, Any]] = LFUCac
# TODO(ts):
#
# Next:
# - inbox/outbox admin
# - no counters anymore?
# - allow to show tags in the menu
# - support update post with history
# - inbox/outbox in the admin (as in show every objects)
# - show likes/announces counter for outbox activities
# - update actor support
# - hash config/profile to detect when to send Update actor
#
# - [ ] block support
# - [ ] make the media proxy authenticated
# - [ ] prevent SSRF (urlutils from little-boxes)
# - [ ] Dockerization
# - [ ] Webmentions
# - [ ] custom emoji
# - [ ] poll/questions support
# - [ ] cleanup tasks
app = FastAPI(docs_url=None, redoc_url=None)
@ -564,23 +555,54 @@ async def tag_by_name(
if not tagged_count:
raise HTTPException(status_code=404)
outbox_objects = await db_session.execute(
select(models.OutboxObject.ap_id)
.join(models.TaggedOutboxObject)
if is_activitypub_requested(request):
outbox_object_ids = await db_session.execute(
select(models.OutboxObject.ap_id)
.join(
models.TaggedOutboxObject,
models.TaggedOutboxObject.outbox_object_id == models.OutboxObject.id,
)
.where(*where)
.order_by(models.OutboxObject.ap_published_at.desc())
.limit(20)
)
return ActivityPubResponse(
{
"@context": ap.AS_CTX,
"id": BASE_URL + f"/t/{tag}",
"type": "OrderedCollection",
"totalItems": tagged_count,
"orderedItems": [
outbox_object.ap_id for outbox_object in outbox_object_ids
],
}
)
outbox_objects_result = await db_session.scalars(
select(models.OutboxObject)
.where(*where)
.join(
models.TaggedOutboxObject,
models.TaggedOutboxObject.outbox_object_id == models.OutboxObject.id,
)
.options(
joinedload(models.OutboxObject.outbox_object_attachments).options(
joinedload(models.OutboxObjectAttachment.upload)
)
)
.order_by(models.OutboxObject.ap_published_at.desc())
.limit(20)
)
# TODO(ts): implement HTML version
# if is_activitypub_requested(request):
return ActivityPubResponse(
outbox_objects = outbox_objects_result.unique().all()
return await templates.render_template(
db_session,
request,
"index.html",
{
"@context": ap.AS_CTX,
"id": BASE_URL + f"/t/{tag}",
"type": "OrderedCollection",
"totalItems": tagged_count,
"orderedItems": [outbox_object.ap_id for outbox_object in outbox_objects],
}
"request": request,
"objects": outbox_objects,
},
)

View file

@ -2,6 +2,9 @@ from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
from app import activitypub as ap
from app import models
from app.config import generate_csrf_token
from tests.utils import generate_admin_session_cookies
def test_tags__no_tags(
@ -11,3 +14,43 @@ def test_tags__no_tags(
response = client.get("/t/nope", headers={"Accept": ap.AP_CONTENT_TYPE})
assert response.status_code == 404
def test_tags__note_with_tag(db: Session, client: TestClient) -> None:
# Call admin endpoint to create a note with
note_content = "Hello #testing"
response = client.post(
"/admin/actions/new",
data={
"redirect_url": "http://testserver/",
"content": note_content,
"visibility": ap.VisibilityEnum.PUBLIC.name,
"csrf_token": generate_csrf_token(),
},
cookies=generate_admin_session_cookies(),
)
# Then the server returns a 302
assert response.status_code == 302
# And the Follow activity was created in the outbox
outbox_object = db.query(models.OutboxObject).one()
assert outbox_object.ap_type == "Note"
assert len(outbox_object.tags) == 1
emoji_tag = outbox_object.tags[0]
assert emoji_tag["type"] == "Hashtag"
assert emoji_tag["name"] == "#testing"
# And the tag page returns this note
html_resp = client.get("/t/testing")
html_resp.raise_for_status()
assert html_resp.status_code == 200
assert "Hello" in html_resp.text
# And the AP version of the page turns the note too
ap_resp = client.get("/t/testing", headers={"Accept": ap.AP_CONTENT_TYPE})
ap_resp.raise_for_status()
ap_json_resp = ap_resp.json()
assert ap_json_resp["totalItems"] == 1
assert ap_json_resp["orderedItems"] == [outbox_object.ap_id]