1
1
import datetime
2
- from typing import List
2
+ from typing import List , Optional
3
3
4
- from fastapi import FastAPI
4
+ from fastapi import FastAPI , HTTPException , Query
5
5
from placedump .model import Pixel , async_sm
6
6
from pydantic import BaseModel
7
7
from sqlalchemy import func , select
11
11
12
12
class PixelResult (BaseModel ):
13
13
canvas : int
14
+ user : str
14
15
x : int
15
16
y : int
16
17
modified : datetime .datetime
@@ -22,7 +23,7 @@ class CountableBase(BaseModel):
22
23
23
24
24
25
class PixelList (CountableBase ):
25
- pixels : List [PixelResult ]
26
+ history : List [PixelResult ]
26
27
27
28
28
29
class PixelInfo (CountableBase ):
@@ -34,8 +35,8 @@ async def root():
34
35
return {"message" : "Hello World" }
35
36
36
37
37
- @app .get ("/pixels " , response_model = PixelInfo )
38
- async def pixels ():
38
+ @app .get ("/info " , response_model = PixelInfo )
39
+ async def info ():
39
40
async with async_sm () as db :
40
41
count_query = select (func .count ()).select_from (Pixel )
41
42
pixel_count = await db .execute (count_query )
@@ -44,61 +45,80 @@ async def pixels():
44
45
return {"count" : pixel_count , "generated" : datetime .datetime .utcnow ()}
45
46
46
47
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.
56
58
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.
59
60
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.
63
62
64
- pixels = [x .to_dict () for x in filtered_pixels ]
63
+ This call accepts authors to pull pixels changed by that author.
64
+ """
65
65
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
71
72
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
72
80
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."""
77
81
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 )
84
97
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 )
87
102
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.
88
114
pixel_count = await db .execute (count_query )
89
115
pixel_count = pixel_count .scalar_one ()
90
116
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 )
96
117
filtered_pixels = (await db .execute (filter_query )).scalars ()
97
-
98
118
pixels = [x .to_dict () for x in filtered_pixels ]
99
119
100
120
return {
101
121
"count" : pixel_count ,
102
122
"generated" : datetime .datetime .utcnow (),
103
- "pixels " : pixels ,
123
+ "history " : pixels ,
104
124
}
0 commit comments