Skip to content

Commit 3470ceb

Browse files
committed
api changes to make querying for pixels work
1 parent 858eb52 commit 3470ceb

File tree

1 file changed

+64
-44
lines changed

1 file changed

+64
-44
lines changed

placedump/api/__init__.py

Lines changed: 64 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import datetime
2-
from typing import List
2+
from typing import List, Optional
33

4-
from fastapi import FastAPI
4+
from fastapi import FastAPI, HTTPException, Query
55
from placedump.model import Pixel, async_sm
66
from pydantic import BaseModel
77
from sqlalchemy import func, select
@@ -11,6 +11,7 @@
1111

1212
class PixelResult(BaseModel):
1313
canvas: int
14+
user: str
1415
x: int
1516
y: int
1617
modified: datetime.datetime
@@ -22,7 +23,7 @@ class CountableBase(BaseModel):
2223

2324

2425
class PixelList(CountableBase):
25-
pixels: List[PixelResult]
26+
history: List[PixelResult]
2627

2728

2829
class PixelInfo(CountableBase):
@@ -34,8 +35,8 @@ async def root():
3435
return {"message": "Hello World"}
3536

3637

37-
@app.get("/pixels", response_model=PixelInfo)
38-
async def pixels():
38+
@app.get("/info", response_model=PixelInfo)
39+
async def info():
3940
async with async_sm() as db:
4041
count_query = select(func.count()).select_from(Pixel)
4142
pixel_count = await db.execute(count_query)
@@ -44,61 +45,80 @@ async def pixels():
4445
return {"count": pixel_count, "generated": datetime.datetime.utcnow()}
4546

4647

47-
@app.get("/pixels/author/<author: str>", response_model=PixelList)
48-
async def get_pixel_history_by_author(author: str):
49-
async with async_sm() as db:
50-
# Count all.
51-
count_query = (
52-
select(func.count())
53-
.select_from(Pixel)
54-
.filter(func.lower(Pixel.user) == author.lower())
55-
)
48+
@app.get("/pixel", response_model=PixelList)
49+
async def get_pixel_history(
50+
x: Optional[int] = Query(None, ge=0),
51+
y: Optional[int] = Query(None, ge=0),
52+
canvas_id: Optional[int] = Query(None, ge=-1),
53+
author: Optional[str] = None,
54+
limit: Optional[int] = Query(100, ge=0),
55+
after: Optional[int] = None,
56+
):
57+
"""Get the history of pixels in a location or by author.
5658
57-
pixel_count = await db.execute(count_query)
58-
pixel_count = pixel_count.scalar_one()
59+
This call accepts positions with X, Y coordinates, without a canvas.
5960
60-
# Query all.
61-
filter_query = select(Pixel).filter(func.lower(Pixel.user) == author.lower())
62-
filtered_pixels = (await db.execute(filter_query)).scalars()
61+
This call accepts positions with X, Y coordinates in specific canvases.
6362
64-
pixels = [x.to_dict() for x in filtered_pixels]
63+
This call accepts authors to pull pixels changed by that author.
64+
"""
6565

66-
return {
67-
"count": pixel_count,
68-
"generated": datetime.datetime.utcnow(),
69-
"pixels": pixels,
70-
}
66+
if all(x is None for x in [x, y, canvas_id, author]):
67+
raise HTTPException(status_code=400, detail="Missing parameters.")
68+
69+
# GOOD ENOUGH HACK
70+
if canvas_id is None:
71+
canvas_id = 0
7172

73+
if x and x > 999:
74+
canvas_id += 1
75+
x -= 999
76+
77+
if y and y > 999:
78+
canvas_id += 2
79+
y -= 999
7280

73-
@app.get("/pixels/canvas/<canvas: int>/<x: int>/<y: int>")
74-
async def get_pixel_history_by_cords(canvas: int, x: int, y: int):
75-
"""Get the history of a specific pixel.
76-
Using a value of -1 for canvas will get it for all canvases."""
7781
async with async_sm() as db:
78-
count_query = (
79-
select(func.count())
80-
.select_from(Pixel)
81-
.filter(Pixel.x == x)
82-
.filter(Pixel.y == y)
83-
)
82+
# Create count query, no limits.
83+
count_query = select(func.count()).select_from(Pixel)
84+
85+
# Query all with limit.
86+
filter_query = select(Pixel).order_by(Pixel.modified).limit(limit)
87+
88+
if after:
89+
timestamp = float(after) / 1000.0
90+
timestamp = datetime.datetime.fromtimestamp(timestamp)
91+
filter_query = filter_query.filter(Pixel.modified >= timestamp)
92+
93+
# Canvas
94+
if canvas_id:
95+
count_query = count_query.filter(Pixel.board_id == canvas_id)
96+
filter_query = filter_query.filter(Pixel.board_id == canvas_id)
8497

85-
if canvas != -1:
86-
count_query = count_query.filter(Pixel.board_id == canvas)
98+
# X filters
99+
if x:
100+
count_query = count_query.filter(Pixel.x == x)
101+
filter_query = filter_query.filter(Pixel.x == x)
87102

103+
# Y filters
104+
if y:
105+
count_query = count_query.filter(Pixel.y == y)
106+
filter_query = filter_query.filter(Pixel.y == y)
107+
108+
# Filter: Author
109+
if author:
110+
count_query = count_query.filter(Pixel.user == author)
111+
filter_query = filter_query.filter(Pixel.user == author)
112+
113+
# Execute queries.
88114
pixel_count = await db.execute(count_query)
89115
pixel_count = pixel_count.scalar_one()
90116

91-
# Query all.
92-
filter_query = select(Pixel).filter(Pixel.x == x).filter(Pixel.y == y)
93-
94-
if canvas != -1:
95-
filter_query = filter_query.filter(Pixel.board_id == canvas)
96117
filtered_pixels = (await db.execute(filter_query)).scalars()
97-
98118
pixels = [x.to_dict() for x in filtered_pixels]
99119

100120
return {
101121
"count": pixel_count,
102122
"generated": datetime.datetime.utcnow(),
103-
"pixels": pixels,
123+
"history": pixels,
104124
}

0 commit comments

Comments
 (0)