Refactored some stuff
This commit is contained in:
parent
aa8be6006c
commit
08d060e160
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
Loading…
Reference in New Issue
Block a user