actually fix asset saving and loading

This commit is contained in:
Georges-Antoine Assi
2024-01-21 20:18:48 -05:00
parent e069e80a46
commit c889fbbd96
8 changed files with 119 additions and 63 deletions

View File

@@ -4,7 +4,7 @@ from endpoints.responses import MessageResponse
from endpoints.responses.assets import UploadedSavesResponse, SaveSchema
from fastapi import APIRouter, File, HTTPException, Request, UploadFile, status
from handler import db_save_handler, fs_asset_handler, db_rom_handler
from handler.scan_handler import scan_save
from handler.scan_handler import scan_save, build_asset_file_path
from logger.logger import log
from config import LIBRARY_BASE_PATH
@@ -13,7 +13,10 @@ router = APIRouter()
@protected_route(router.post, "/saves", ["assets.write"])
def add_saves(
request: Request, rom_id: int, saves: list[UploadFile] = File(...)
request: Request,
rom_id: int,
saves: list[UploadFile] = File(...),
emulator: str = None,
) -> UploadedSavesResponse:
rom = db_rom_handler.get_roms(rom_id)
log.info(f"Uploading saves to {rom.name}")
@@ -24,15 +27,19 @@ def add_saves(
detail="No saves were uploaded",
)
saves_path = fs_asset_handler.build_upload_file_path(
rom.platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME
saves_path = build_asset_file_path(
rom.platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME, emulator=emulator
)
for save in saves:
fs_asset_handler._write_file(file=save, path=saves_path)
fs_asset_handler._write_file(
file=save, path=f"{LIBRARY_BASE_PATH}/{saves_path}"
)
# Scan or update save
scanned_save = scan_save(platform=rom.platform, file_name=save.filename)
scanned_save = scan_save(
platform=rom.platform, file_name=save.filename, emulator=emulator
)
db_save = db_save_handler.get_save_by_filename(rom.id, save.filename)
if db_save:
db_save_handler.update_save(

View File

@@ -4,7 +4,7 @@ from endpoints.responses import MessageResponse
from endpoints.responses.assets import UploadedStatesResponse, StateSchema
from fastapi import APIRouter, File, HTTPException, Request, UploadFile, status
from handler import db_state_handler, db_rom_handler, fs_asset_handler
from handler.scan_handler import scan_state
from handler.scan_handler import scan_state, build_asset_file_path
from logger.logger import log
from config import LIBRARY_BASE_PATH
@@ -13,7 +13,10 @@ router = APIRouter()
@protected_route(router.post, "/states", ["assets.write"])
def add_states(
request: Request, rom_id: int, states: list[UploadFile] = File(...)
request: Request,
rom_id: int,
states: list[UploadFile] = File(...),
emulator: str = None,
) -> UploadedStatesResponse:
rom = db_rom_handler.get_roms(rom_id)
log.info(f"Uploading states to {rom.name}")
@@ -24,15 +27,19 @@ def add_states(
detail="No states were uploaded",
)
states_path = fs_asset_handler.build_upload_file_path(
rom.platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME
states_path = build_asset_file_path(
rom.platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME, emulator=emulator
)
for state in states:
fs_asset_handler._write_file(file=state, path=states_path)
fs_asset_handler._write_file(
file=state, path=f"{LIBRARY_BASE_PATH}/{states_path}"
)
# Scan or update state
scanned_state = scan_state(platform=rom.platform, file_name=state.filename)
scanned_state = scan_state(
platform=rom.platform, file_name=state.filename, emulator=emulator
)
db_state = db_state_handler.get_state_by_filename(rom.id, state.filename)
if db_state:
db_state_handler.update_state(

View File

@@ -122,5 +122,5 @@ class FSHandler(ABC):
def build_upload_file_path(
self, fs_slug: str, folder: str = cm.config.ROMS_FOLDER_NAME
):
rom_path = self.get_fs_structure(fs_slug, folder=folder)
return f"{LIBRARY_BASE_PATH}/{rom_path}"
file_path = self.get_fs_structure(fs_slug, folder=folder)
return f"{LIBRARY_BASE_PATH}/{file_path}"

View File

@@ -185,36 +185,34 @@ def _scan_asset(file_name: str, path: str):
}
def scan_save(platform: Platform, file_name: str, emulator: str = None) -> Save:
saves_path = fs_asset_handler.get_fs_structure(
platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME
)
def build_asset_file_path(fs_slug: str, folder: str, emulator: str = None):
saves_path = fs_asset_handler.get_fs_structure(fs_slug, folder=folder)
# Scan asset with the sames path and emulator folder name
if emulator:
return Save(**_scan_asset(file_name, os.path.join(saves_path, emulator)))
return os.path.join(saves_path, emulator)
return saves_path
def scan_save(platform: Platform, file_name: str, emulator: str = None) -> Save:
saves_path = build_asset_file_path(
platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME, emulator=emulator
)
return Save(**_scan_asset(file_name, saves_path))
def scan_state(platform: Platform, file_name: str, emulator: str = None) -> State:
states_path = fs_asset_handler.get_fs_structure(
platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME
states_path = build_asset_file_path(
platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME, emulator=emulator
)
# Scan asset with the sames path and emulator folder name
if emulator:
return State(**_scan_asset(file_name, os.path.join(states_path, emulator)))
return State(**_scan_asset(file_name, states_path))
def scan_screenshot(file_name: str, platform: Platform = None) -> Screenshot:
screenshots_path = fs_asset_handler.get_fs_structure(
if not platform:
return Screenshot(**_scan_asset(file_name, cm.config.SCREENSHOTS_FOLDER_NAME))
screenshots_path = build_asset_file_path(
platform.fs_slug, folder=cm.config.SCREENSHOTS_FOLDER_NAME
)
if platform:
return Screenshot(**_scan_asset(file_name, screenshots_path))
return Screenshot(**_scan_asset(file_name, cm.config.SCREENSHOTS_FOLDER_NAME))
return Screenshot(**_scan_asset(file_name, screenshots_path))

View File

@@ -7,17 +7,20 @@ export const saveApi = api;
async function uploadSaves({
rom,
saves,
emulator,
}: {
rom: Rom;
saves: File[];
emulator?: string;
}): Promise<{ data: UploadedSavesResponse }> {
let formData = new FormData();
saves.forEach((save) => formData.append("saves", save));
return api.post("/saves", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
params: { rom_id: rom.id },
params: { rom_id: rom.id, emulator },
});
}

View File

@@ -7,9 +7,11 @@ export const stateApi = api;
async function uploadStates({
rom,
states,
emulator,
}: {
rom: Rom;
states: File[];
emulator?: string;
}): Promise<{ data: UploadedStatesResponse }> {
let formData = new FormData();
states.forEach((state) => formData.append("states", state));
@@ -18,7 +20,7 @@ async function uploadStates({
headers: {
"Content-Type": "multipart/form-data",
},
params: { rom_id: rom.id },
params: { rom_id: rom.id, emulator },
});
}

View File

@@ -244,37 +244,74 @@ export function languageToEmoji(language: string) {
export const platformSlugEJSPlatformMap: Record<string, string> = {
"3do": "3do",
"amiga": "amiga",
"arcade": "arcade",
"atari2600": "atari2600",
"atari5200": "atari5200",
"atari7800": "atari7800",
"c64": "c64",
"colecovision": "coleco",
"jaguar": "jaguar",
"lynx": "lynx",
"mame": "mame2003",
amiga: "amiga",
arcade: "arcade",
atari2600: "atari2600",
atari5200: "atari5200",
atari7800: "atari7800",
c64: "c64",
colecovision: "coleco",
jaguar: "jaguar",
lynx: "lynx",
mame: "mame2003",
"neo-geo-pocket": "ngp",
"neo-geo-pocket-color": "ngp",
"nes": "nes",
"famicom": "nes",
"n64": "n64",
"nds": "nds",
"gba": "gba",
"gb": "gb",
nes: "nes",
famicom: "nes",
n64: "n64",
nds: "nds",
gba: "gba",
gb: "gb",
"pc-fx": "pcfx",
"ps": "psx",
"psp": "psp",
"segacd": "segaCD",
"sega32": "sega32x",
"gamegear": "segaGG",
"sms": "segaMS",
ps: "psx",
psp: "psp",
segacd: "segaCD",
sega32: "sega32x",
gamegear: "segaGG",
sms: "segaMS",
"genesis-slash-megadrive": "segaMD",
"saturn": "segaSaturn",
"snes": "snes",
"sfam": "snes",
saturn: "segaSaturn",
snes: "snes",
sfam: "snes",
"turbografx16--1": "pce",
"virtualboy": "vb",
"wonderswan": "ws",
virtualboy: "vb",
wonderswan: "ws",
"wonderswan-color": "ws",
} as const;
export const platformSlugEJSCoreMap: Record<string, string> = {
"3do": "opera",
amiga: "puae",
arcade: "fbneo",
atari2600: "stella2014",
atari5200: "a5200",
atari7800: "prosystem",
c64: "vice_x64",
colecovision: "gearcoleco",
jaguar: "virtualjaguar",
lynx: "handy",
mame: "mame2003_plus",
"neo-geo-pocket": "mednafen_ngp",
"neo-geo-pocket-color": "mednafen_ngp",
nes: "fceumm",
"famicom": "fceumm",
n64: "mupen64plus_next",
nds: "melonds",
gba: "mgba",
gb: "gambatte",
"pc-fx": "mednafen_pcfx",
ps: "pcsx_rearmed",
psp: "ppsspp",
segacd: "genesis_plus_gx",
sega32: "picodrive",
gamegear: "genesis_plus_gx",
sms: "genesis_plus_gx",
"genesis-slash-megadrive": "genesis_plus_gx",
saturn: "yabause",
snes: "snes9x",
sfam: "snes9x",
"turbografx16--1": "mednafen_pce",
virtualboy: "beetle_vb",
wonderswan: "mednafen_wswan",
"wonderswan-color": "mednafen_wswan",
} as const;

View File

@@ -4,7 +4,7 @@ import stateApi from "@/services/api/state";
import saveApi, { saveApi as api } from "@/services/api/save";
import screenshotApi from "@/services/api/screenshot";
import type { Rom } from "@/stores/roms";
import { platformSlugEJSPlatformMap } from "@/utils";
import { platformSlugEJSPlatformMap, platformSlugEJSCoreMap } from "@/utils";
import type { SaveSchema, StateSchema } from "@/__generated__";
const props = defineProps<{
@@ -171,6 +171,7 @@ window.EJS_onSaveState = function ({
stateApi
.uploadStates({
rom: props.rom,
emulator: platformSlugEJSCoreMap[props.rom.platform_slug],
states: [
new File([state], buildStateName(), {
type: "application/octet-stream",
@@ -282,6 +283,7 @@ window.EJS_onSaveSave = function ({
saveApi
.uploadSaves({
rom: props.rom,
emulator: platformSlugEJSCoreMap[props.rom.platform_slug],
saves: [
new File([save], buildSaveName(), {
type: "application/octet-stream",