diff --git a/backend/endpoints/rom.py b/backend/endpoints/rom.py index 4432fcaa9..928c7b090 100644 --- a/backend/endpoints/rom.py +++ b/backend/endpoints/rom.py @@ -35,9 +35,8 @@ async def updateRom(req: Request, p_slug: str, id: int) -> dict: try: fs.rename_rom(platform.fs_slug, db_rom.file_name, updated_rom['file_name']) except RomAlreadyExistsException as e: - error: str = f"{e}" - log.error(error) - raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error) + log.error(str(e)) + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)) updated_rom['file_name_no_tags'] = get_file_name_with_no_tags(updated_rom['file_name']) updated_rom.update(fs.get_cover(True, p_slug, updated_rom['file_name'], updated_rom['url_cover'])) updated_rom.update(fs.get_screenshots(p_slug, updated_rom['file_name'], updated_rom['url_screenshots'])) @@ -58,7 +57,7 @@ def delete_rom(p_slug: str, id: int, filesystem: bool=False) -> dict: platform: Platform = dbh.get_platform(p_slug) fs.remove_rom(platform.fs_slug, rom.file_name) except RomNotFoundError as e: - error: str = f"{e}. Couldn't delete from filesystem." + error = f"Couldn't delete from filesystem: {str(e)}" log.error(error) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=error) return {'msg': f'{rom.file_name} deleted successfully!'} diff --git a/backend/endpoints/scan.py b/backend/endpoints/scan.py index 9dad19980..3eb5eb94d 100644 --- a/backend/endpoints/scan.py +++ b/backend/endpoints/scan.py @@ -9,7 +9,7 @@ from models.platform import Platform from models.rom import Rom -async def scan(sid: str, platforms: str, complete_rescan: bool=True, sm=None): +async def scan(_sid: str, platforms: str, complete_rescan: bool=True, sm=None): """Scan platforms and roms and write them in database.""" log.info(emoji.emojize(":magnifying_glass_tilted_right: Scanning ")) @@ -18,7 +18,7 @@ async def scan(sid: str, platforms: str, complete_rescan: bool=True, sm=None): try: # Scanning platforms fs_platforms: list[str] = fs.get_platforms() except PlatformsNotFoundException as e: - log.error(e); await sm.emit('done_ko', e.message); return + log.error(e); await sm.emit('scan:done_ko', e.message); return platforms: list[str] = json.loads(platforms) if len(json.loads(platforms)) > 0 else fs_platforms log.info(f"Platforms to be scanned: {', '.join(platforms)}") @@ -28,7 +28,7 @@ async def scan(sid: str, platforms: str, complete_rescan: bool=True, sm=None): scanned_platform: Platform = fastapi.scan_platform(platform) except RomsNotFoundException as e: log.error(e); continue - await sm.emit('scanning_platform', [scanned_platform.name, scanned_platform.slug]); await sm.emit('') # Workaround to emit in real-time + await sm.emit('scan:scanning_platform', [scanned_platform.name, scanned_platform.slug]); await sm.emit('') # Workaround to emit in real-time if platform != str(scanned_platform): log.info(f"Identified as {COLORS['blue']}{scanned_platform}{COLORS['reset']}") dbh.add_platform(scanned_platform) @@ -37,7 +37,7 @@ async def scan(sid: str, platforms: str, complete_rescan: bool=True, sm=None): for rom in fs_roms: rom_id: int = dbh.rom_exists(scanned_platform.slug, rom['file_name']) if rom_id and not complete_rescan: continue - await sm.emit('scanning_rom', rom['file_name']); await sm.emit('') # Workaround to emit in real-time + await sm.emit('scan:scanning_rom', rom['file_name']); await sm.emit('') # Workaround to emit in real-time log.info(f"Scanning {COLORS['orange']}{rom['file_name']}{COLORS['reset']}") if rom['multi']: [log.info(f"\t - {COLORS['orange_i']}{file}{COLORS['reset']}") for file in rom['files']] scanned_rom: Rom = fastapi.scan_rom(scanned_platform, rom) @@ -45,4 +45,4 @@ async def scan(sid: str, platforms: str, complete_rescan: bool=True, sm=None): dbh.add_rom(scanned_rom) dbh.purge_roms(scanned_platform.slug, [rom['file_name'] for rom in fs_roms]) dbh.purge_platforms(fs_platforms) - await sm.emit('done') + await sm.emit('scan:done') diff --git a/backend/handler/db_handler.py b/backend/handler/db_handler.py index 1cc66609a..fba643ad6 100644 --- a/backend/handler/db_handler.py +++ b/backend/handler/db_handler.py @@ -27,9 +27,8 @@ class DBHandler: @staticmethod def raise_error(e: Exception) -> None: - error: str = f"{e}" - log.critical(error) - raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error) + log.critical(str(e)) + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)) # ========= Platforms ========= diff --git a/backend/main.py b/backend/main.py index 13a5a9476..7e52dd375 100644 --- a/backend/main.py +++ b/backend/main.py @@ -21,8 +21,12 @@ app.include_router(rom.router) sm = SocketManager() sm.mount_to("/ws", app) -async def scan_handler(*args): await scan.scan(*args, sm) -sm.on('scan', handler=scan_handler) + +async def scan_handler(*args): + await scan.scan(*args, sm) + + +sm.on("scan", handler=scan_handler) @app.on_event("startup") @@ -31,6 +35,6 @@ def startup() -> None: pass -if __name__ == '__main__': +if __name__ == "__main__": uvicorn.run("main:app", host=DEV_HOST, port=DEV_PORT, reload=True) # uvicorn.run("main:app", host=DEV_HOST, port=DEV_PORT, reload=False, workers=2) diff --git a/backend/utils/__init__.py b/backend/utils/__init__.py index 2bddd075f..f173fca5a 100644 --- a/backend/utils/__init__.py +++ b/backend/utils/__init__.py @@ -1,26 +1,85 @@ import re +LANGUAGES = [ + "Ar", + "Da", + "De", + "En", + "En-US", + "Es", + "Fi", + "Fr", + "It", + "Ja", + "Ko", + "Nl", + "Pl", + "Pt", + "Pt-BR", + "Ru", + "Sv", + "Zh", + "Zh-Hans", + "Zh-Hant", + "nolang", +] + +REGIONS = [ + ("U", "USA"), + ("E", "Europe"), + ("J", "Japan"), + ("K", "Korea"), + ("T", "Taiwan"), + ("G", "Germany"), + ("B", "Brazil"), + ("A", "Australia"), + ("CH", "China"), + ("NL", "Netherlands"), + ("PD", "Public Domain"), + ("F", "France"), + ("S", "Spain"), + ("W", "World"), + ("C", "Canada"), + ("SW", "Sweden"), + ("FN", "Finland"), + ("UK", "England"), + ("GR", "Greece"), + ("UNK", "Unknown"), + ("HK", "Hong Kong"), + ("I", "Italy"), + ("H", "Holland"), + ("UNL", "Unlicensed"), + ("AS", "Asia"), + ("R", "Russia"), + ("NO", "Norway"), +] + +REGIONS_BY_SHORTCODE = {region[0].lower(): region[1] for region in REGIONS} +REGIONS_NAME_KEYS = [region[1].lower() for region in REGIONS] + + def parse_tags(file_name: str) -> tuple: - reg: str = '' - rev: str = '' - other_tags: list = [] - tags: list = re.findall('\(([^)]+)', file_name) + reg = "" + rev = "" + other_tags = [] + tags = re.findall("\(([^)]+)", file_name) + for tag in tags: - if tag.split('-')[0].lower() == 'reg': - try: reg = tag.split('-', 1)[1] - except IndexError: pass - elif tag.split('-')[0].lower() == 'rev': - try: rev = tag.split('-', 1)[1] - except IndexError: pass + if tag.lower() in REGIONS_BY_SHORTCODE.keys(): + reg = REGIONS_BY_SHORTCODE[tag.lower()] + elif tag.lower() in REGIONS_NAME_KEYS: + reg = tag + elif "rev" in tag.lower(): + rev = tag.split(" ")[1] else: other_tags.append(tag) return reg, rev, other_tags def get_file_name_with_no_tags(file_name: str) -> str: - return re.sub('[\(\[].*?[\)\]]', '', file_name.split('.')[0]) + return re.sub("[\(\[].*?[\)\]]", "", file_name.split(".")[0]) def get_file_extension(rom: dict) -> str: - return rom['file_name'].split('.')[-1] if not rom['multi'] else '' + return rom["file_name"].split(".")[-1] if not rom["multi"] else "" diff --git a/frontend/.eslintignore b/frontend/.eslintignore new file mode 100644 index 000000000..1a58a1237 --- /dev/null +++ b/frontend/.eslintignore @@ -0,0 +1,15 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json new file mode 100644 index 000000000..2f5ad79b2 --- /dev/null +++ b/frontend/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "env": { + "node": true, + "browser": true + }, + "extends": [ + "eslint:recommended", + "plugin:vue/vue3-recommended" + ] +} diff --git a/frontend/package.json b/frontend/package.json index 73c767130..947bb4698 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,7 @@ "dev": "vite --host", "build": "vite build", "preview": "vite preview", - "lint": "eslint . --fix --ignore-path .gitignore" + "lint": "eslint . --fix" }, "dependencies": { "@mdi/font": "7.0.96", diff --git a/frontend/src/components/Notification.vue b/frontend/src/components/Notification.vue index 9ea53b56a..c6f740161 100644 --- a/frontend/src/components/Notification.vue +++ b/frontend/src/components/Notification.vue @@ -7,7 +7,7 @@ const snackbarStatus = ref({}) // Event listeners bus const emitter = inject('emitter') -emitter.on('snackbarScan', (snackbar) => { +emitter.on('snackbarShow', (snackbar) => { snackbarShow.value = true snackbarStatus.value = snackbar }) @@ -21,4 +21,4 @@ emitter.on('snackbarScan', (snackbar) => { - \ No newline at end of file + diff --git a/frontend/src/services/download.js b/frontend/src/services/download.js index 236d217f4..0450c4901 100644 --- a/frontend/src/services/download.js +++ b/frontend/src/services/download.js @@ -6,7 +6,7 @@ const downloading = storeDownloading() export async function downloadRom(rom, emitter, filesToDownload=[]) { downloading.add(rom.file_name) - emitter.emit('snackbarScan', {'msg': `Downloading ${rom.file_name}...`, 'icon': 'mdi-download', 'color': 'green'}) + emitter.emit('snackbarShow', {'msg': `Downloading ${rom.file_name}...`, 'icon': 'mdi-download', 'color': 'green'}) if(rom.multi){ const zip = new JSZip() var zipFilename = `${rom.file_name}.zip` @@ -33,4 +33,4 @@ export async function downloadRom(rom, emitter, filesToDownload=[]) { downloading.remove(rom.file_name) } -export async function downloadSave(rom) { console.log(`Downloading ${rom.file_name} save file`) } \ No newline at end of file +export async function downloadSave(rom) { console.log(`Downloading ${rom.file_name} save file`) } diff --git a/frontend/src/utils/socket.js b/frontend/src/utils/socket.js new file mode 100644 index 000000000..55c8df5d5 --- /dev/null +++ b/frontend/src/utils/socket.js @@ -0,0 +1,9 @@ +import { io } from "socket.io-client"; + +const socket = io({ + path: "/ws/socket.io/", + transports: ["websocket", "polling"], + autoConnect: false, +}); + +export default socket; diff --git a/frontend/src/views/Details.vue b/frontend/src/views/Details.vue index 82a67f43d..5a07405e4 100644 --- a/frontend/src/views/Details.vue +++ b/frontend/src/views/Details.vue @@ -59,10 +59,10 @@ async function updateRom(updatedData={...updatedRom.value}) { .then((response) => { rom.value = response.data.data updatedRom.value = {...response.data.data} - emitter.emit('snackbarScan', {'msg': response.data.msg, 'icon': 'mdi-check-bold', 'color': 'green'}) + emitter.emit('snackbarShow', {'msg': response.data.msg, 'icon': 'mdi-check-bold', 'color': 'green'}) emitter.emit('refreshGallery') }).catch((error) => { - emitter.emit('snackbarScan', {'msg': error.response.data.detail, 'icon': 'mdi-close-circle', 'color': 'red'}) + emitter.emit('snackbarShow', {'msg': error.response.data.detail, 'icon': 'mdi-close-circle', 'color': 'red'}) }) renameAsIGDB.value = false updating.value = false @@ -72,11 +72,11 @@ async function updateRom(updatedData={...updatedRom.value}) { async function deleteRom() { await deleteRomApi(rom.value.p_slug, deleteFromFs.value) .then((response) => { - emitter.emit('snackbarScan', {'msg': response.data.msg, 'icon': 'mdi-check-bold', 'color': 'green'}) + emitter.emit('snackbarShow', {'msg': response.data.msg, 'icon': 'mdi-check-bold', 'color': 'green'}) router.push(`/platform/${rom.value.p_slug}`) }).catch((error) => { console.log(error) - emitter.emit('snackbarScan', {'msg': error.response.data.detail, 'icon': 'mdi-close-circle', 'color': 'red'}) + emitter.emit('snackbarShow', {'msg': error.response.data.detail, 'icon': 'mdi-close-circle', 'color': 'red'}) if (error.response.status == 404) { router.push(`/platform/${rom.value.p_slug}`) } }) dialogDeleteRom.value = false diff --git a/frontend/src/views/Gallery.vue b/frontend/src/views/Gallery.vue index b5326a3fc..8ed92da14 100644 --- a/frontend/src/views/Gallery.vue +++ b/frontend/src/views/Gallery.vue @@ -1,142 +1,154 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - Feels cold here... mdi-emoticon-sad - - - - + + + Feels cold here... mdi-emoticon-sad + + - + diff --git a/frontend/src/views/library/Scan.vue b/frontend/src/views/library/Scan.vue index dbc82ecf2..876067aed 100644 --- a/frontend/src/views/library/Scan.vue +++ b/frontend/src/views/library/Scan.vue @@ -1,95 +1,94 @@ + + + - - - + + + - - - + + + Scan + + + - - - Scan - - - + - - - - - - {{ d['p_name'] }} - - {{ r }} - - - - \ No newline at end of file + + + + {{ d["p_name"] }} + + - {{ r }} + + +