Fix map searching.

This commit is contained in:
magmaus3 2022-12-04 12:54:50 +01:00
parent 7f9bf38da0
commit 270cae46b2
Signed by: magmaus3
GPG key ID: 966755D3F4A9B251
2 changed files with 45 additions and 15 deletions

View file

@ -1,6 +1,6 @@
from pydantic import BaseModel from pydantic import BaseModel
from typing import List, Optional, Union from typing import List, Optional, Union
from datetime import datetime
class User(BaseModel): class User(BaseModel):
"""Pydantic model for user data. """Pydantic model for user data.
@ -13,7 +13,7 @@ class User(BaseModel):
CapeColor: int = 0 CapeColor: int = 0
Costume: int = 0 Costume: int = 0
Country: int = 0 Country: int = 0
CreatedAt: str = "2020-02-14T10:03:40Z" CreatedAt: str = datetime.strftime(datetime.now(), "%Y-%m-%dT%H:%M:%SZ")
DeathEffect: int = 0 DeathEffect: int = 0
DeletedAt: Optional[str] = None DeletedAt: Optional[str] = None
FacialExpression: int = 0 FacialExpression: int = 0
@ -49,7 +49,7 @@ class User(BaseModel):
SwordSpr: int = 0 SwordSpr: int = 0
TextSnd: int = 0 TextSnd: int = 0
Unlocks: str = "" Unlocks: str = ""
UpdatedAt: str = "2020-03-26T05:22:32Z" UpdatedAt: str = datetime.strftime(datetime.now(), "%Y-%m-%dT%H:%M:%SZ")
Username: str = "magmaus3" Username: str = "magmaus3"
Email: str = "user@example.com" Email: str = "user@example.com"
@ -115,8 +115,8 @@ class Notification(BaseModel):
otherwise the game crashes (as of `Early Access Ver 0.786`) otherwise the game crashes (as of `Early Access Ver 0.786`)
""" """
CreatedAt: str = "2008-01-18T00:00:00Z" CreatedAt: str = datetime.strftime(datetime.now(), "%Y-%m-%dT%H:%M:%SZ")
UpdatedAt: str = "2008-01-18T00:00:00Z" UpdatedAt: str = datetime.strftime(datetime.now(), "%Y-%m-%dT%H:%M:%SZ")
DeletedAt: Optional[str] = None DeletedAt: Optional[str] = None
ForUserID: int = 0 ForUserID: int = 0
ID: int = 0 ID: int = 0
@ -151,7 +151,7 @@ class Map(BaseModel):
Name: str = "Interesting level" Name: str = "Interesting level"
Description: str = "" Description: str = ""
Version: int = 90 Version: int = 90
CreatedAt: str = "2022-06-18T15:10:02Z" CreatedAt: str = datetime.strftime(datetime.now(), "%Y-%m-%dT%H:%M:%SZ")
DeletedAt: Union[str, None] = None DeletedAt: Union[str, None] = None
MapCode: str = "AAABBAAA" MapCode: str = "AAABBAAA"
Listed: bool = True Listed: bool = True
@ -234,7 +234,7 @@ class MapLeaderboard(BaseModel):
"""Pydantic model for Map record leaderboards.""" """Pydantic model for Map record leaderboards."""
BestPlaytime: int BestPlaytime: int
BestPlaytimeTime: str BestPlaytimeTime: str = datetime.strftime(datetime.now(), "%Y-%m-%dT%H:%M:%SZ")
BestReplay: str BestReplay: str
CreatorName: str CreatorName: str
UserID: int UserID: int

View file

@ -1,3 +1,4 @@
from datetime import datetime
from fastapi import FastAPI, Form, File, UploadFile, Header, HTTPException, Body from fastapi import FastAPI, Form, File, UploadFile, Header, HTTPException, Body
from fastapi.responses import PlainTextResponse from fastapi.responses import PlainTextResponse
from fastapi.exceptions import RequestValidationError from fastapi.exceptions import RequestValidationError
@ -114,16 +115,46 @@ async def search_for_maps(
author: str = "", author: str = "",
author_id: Optional[int] = None, author_id: Optional[int] = None,
last_x_hours: Optional[int] = None, last_x_hours: Optional[int] = None,
required_tags: str = "",
disallowed_tags: str = "",
code: Optional[str] = None,
admin_show_unlisted: Optional[int] = 0,
): ):
"""Search for maps.""" """Search for maps."""
# query = db.maps_collection.find({ "CreatorId": author_id }).limit(limit) # query = db.maps_collection.find({ "CreatorId": author_id }).limit(limit)
query = db.maps_collection.find({}).limit(limit) if code:
query = list(db.maps_collection.find({"MapCode": code}).skip(start).limit(limit))[0]
del query["_id"]
del query["MapData"]
return [query]
query = db.maps_collection.find({}).skip(start).limit(limit)
entries = [] entries = []
# Convert required_tags and disallowed_tags to a list.
required_tag_list = required_tags.split(",") if required_tags != "" else []
disallowed_tag_list = disallowed_tags.split(",") if disallowed_tags != "" else []
for i in query: for i in query:
del i["_id"] del i["_id"]
del i["MapData"] del i["MapData"]
entries.append(i)
if not i["Listed"] and admin_show_unlisted != 1:
continue
level_tags = i['TagIDs'].split(",")
CreatedAt = datetime.strptime(i["CreatedAt"], "%Y-%m-%dT%H:%M:%SZ")
# TODO: Improve tag filtering
required_tags_included = False if len(required_tag_list) != 0 else True
disallowed_tags_included = False
for tag in level_tags:
if tag in disallowed_tag_list and len(disallowed_tag_list) != 0: disallowed_tags_included = True
elif tag in required_tag_list and len(required_tag_list) != 0: required_tags_included = True
else:
if required_tags_included and not disallowed_tags_included:
if not last_x_hours or CreatedAt.hour < last_x_hours:
entries.append(i)
return entries return entries
@ -135,7 +166,7 @@ async def getMap(mapID: int):
@app.post("/api/v1/map/{mapID}/start") @app.post("/api/v1/map/{mapID}/start")
async def getMap(mapID: int): async def startMap(mapID: int):
query = db.maps_collection.find_one({"ID": mapID}) query = db.maps_collection.find_one({"ID": mapID})
del query["_id"] del query["_id"]
@ -232,7 +263,6 @@ async def stopMapPlay(
SaveEffect=userData.SaveEffect, SaveEffect=userData.SaveEffect,
TextSnd=userData.TextSnd, TextSnd=userData.TextSnd,
BestPlaytime=playtime, BestPlaytime=playtime,
BestPlaytimeTime="2020-02-13T15:19:33Z",
BestReplay=replayData, BestReplay=replayData,
CreatorName=userData.Username, CreatorName=userData.Username,
UserID=userData.ID, UserID=userData.ID,
@ -327,7 +357,6 @@ async def upload_map(
Leaderboard=[ Leaderboard=[
types.MapLeaderboard( types.MapLeaderboard(
BestPlaytime=playtime, BestPlaytime=playtime,
BestPlaytimeTime="2020-02-13T15:19:33Z",
BestReplay=mapReplay, BestReplay=mapReplay,
CreatorName=userData.Username, CreatorName=userData.Username,
UserID=userData.ID, UserID=userData.ID,
@ -341,7 +370,7 @@ async def upload_map(
@app.get("/api/v1/map/{mapID}/besttimes/{maxEntries}") @app.get("/api/v1/map/{mapID}/besttimes/{maxEntries}")
async def getMapLeaderboard(mapID, maxEntries): async def getMapLeaderboard(mapID: int, maxEntries: int = 5):
"""Returns maxEntries records for the specified level""" """Returns maxEntries records for the specified level"""
query = db.maps_collection.find_one({"ID": int(mapID)}) query = db.maps_collection.find_one({"ID": int(mapID)})
if not query: if not query:
@ -349,7 +378,7 @@ async def getMapLeaderboard(mapID, maxEntries):
del query["_id"] del query["_id"]
leaderboard = query["Leaderboard"] leaderboard = query["Leaderboard"]
return sorted(leaderboard, key=lambda sort: sort["BestPlaytime"])[0:5] return sorted(leaderboard, key=lambda sort: sort["BestPlaytime"])[0:maxEntries]
@app.get("/api/v1/map/{mapID}/userbesttime/{userID}") @app.get("/api/v1/map/{mapID}/userbesttime/{userID}")
@ -473,7 +502,8 @@ async def featuredlist():
@app.get("/api/v1/followcheck") @app.get("/api/v1/followcheck")
async def followcheck(): async def followcheck():
# FIXME Find the purpouse of this endpoint """Check, if creators that the user follows uploaded new levels."""
# FIXME: Stub
return 1 return 1