Refactored some stuff

This commit is contained in:
Profitroll 2023-01-19 13:47:18 +01:00
parent aa8be6006c
commit 08d060e160
3 changed files with 23 additions and 64 deletions

View File

@ -1,64 +1,17 @@
from datetime import datetime from datetime import datetime
from io import BytesIO
from urllib.parse import quote_plus from urllib.parse import quote_plus
from os import makedirs, path, remove from os import remove
from typing import Dict, List, Tuple, Union from typing import Dict, List, Union
from uuid import uuid4
from zipfile import ZipFile, ZIP_DEFLATED
from xmltodict import parse from xmltodict import parse
from models.saves import StardewSave from models.saves import StardewSave
from modules.app import app, get_api_key, user_by_key from modules.app import app, get_api_key, user_by_key
from modules.utils import configGet, saveFile
from modules.database import col_devices, col_saves from modules.database import col_devices, col_saves
from fastapi import HTTPException, Depends, UploadFile from fastapi import HTTPException, Depends, UploadFile
from fastapi.responses import UJSONResponse, FileResponse, Response from fastapi.responses import UJSONResponse, FileResponse, Response
from fastapi.openapi.models import APIKey from fastapi.openapi.models import APIKey
from starlette.status import HTTP_204_NO_CONTENT, HTTP_404_NOT_FOUND, HTTP_406_NOT_ACCEPTABLE from starlette.status import HTTP_204_NO_CONTENT, HTTP_404_NOT_FOUND, HTTP_406_NOT_ACCEPTABLE
def zip_saves(save_filename: str, save_bytes: bytes, saveinfo_bytes: bytes) -> Tuple[str, str]: from modules.utils import zip_saves
save_uuid = str(uuid4())
makedirs(path.join(configGet("data", "locations"), "files", save_uuid))
#saveFile(save_bytes, filename=save_filename, dirname=zipname)
#saveFile(saveinfo_bytes, filename="SaveGameInfo", dirname=zipname)
with ZipFile(path.join(configGet("data", "locations"), "files", save_uuid, save_filename+".svsave"), 'w', ZIP_DEFLATED, compresslevel=configGet("compression")) as ziph:
ziph.writestr("SaveGameInfo", saveinfo_bytes)
ziph.writestr(save_filename, save_bytes)
return save_uuid, path.join(configGet("data", "locations"), "files", save_uuid, save_filename+".svsave")
def zipfiles(filenames, save_name: str) -> Response:
zip_filename = save_name+".svsave"
s = BytesIO()
zf = ZipFile(s, "w")
for fpath in filenames:
# Calculate path for file in zip
fdir, fname = path.split(fpath)
# Add file, at correct path
for entry in (list(col_saves.find({"files.save.uuid": fname})) + list(col_saves.find({"files.saveinfo.uuid": fname}))):
filename = entry["file"]["save"]["name"] if (entry["file"]["save"]["uuid"] == fname) else entry["file"]["saveinfo"]["name"]
zf.write(fpath, filename)
# Must close zip for all contents to be written
zf.close()
# Grab ZIP file from in-memory, make response with correct MIME-type
return Response(
s.getvalue(),
media_type="application/x-zip-compressed",
headers={
'Content-Disposition': f'attachment;filename={quote_plus(zip_filename)}'
}
)
@app.get("/saves", response_class=UJSONResponse, response_model=Dict[str, StardewSave], description="Get all available game saves") @app.get("/saves", response_class=UJSONResponse, response_model=Dict[str, StardewSave], description="Get all available game saves")
@ -149,7 +102,6 @@ async def saves_download(id: int, save_date: int, device: Union[str, None] = Non
} }
) )
return response return response
# return zipfiles([saves_entry["file"]["save"]["path"], saves_entry["file"]["saveinfo"]["path"]], save_name=f'{saves_entry["data"]["farmer"]}_{saves_entry["id"]}')
else: else:
raise HTTPException(HTTP_404_NOT_FOUND, detail="Could not find save with such id.") raise HTTPException(HTTP_404_NOT_FOUND, detail="Could not find save with such id.")
@ -204,7 +156,8 @@ async def saves_post(device: str, files: List[UploadFile], apikey: APIKey = Depe
"save_time": int(save_info["Farmer"]["saveTime"]), "save_time": int(save_info["Farmer"]["saveTime"]),
"year": int(save_info["Farmer"]["yearForSaveGame"]), "year": int(save_info["Farmer"]["yearForSaveGame"]),
"season": int(save_info["Farmer"]["seasonForSaveGame"]), "season": int(save_info["Farmer"]["seasonForSaveGame"]),
"day": int(save_info["Farmer"]["dayOfMonthForSaveGame"]) "day": int(save_info["Farmer"]["dayOfMonthForSaveGame"]),
"game_version": save_info["Farmer"]["gameVersion"]
}, },
"file": { "file": {
"name": save_data_filename, "name": save_data_filename,

View File

@ -8,6 +8,7 @@ class StardewSaveData(BaseModel):
year: int year: int
season: int season: int
day: int day: int
game_version: str
class StardewSave(BaseModel): class StardewSave(BaseModel):
id: int id: int

View File

@ -1,6 +1,7 @@
from os import makedirs, path from os import makedirs, path
from typing import Any, Tuple, Union from typing import Any, Tuple, Union
from uuid import uuid4 from uuid import uuid4
from zipfile import ZIP_DEFLATED, ZipFile
from ujson import loads, dumps, JSONDecodeError from ujson import loads, dumps, JSONDecodeError
from traceback import print_exc from traceback import print_exc
@ -62,20 +63,24 @@ def configGet(key: str, *args: str) -> Any:
this_key = this_key[dict_key] this_key = this_key[dict_key]
return this_key[key] return this_key[key]
def saveFile(filebytes: bytes, filename: Union[str, None] = None, dirname: Union[str, None] = None) -> Tuple[str, str]: def zip_saves(save_filename: str, save_bytes: bytes, saveinfo_bytes: bytes) -> Tuple[str, str]:
"""Save some bytedata into random file and return its ID """Save files of the SV save into archive and return uuid and path
### Args: ### Args:
* filebytes (`bytes`): Bytes to write into file * save_filename (`str`): Filename of the save file
vsave_bytes (`bytes`): Bytes of the save file
* saveinfo_bytes (`bytes`): Bytes of the save info file
### Returns: ### Returns:
* `Tuple[str, str]`: Tuple where first item is an ID and the second is an absolute path to file * `Tuple[str, str]`: First element is an UUID and the second is a filepath
""" """
pathlist = [configGet("data", "locations"), "files"]
if dirname is not None: save_uuid = str(uuid4())
pathlist.append(dirname)
makedirs(path.join(pathlist), exist_ok=True) makedirs(path.join(configGet("data", "locations"), "files", save_uuid))
filename = str(uuid4()) if filename is None else filename
with open(path.join(pathlist+[filename], "wb")) as file: with ZipFile(path.join(configGet("data", "locations"), "files", save_uuid, save_filename+".svsave"), 'w', ZIP_DEFLATED, compresslevel=configGet("compression")) as ziph:
file.write(filebytes) ziph.writestr("SaveGameInfo", saveinfo_bytes)
return filename, path.join(pathlist+[filename]) ziph.writestr(save_filename, save_bytes)
return save_uuid, path.join(configGet("data", "locations"), "files", save_uuid, save_filename+".svsave")