Bootstrap Micropub support, and start support for Update activities
This commit is contained in:
parent
fb5759cfc1
commit
6f25d06bbb
11 changed files with 279 additions and 16 deletions
109
app/micropub.py
Normal file
109
app/micropub.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import Request
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.responses import RedirectResponse
|
||||
|
||||
from app import activitypub as ap
|
||||
from app.boxes import get_outbox_object_by_ap_id
|
||||
from app.boxes import send_create
|
||||
from app.boxes import send_delete
|
||||
from app.database import AsyncSession
|
||||
from app.database import get_db_session
|
||||
from app.indieauth import AccessTokenInfo
|
||||
from app.indieauth import verify_access_token
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/micropub")
|
||||
async def micropub_endpoint(
|
||||
request: Request,
|
||||
access_token_info: AccessTokenInfo = Depends(verify_access_token),
|
||||
db_session: AsyncSession = Depends(get_db_session),
|
||||
) -> dict[str, Any] | JSONResponse:
|
||||
if request.query_params.get("q") == "config":
|
||||
return {}
|
||||
|
||||
elif request.query_params.get("q") == "source":
|
||||
url = request.query_params.get("url")
|
||||
outbox_object = await get_outbox_object_by_ap_id(db_session, url)
|
||||
if not outbox_object:
|
||||
return JSONResponse(
|
||||
content={
|
||||
"error": "invalid_request",
|
||||
"error_description": "No post with this URL",
|
||||
},
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
extra_props: dict[str, list[str]] = {}
|
||||
|
||||
return {
|
||||
"type": ["h-entry"],
|
||||
"properties": {
|
||||
"published": [
|
||||
outbox_object.ap_published_at.isoformat() # type: ignore
|
||||
],
|
||||
"content": [outbox_object.source],
|
||||
**extra_props,
|
||||
},
|
||||
}
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
@router.post("/micropub")
|
||||
async def post_micropub_endpoint(
|
||||
request: Request,
|
||||
access_token_info: AccessTokenInfo = Depends(verify_access_token),
|
||||
db_session: AsyncSession = Depends(get_db_session),
|
||||
) -> RedirectResponse | JSONResponse:
|
||||
form_data = await request.form()
|
||||
if "action" in form_data:
|
||||
if form_data["action"] == "delete":
|
||||
outbox_object = await get_outbox_object_by_ap_id(
|
||||
db_session, form_data["url"]
|
||||
)
|
||||
if not outbox_object:
|
||||
return JSONResponse(
|
||||
content={
|
||||
"error": "invalid_request",
|
||||
"error_description": "No post with this URL",
|
||||
},
|
||||
status_code=400,
|
||||
)
|
||||
await send_delete(db_session, outbox_object.ap_id) # type: ignore
|
||||
return JSONResponse(content={}, status_code=200)
|
||||
|
||||
h = "entry"
|
||||
if "h" in form_data:
|
||||
h = form_data["h"]
|
||||
|
||||
if h != "entry":
|
||||
return JSONResponse(
|
||||
content={
|
||||
"error": "invalid_request",
|
||||
"error_description": "Only h-entry are supported",
|
||||
},
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
content = form_data["content"]
|
||||
public_id = await send_create(
|
||||
db_session,
|
||||
content,
|
||||
uploads=[],
|
||||
in_reply_to=None,
|
||||
visibility=ap.VisibilityEnum.PUBLIC,
|
||||
)
|
||||
|
||||
return JSONResponse(
|
||||
content={},
|
||||
status_code=201,
|
||||
headers={
|
||||
"Location": request.url_for("outbox_by_public_id", public_id=public_id)
|
||||
},
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue