Compare commits

...

2 Commits

Author SHA1 Message Date
94bc8b6c21 (api): Add document routes. 2025-06-08 22:05:13 +10:00
aba73b8bba dix(data): Fix typo in schema. 2025-06-08 22:04:42 +10:00
4 changed files with 77 additions and 11 deletions

View File

@@ -276,7 +276,7 @@ SELECT
cheer_events.message AS cheer_message,
subscriber_events.subscribed_length AS subscriber_length,
subscriber_events.tier AS subscriber_tier,
subscriber_events.message AS subscriber_message,
subscriber_events.message AS subscriber_message
FROM
events
LEFT JOIN plain_events USING (event_id)

View File

@@ -11,6 +11,7 @@ from datamodels import DataModel
from constants import DATA_VERSION
from routes.stamps import routes as stamp_routes
from routes.documents import routes as doc_routes
from routes.lib import dbvar, datamodelsv
sys.path.insert(0, os.path.join(os.getcwd()))
@@ -74,6 +75,7 @@ async def app_factory():
app.cleanup_ctx.append(attach_db)
app.router.add_get('/', test)
app.router.add_routes(stamp_routes)
app.router.add_routes(doc_routes)
return app

View File

@@ -83,9 +83,9 @@ class Document:
conds = []
if document_id is not None:
conds.append(Doc.document_id == document_id)
conds.append(Doc.document_id == int(document_id))
if seal is not None:
conds.append(Doc.seal == seal)
conds.append(Doc.seal == int(seal))
if created_before is not None:
cbefore = datetime.fromisoformat(created_before)
conds.append(Doc.created_at <= cbefore)
@@ -96,9 +96,9 @@ class Document:
conds.append(Doc.metadata == metadata)
query = data.Document.table.fetch_rows_where(*conds)
results = await query
# results = await query
query = data.Document.table.select_where(*conds)
# query = data.Document.table.select_where(*conds)
if stamp_type is not None:
query.join('document_stamps', using=('document_id',), join_type=JOINTYPE.LEFT)
query.join(
@@ -119,7 +119,7 @@ class Document:
else:
rows = await query
return [cls(app, row) for row in rows]
return [cls(app, row) for row in sorted(rows, key=lambda row:row.created_at)]
@classmethod
async def create(cls, app: web.Application, **kwargs: Unpack[DocCreateParams]) -> Self:
@@ -147,7 +147,7 @@ class Document:
return cls(app, row)
async def get_stamps(self) -> List[Stamp]:
stamprows = await self.data.DocumentStamp.table.fetch_rows_where(document_id=self.row.document_id)
stamprows = await self.data.DocumentStamp.table.fetch_rows_where(document_id=self.row.document_id).order_by('stamp_id')
return [Stamp(self.app, row) for row in stamprows]
async def prepare(self) -> DocPayload:
@@ -191,6 +191,7 @@ class Document:
@routes.view('/documents')
@routes.view('/documents/')
class DocumentsView(web.View):
async def get(self):
request = self.request
@@ -229,3 +230,64 @@ class DocumentsView(web.View):
document = await Document.create(self.request.app, **params)
payload = await document.prepare()
return web.json_response(payload)
@routes.view('/documents/{document_id}')
@routes.view('/documents/{document_id}/')
class DocumentView(web.View):
async def resolve_document(self):
request = self.request
document_id = request.match_info['document_id']
document = await Document.fetch_from_id(request.app, int(document_id))
if document is None:
raise web.HTTPNotFound(text="No document exists with the given ID.")
return document
async def get(self):
doc = await self.resolve_document()
payload = await doc.prepare()
return web.json_response(payload)
async def patch(self):
doc = await self.resolve_document()
params = await self.request.json()
edit_data = {}
for key, value in params.items():
if key not in edit_fields:
raise web.HTTPBadRequest(text=f"You cannot update field '{key}' of Document!")
edit_data[key] = value
for key in edit_fields:
if key in self.request:
edit_data.setdefault(key, self.request[key])
await doc.edit(**edit_data)
payload = await doc.prepare()
return web.json_response(payload)
async def delete(self):
doc = await self.resolve_document()
payload = await doc.delete()
return web.json_response(payload)
# We have one prefix route, /documents/{document_id}/stamps
@routes.route('*', "/documents/{document_id}{tail:/stamps}")
@routes.route('*', "/documents/{document_id}{tail:/stamps/.*}")
async def document_stamps_route(request: web.Request):
document_id = request.match_info['document_id']
document = await Document.fetch_from_id(request.app, int(document_id))
if document is None:
raise web.HTTPNotFound(text="No document exists with the given ID.")
new_path = request.match_info['tail']
new_request = request.clone(rel_url=new_path)
new_request['document_id'] = document_id
match_info = await request.app.router.resolve(new_request)
if match_info.handler:
return await match_info.handler(new_request)
else:
raise web.HTTPNotFound()

View File

@@ -76,9 +76,9 @@ class Stamp:
query_args = {}
if stamp_id is not None:
query_args['stamp_id'] = stamp_id
query_args['stamp_id'] = int(stamp_id)
if document_id is not None:
query_args['document_id'] = document_id
query_args['document_id'] = int(document_id)
if stamp_type is not None:
typerows = await data.StampType.table.fetch_rows_where(stamp_type_name=stamp_type)
typeids = [row.stamp_type_id for row in typerows]
@@ -86,7 +86,7 @@ class Stamp:
return []
query_args['stamp_type'] = typeids
results = await data.DocumentStamp.table.fetch_rows_where(**query_args)
return [cls(app, row) for row in results]
return [cls(app, row) for row in sorted(results, key=lambda row:row.stamp_id)]
@classmethod
async def create(
@@ -150,7 +150,7 @@ class Stamp:
'pos_y': 'position_y',
'rotation': 'rotation'
}
for editkey, datakey in simple_keys.values():
for editkey, datakey in simple_keys.items():
if editkey in kwargs:
edit_args[datakey] = kwargs[editkey]
@@ -165,6 +165,7 @@ class Stamp:
@routes.view('/stamps')
@routes.view('/stamps/', name='stamps')
class StampsView(web.View):
async def get(self):
request = self.request
@@ -221,6 +222,7 @@ class StampsView(web.View):
@routes.view('/stamps/{stamp_id}')
@routes.view('/stamps/{stamp_id}/', name='stamp')
class StampView(web.View):
async def resolve_stamp(self):