mirror of
https://github.com/rommapp/romm.git
synced 2026-02-19 07:50:57 +01:00
Merge pull request #2583 from rommapp/threaded-scan-fixes
Multi-threaded scan fixes
This commit is contained in:
@@ -12,10 +12,10 @@ class ScanStats(TypedDict):
|
||||
new_platforms: int
|
||||
identified_platforms: int
|
||||
scanned_roms: int
|
||||
added_roms: int
|
||||
new_roms: int
|
||||
identified_roms: int
|
||||
scanned_firmware: int
|
||||
added_firmware: int
|
||||
new_firmware: int
|
||||
|
||||
|
||||
class ScanTaskMeta(TypedDict):
|
||||
|
||||
@@ -56,17 +56,33 @@ class ScanStats:
|
||||
new_platforms: int = 0
|
||||
identified_platforms: int = 0
|
||||
scanned_roms: int = 0
|
||||
added_roms: int = 0
|
||||
new_roms: int = 0
|
||||
identified_roms: int = 0
|
||||
scanned_firmware: int = 0
|
||||
added_firmware: int = 0
|
||||
new_firmware: int = 0
|
||||
|
||||
def update(self, **kwargs):
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(self, key):
|
||||
setattr(self, key, value)
|
||||
def __post_init__(self):
|
||||
# Lock for thread-safe updates
|
||||
self._lock = asyncio.Lock()
|
||||
|
||||
update_job_meta({"scan_stats": self.to_dict()})
|
||||
async def update(self, socket_manager: socketio.AsyncRedisManager, **kwargs):
|
||||
async with self._lock:
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(self, key):
|
||||
setattr(self, key, value)
|
||||
|
||||
update_job_meta({"scan_stats": self.to_dict()})
|
||||
await socket_manager.emit("scan:update_stats", self.to_dict())
|
||||
|
||||
async def increment(self, socket_manager: socketio.AsyncRedisManager, **kwargs):
|
||||
async with self._lock:
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(self, key):
|
||||
current_value = getattr(self, key)
|
||||
setattr(self, key, current_value + value)
|
||||
|
||||
update_job_meta({"scan_stats": self.to_dict()})
|
||||
await socket_manager.emit("scan:update_stats", self.to_dict())
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
@@ -76,10 +92,10 @@ class ScanStats:
|
||||
"new_platforms": self.new_platforms,
|
||||
"identified_platforms": self.identified_platforms,
|
||||
"scanned_roms": self.scanned_roms,
|
||||
"added_roms": self.added_roms,
|
||||
"new_roms": self.new_roms,
|
||||
"identified_roms": self.identified_roms,
|
||||
"scanned_firmware": self.scanned_firmware,
|
||||
"added_firmware": self.added_firmware,
|
||||
"new_firmware": self.new_firmware,
|
||||
}
|
||||
|
||||
|
||||
@@ -92,10 +108,11 @@ async def _identify_firmware(
|
||||
platform: Platform,
|
||||
fs_fw: str,
|
||||
scan_stats: ScanStats,
|
||||
) -> ScanStats:
|
||||
socket_manager: socketio.AsyncRedisManager,
|
||||
) -> None:
|
||||
# Break early if the flag is set
|
||||
if redis_client.get(STOP_SCAN_FLAG):
|
||||
return scan_stats
|
||||
return
|
||||
|
||||
firmware = db_firmware_handler.get_firmware_by_filename(platform.id, fs_fw)
|
||||
|
||||
@@ -114,17 +131,16 @@ async def _identify_firmware(
|
||||
crc_hash=scanned_firmware.crc_hash,
|
||||
)
|
||||
|
||||
scan_stats.update(
|
||||
scanned_firmware=scan_stats.scanned_firmware + 1,
|
||||
added_firmware=scan_stats.added_firmware + (1 if not firmware else 0),
|
||||
await scan_stats.increment(
|
||||
socket_manager=socket_manager,
|
||||
scanned_firmware=1,
|
||||
new_firmware=1 if not firmware else 0,
|
||||
)
|
||||
|
||||
scanned_firmware.missing_from_fs = False
|
||||
scanned_firmware.is_verified = is_verified
|
||||
db_firmware_handler.add_firmware(scanned_firmware)
|
||||
|
||||
return scan_stats
|
||||
|
||||
|
||||
def _should_scan_rom(scan_type: ScanType, rom: Rom | None, roms_ids: list[int]) -> bool:
|
||||
"""Decide if a rom should be scanned or not
|
||||
@@ -166,10 +182,10 @@ async def _identify_rom(
|
||||
metadata_sources: list[str],
|
||||
socket_manager: socketio.AsyncRedisManager,
|
||||
scan_stats: ScanStats,
|
||||
) -> ScanStats:
|
||||
) -> None:
|
||||
# Break early if the flag is set
|
||||
if redis_client.get(STOP_SCAN_FLAG):
|
||||
return scan_stats
|
||||
return
|
||||
|
||||
if not _should_scan_rom(scan_type=scan_type, rom=rom, roms_ids=roms_ids):
|
||||
if rom:
|
||||
@@ -181,8 +197,7 @@ async def _identify_rom(
|
||||
if rom.missing_from_fs:
|
||||
db_rom_handler.update_rom(rom.id, {"missing_from_fs": False})
|
||||
|
||||
scan_stats.update(scanned_roms=scan_stats.scanned_roms + 1)
|
||||
return scan_stats
|
||||
return
|
||||
|
||||
# Update properties that don't require metadata
|
||||
fs_regions, fs_revisions, fs_languages, fs_other_tags = fs_rom_handler.parse_tags(
|
||||
@@ -218,7 +233,7 @@ async def _identify_rom(
|
||||
|
||||
# Silly checks to make the type checker happy
|
||||
if not rom:
|
||||
return scan_stats
|
||||
return
|
||||
|
||||
# Build rom files object before scanning
|
||||
log.debug(f"Calculating file hashes for {rom.fs_name}...")
|
||||
@@ -246,11 +261,11 @@ async def _identify_rom(
|
||||
socket_manager=socket_manager,
|
||||
)
|
||||
|
||||
scan_stats.update(
|
||||
scanned_roms=scan_stats.scanned_roms + 1,
|
||||
added_roms=scan_stats.added_roms + (1 if not rom else 0),
|
||||
identified_roms=scan_stats.identified_roms
|
||||
+ (1 if scanned_rom.is_identified else 0),
|
||||
await scan_stats.increment(
|
||||
socket_manager=socket_manager,
|
||||
scanned_roms=1,
|
||||
new_roms=1 if newly_added else 0,
|
||||
identified_roms=1 if scanned_rom.is_identified else 0,
|
||||
)
|
||||
|
||||
_added_rom = db_rom_handler.add_rom(scanned_rom)
|
||||
@@ -341,9 +356,6 @@ async def _identify_rom(
|
||||
exclude={"created_at", "updated_at", "rom_user"}
|
||||
),
|
||||
)
|
||||
await socket_manager.emit("", None)
|
||||
|
||||
return scan_stats
|
||||
|
||||
|
||||
async def _identify_platform(
|
||||
@@ -367,11 +379,11 @@ async def _identify_platform(
|
||||
if platform:
|
||||
scanned_platform.id = platform.id
|
||||
|
||||
scan_stats.update(
|
||||
scanned_platforms=scan_stats.scanned_platforms + 1,
|
||||
new_platforms=scan_stats.new_platforms + (1 if not platform else 0),
|
||||
identified_platforms=scan_stats.identified_platforms
|
||||
+ (1 if scanned_platform.is_identified else 0),
|
||||
await scan_stats.increment(
|
||||
socket_manager=socket_manager,
|
||||
scanned_platforms=1,
|
||||
new_platforms=1 if not platform else 0,
|
||||
identified_platforms=1 if scanned_platform.is_identified else 0,
|
||||
)
|
||||
|
||||
platform = db_platform_handler.add_platform(scanned_platform)
|
||||
@@ -382,7 +394,6 @@ async def _identify_platform(
|
||||
include={"id", "name", "display_name", "slug", "fs_slug", "is_identified"}
|
||||
),
|
||||
)
|
||||
await socket_manager.emit("", None)
|
||||
|
||||
# Scanning firmware
|
||||
try:
|
||||
@@ -398,7 +409,8 @@ async def _identify_platform(
|
||||
log.info(f"{hl(str(len(fs_firmware)))} firmware files found")
|
||||
|
||||
for fs_fw in fs_firmware:
|
||||
scan_stats = await _identify_firmware(
|
||||
await _identify_firmware(
|
||||
socket_manager=socket_manager,
|
||||
platform=platform,
|
||||
fs_fw=fs_fw,
|
||||
scan_stats=scan_stats,
|
||||
@@ -421,12 +433,10 @@ async def _identify_platform(
|
||||
# Create semaphore to limit concurrent ROM scanning
|
||||
scan_semaphore = asyncio.Semaphore(SCAN_WORKERS)
|
||||
|
||||
async def scan_rom_with_semaphore(fs_rom: FSRom, rom: Rom | None) -> dict[str, int]:
|
||||
"""Scan a single ROM with semaphore limiting and return stats delta"""
|
||||
async def scan_rom_with_semaphore(fs_rom: FSRom, rom: Rom | None) -> None:
|
||||
"""Scan a single ROM with semaphore limiting"""
|
||||
async with scan_semaphore:
|
||||
# Create a fresh stats object for this ROM to avoid race conditions
|
||||
rom_scan_stats = ScanStats()
|
||||
result_stats = await _identify_rom(
|
||||
await _identify_rom(
|
||||
platform=platform,
|
||||
fs_rom=fs_rom,
|
||||
rom=rom,
|
||||
@@ -434,15 +444,9 @@ async def _identify_platform(
|
||||
roms_ids=roms_ids,
|
||||
metadata_sources=metadata_sources,
|
||||
socket_manager=socket_manager,
|
||||
scan_stats=rom_scan_stats,
|
||||
scan_stats=scan_stats,
|
||||
)
|
||||
|
||||
return {
|
||||
"scanned_roms": result_stats.scanned_roms,
|
||||
"added_roms": result_stats.added_roms,
|
||||
"identified_roms": result_stats.identified_roms,
|
||||
}
|
||||
|
||||
for fs_roms_batch in batched(fs_roms, 200, strict=False):
|
||||
roms_by_fs_name = db_rom_handler.get_roms_by_fs_name(
|
||||
platform_id=platform.id,
|
||||
@@ -458,19 +462,10 @@ async def _identify_platform(
|
||||
]
|
||||
|
||||
# Wait for all ROMs in the batch to complete
|
||||
batch_results = await asyncio.gather(*scan_tasks, return_exceptions=True)
|
||||
|
||||
# Aggregate stats from all ROMs in the batch
|
||||
for result, fs_rom in zip(batch_results, fs_roms_batch, strict=False):
|
||||
if isinstance(result, BaseException):
|
||||
batched_results = await asyncio.gather(*scan_tasks, return_exceptions=True)
|
||||
for result, fs_rom in zip(batched_results, fs_roms_batch, strict=False):
|
||||
if isinstance(result, Exception):
|
||||
log.error(f"Error scanning ROM {fs_rom['fs_name']}: {result}")
|
||||
else:
|
||||
scan_stats.update(
|
||||
scanned_roms=scan_stats.scanned_roms + result["scanned_roms"],
|
||||
added_roms=scan_stats.added_roms + result["added_roms"],
|
||||
identified_roms=scan_stats.identified_roms
|
||||
+ result["identified_roms"],
|
||||
)
|
||||
|
||||
missing_roms = db_rom_handler.mark_missing_roms(
|
||||
platform.id, [rom["fs_name"] for rom in fs_roms]
|
||||
@@ -521,10 +516,15 @@ async def scan_platforms(
|
||||
return scan_stats
|
||||
|
||||
# Precalculate total platforms and ROMs
|
||||
scan_stats.update(total_platforms=len(fs_platforms))
|
||||
total_roms = 0
|
||||
for platform_slug in fs_platforms:
|
||||
fs_roms = await fs_rom_handler.get_roms(Platform(fs_slug=platform_slug))
|
||||
scan_stats.update(total_roms=scan_stats.total_roms + len(fs_roms))
|
||||
total_roms += len(fs_roms)
|
||||
await scan_stats.update(
|
||||
socket_manager=socket_manager,
|
||||
total_platforms=len(fs_platforms),
|
||||
total_roms=total_roms,
|
||||
)
|
||||
|
||||
async def stop_scan():
|
||||
log.info(f"{emoji.EMOJI_STOP_SIGN} Scan stopped manually")
|
||||
|
||||
@@ -14,7 +14,6 @@ from logger.logger import log
|
||||
from tasks.scheduled.update_switch_titledb import (
|
||||
SWITCH_PRODUCT_ID_KEY,
|
||||
SWITCH_TITLEDB_INDEX_KEY,
|
||||
update_switch_titledb_task,
|
||||
)
|
||||
|
||||
jarowinkler = JaroWinkler()
|
||||
@@ -190,12 +189,8 @@ class MetadataHandler(abc.ABC):
|
||||
title_id = match.group(1)
|
||||
|
||||
if not (await async_cache.exists(SWITCH_TITLEDB_INDEX_KEY)):
|
||||
log.warning("Fetching the Switch titleID index file...")
|
||||
await update_switch_titledb_task.run(force=True)
|
||||
|
||||
if not (await async_cache.exists(SWITCH_TITLEDB_INDEX_KEY)):
|
||||
log.error("Could not fetch the Switch titleID index file")
|
||||
return search_term, None
|
||||
log.error("Could not find the Switch titleID index file in cache")
|
||||
return search_term, None
|
||||
|
||||
index_entry = await async_cache.hget(SWITCH_TITLEDB_INDEX_KEY, title_id)
|
||||
if index_entry:
|
||||
@@ -215,12 +210,8 @@ class MetadataHandler(abc.ABC):
|
||||
product_id = "".join(product_id)
|
||||
|
||||
if not (await async_cache.exists(SWITCH_PRODUCT_ID_KEY)):
|
||||
log.warning("Fetching the Switch productID index file...")
|
||||
await update_switch_titledb_task.run(force=True)
|
||||
|
||||
if not (await async_cache.exists(SWITCH_PRODUCT_ID_KEY)):
|
||||
log.error("Could not fetch the Switch productID index file")
|
||||
return search_term, None
|
||||
log.error("Could not find the Switch productID index file in cache")
|
||||
return search_term, None
|
||||
|
||||
index_entry = await async_cache.hget(SWITCH_PRODUCT_ID_KEY, product_id)
|
||||
if index_entry:
|
||||
|
||||
@@ -142,17 +142,8 @@ class LaunchboxHandler(MetadataHandler):
|
||||
self, file_name: str, platform_slug: str
|
||||
) -> dict | None:
|
||||
if not (await async_cache.exists(LAUNCHBOX_METADATA_NAME_KEY)):
|
||||
log.info("Fetching the Launchbox Metadata.xml file...")
|
||||
|
||||
from tasks.scheduled.update_launchbox_metadata import (
|
||||
update_launchbox_metadata_task,
|
||||
)
|
||||
|
||||
await update_launchbox_metadata_task.run(force=True)
|
||||
|
||||
if not (await async_cache.exists(LAUNCHBOX_METADATA_NAME_KEY)):
|
||||
log.error("Could not fetch the Launchbox Metadata.xml file")
|
||||
return None
|
||||
log.error("Could not find the Launchbox Metadata.xml file in cache")
|
||||
return None
|
||||
|
||||
lb_platform = self.get_platform(platform_slug)
|
||||
platform_name = lb_platform.get("name", None)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
import socketio
|
||||
|
||||
from endpoints.sockets.scan import ScanStats, _should_scan_rom
|
||||
from handler.scan_handler import ScanType
|
||||
@@ -13,61 +14,62 @@ def test_scan_stats():
|
||||
assert stats.new_platforms == 0
|
||||
assert stats.identified_platforms == 0
|
||||
assert stats.scanned_roms == 0
|
||||
assert stats.added_roms == 0
|
||||
assert stats.new_roms == 0
|
||||
assert stats.identified_roms == 0
|
||||
assert stats.scanned_firmware == 0
|
||||
assert stats.added_firmware == 0
|
||||
assert stats.new_firmware == 0
|
||||
|
||||
stats.scanned_platforms += 1
|
||||
stats.new_platforms += 1
|
||||
stats.identified_platforms += 1
|
||||
stats.scanned_roms += 1
|
||||
stats.added_roms += 1
|
||||
stats.new_roms += 1
|
||||
stats.identified_roms += 1
|
||||
stats.scanned_firmware += 1
|
||||
stats.added_firmware += 1
|
||||
stats.new_firmware += 1
|
||||
|
||||
assert stats.scanned_platforms == 1
|
||||
assert stats.new_platforms == 1
|
||||
assert stats.identified_platforms == 1
|
||||
assert stats.scanned_roms == 1
|
||||
assert stats.added_roms == 1
|
||||
assert stats.new_roms == 1
|
||||
assert stats.identified_roms == 1
|
||||
assert stats.scanned_firmware == 1
|
||||
assert stats.added_firmware == 1
|
||||
assert stats.new_firmware == 1
|
||||
|
||||
|
||||
def test_merging_scan_stats():
|
||||
async def test_merging_scan_stats():
|
||||
stats = ScanStats(
|
||||
scanned_platforms=1,
|
||||
new_platforms=2,
|
||||
identified_platforms=3,
|
||||
scanned_roms=4,
|
||||
added_roms=5,
|
||||
new_roms=5,
|
||||
identified_roms=6,
|
||||
scanned_firmware=7,
|
||||
added_firmware=8,
|
||||
new_firmware=8,
|
||||
)
|
||||
|
||||
stats.update(
|
||||
await stats.update(
|
||||
socket_manager=Mock(spec=socketio.AsyncRedisManager),
|
||||
scanned_platforms=stats.scanned_platforms + 10,
|
||||
new_platforms=stats.new_platforms + 11,
|
||||
identified_platforms=stats.identified_platforms + 12,
|
||||
scanned_roms=stats.scanned_roms + 13,
|
||||
added_roms=stats.added_roms + 14,
|
||||
new_roms=stats.new_roms + 14,
|
||||
identified_roms=stats.identified_roms + 15,
|
||||
scanned_firmware=stats.scanned_firmware + 16,
|
||||
added_firmware=stats.added_firmware + 17,
|
||||
new_firmware=stats.new_firmware + 17,
|
||||
)
|
||||
|
||||
assert stats.scanned_platforms == 11
|
||||
assert stats.new_platforms == 13
|
||||
assert stats.identified_platforms == 15
|
||||
assert stats.scanned_roms == 17
|
||||
assert stats.added_roms == 19
|
||||
assert stats.new_roms == 19
|
||||
assert stats.identified_roms == 21
|
||||
assert stats.scanned_firmware == 23
|
||||
assert stats.added_firmware == 25
|
||||
assert stats.new_firmware == 25
|
||||
|
||||
|
||||
class TestShouldScanRom:
|
||||
|
||||
@@ -268,54 +268,6 @@ class TestMetadataHandlerMethods:
|
||||
assert index_entry is not None
|
||||
assert index_entry["publisher"] == "Nintendo"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_switch_titledb_format_cache_missing_fetch_success(
|
||||
self, handler: MetadataHandler
|
||||
):
|
||||
"""Test Switch TitleDB format when cache is missing but fetch succeeds."""
|
||||
with patch.object(
|
||||
async_cache, "exists", new_callable=AsyncMock
|
||||
) as mock_exists, patch.object(
|
||||
async_cache, "hget", new_callable=AsyncMock
|
||||
) as mock_hget, patch(
|
||||
"handler.metadata.base_handler.update_switch_titledb_task"
|
||||
) as mock_task:
|
||||
|
||||
# First call returns False (cache missing), second returns True (after fetch)
|
||||
mock_exists.side_effect = [False, True]
|
||||
mock_hget.return_value = json.dumps({"name": "Fetched Game"})
|
||||
mock_task.run = AsyncMock()
|
||||
|
||||
match = re.match(SWITCH_TITLEDB_REGEX, "70123456789012")
|
||||
assert match is not None
|
||||
result = await handler._switch_titledb_format(match, "original")
|
||||
|
||||
mock_task.run.assert_called_once_with(force=True)
|
||||
assert result[0] == "Fetched Game"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_switch_titledb_format_cache_missing_fetch_fails(
|
||||
self, handler: MetadataHandler
|
||||
):
|
||||
"""Test Switch TitleDB format when cache is missing and fetch fails."""
|
||||
with patch.object(
|
||||
async_cache, "exists", new_callable=AsyncMock
|
||||
) as mock_exists, patch(
|
||||
"handler.metadata.base_handler.update_switch_titledb_task"
|
||||
) as mock_task, patch(
|
||||
"handler.metadata.base_handler.log"
|
||||
) as mock_log:
|
||||
|
||||
mock_exists.return_value = False # Cache always missing
|
||||
mock_task.run = AsyncMock()
|
||||
|
||||
match = re.match(SWITCH_TITLEDB_REGEX, "70123456789012")
|
||||
assert match is not None
|
||||
result = await handler._switch_titledb_format(match, "original")
|
||||
|
||||
mock_log.error.assert_called()
|
||||
assert result == ("original", None)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_switch_titledb_format_not_found(self, handler: MetadataHandler):
|
||||
"""Test Switch TitleDB format when title ID not found."""
|
||||
|
||||
4
frontend/src/__generated__/models/ScanStats.ts
generated
4
frontend/src/__generated__/models/ScanStats.ts
generated
@@ -9,9 +9,9 @@ export type ScanStats = {
|
||||
new_platforms: number;
|
||||
identified_platforms: number;
|
||||
scanned_roms: number;
|
||||
added_roms: number;
|
||||
new_roms: number;
|
||||
identified_roms: number;
|
||||
scanned_firmware: number;
|
||||
added_firmware: number;
|
||||
new_firmware: number;
|
||||
};
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ async function updatePlatform() {
|
||||
}
|
||||
|
||||
async function scan() {
|
||||
scanningStore.set(true);
|
||||
scanningStore.setScanning(true);
|
||||
|
||||
if (!socket.connected) socket.connect();
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ function scrollToTop() {
|
||||
});
|
||||
}
|
||||
async function onScan() {
|
||||
scanningStore.set(true);
|
||||
scanningStore.setScanning(true);
|
||||
const romCount = romsStore.selectedRoms.length;
|
||||
emitter?.emit("snackbarShow", {
|
||||
msg: `Scanning ${romCount} game${romCount > 1 ? "s" : ""}...`,
|
||||
|
||||
@@ -13,10 +13,10 @@ const scanProgress = computed(() => {
|
||||
total_roms,
|
||||
scanned_platforms,
|
||||
scanned_roms,
|
||||
added_roms,
|
||||
new_roms,
|
||||
identified_roms,
|
||||
scanned_firmware,
|
||||
added_firmware,
|
||||
new_firmware,
|
||||
} = props.scanStats;
|
||||
|
||||
return {
|
||||
@@ -26,10 +26,10 @@ const scanProgress = computed(() => {
|
||||
),
|
||||
roms: `${scanned_roms}/${total_roms}`,
|
||||
romsPercentage: Math.round((scanned_roms / total_roms) * 100),
|
||||
addedRoms: added_roms,
|
||||
newRoms: new_roms,
|
||||
metadataRoms: identified_roms,
|
||||
scannedFirmware: scanned_firmware,
|
||||
addedFirmware: added_firmware,
|
||||
newFirmware: new_firmware,
|
||||
};
|
||||
});
|
||||
</script>
|
||||
@@ -92,7 +92,7 @@ const scanProgress = computed(() => {
|
||||
<v-icon icon="mdi-plus-circle" size="20" />
|
||||
</v-avatar>
|
||||
<div class="font-weight-bold">
|
||||
{{ scanProgress.addedRoms }}
|
||||
{{ scanProgress.newRoms }}
|
||||
</div>
|
||||
<div class="text-uppercase">Added</div>
|
||||
</div>
|
||||
|
||||
@@ -56,7 +56,7 @@ async function resetLastPlayed() {
|
||||
}
|
||||
|
||||
async function onScan() {
|
||||
scanningStore.set(true);
|
||||
scanningStore.setScanning(true);
|
||||
emitter?.emit("snackbarShow", {
|
||||
msg: `Refreshing ${props.rom.name} metadata...`,
|
||||
icon: "mdi-loading mdi-spin",
|
||||
|
||||
@@ -123,7 +123,7 @@ async function uploadRoms() {
|
||||
timeout: 3000,
|
||||
});
|
||||
|
||||
scanningStore.set(true);
|
||||
scanningStore.setScanning(true);
|
||||
|
||||
if (!socket.connected) socket.connect();
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Emitter } from "mitt";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { inject, onBeforeUnmount } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type { ScanStats } from "@/__generated__";
|
||||
import socket from "@/services/socket";
|
||||
import storeAuth from "@/stores/auth";
|
||||
import storeNavigation from "@/stores/navigation";
|
||||
@@ -49,7 +50,7 @@ socket.on(
|
||||
fs_slug: string;
|
||||
is_identified: boolean;
|
||||
}) => {
|
||||
scanningStore.set(true);
|
||||
scanningStore.setScanning(true);
|
||||
scanningPlatforms.value = scanningPlatforms.value.filter(
|
||||
(platform) => platform.display_name !== display_name,
|
||||
);
|
||||
@@ -65,7 +66,7 @@ socket.on(
|
||||
);
|
||||
|
||||
socket.on("scan:scanning_rom", (rom: SimpleRom) => {
|
||||
scanningStore.set(true);
|
||||
scanningStore.setScanning(true);
|
||||
|
||||
// Remove the ROM from the recent list and add it back to the top
|
||||
romsStore.removeFromRecent(rom);
|
||||
@@ -109,7 +110,7 @@ socket.on("scan:scanning_rom", (rom: SimpleRom) => {
|
||||
});
|
||||
|
||||
socket.on("scan:done", () => {
|
||||
scanningStore.set(false);
|
||||
scanningStore.setScanning(false);
|
||||
socket.disconnect();
|
||||
|
||||
emitter?.emit("refreshDrawer", null);
|
||||
@@ -122,7 +123,7 @@ socket.on("scan:done", () => {
|
||||
});
|
||||
|
||||
socket.on("scan:done_ko", (msg) => {
|
||||
scanningStore.set(false);
|
||||
scanningStore.setScanning(false);
|
||||
|
||||
emitter?.emit("snackbarShow", {
|
||||
msg: `Scan failed: ${msg}`,
|
||||
@@ -132,6 +133,10 @@ socket.on("scan:done_ko", (msg) => {
|
||||
socket.disconnect();
|
||||
});
|
||||
|
||||
socket.on("scan:update_stats", (stats: ScanStats) => {
|
||||
scanningStore.setScanStats(stats);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
socket.off("scan:scanning_platform");
|
||||
socket.off("scan:scanning_rom");
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Unvollständige Metadaten",
|
||||
"partial-metadata-desc": "Scanne Spiele mit unvollständigen Metadaten",
|
||||
"platforms-scanned-n": "Plattformen: {n} gescannte | Plattformen: {n} gescannt",
|
||||
"platforms-scanned-with-details": "Plattformen: {n_platforms} gescannt, darunter {n_new_platforms} neue und {n_identified_platforms} identifizierte",
|
||||
"platforms-scanned-with-details": "Plattformen: {n_scanned_platforms} gescannt aus {n_total_platforms}, darunter {n_new_platforms} neue und {n_identified_platforms} identifizierte",
|
||||
"quick-scan": "Schneller Scan",
|
||||
"quick-scan-desc": "Nur neue Dateien scannen",
|
||||
"roms-scanned-n": "Roms: {n} gescannte | Roms: {n} gescannt",
|
||||
"roms-scanned-with-details": "Roms: {n_roms} gescannt, dabei {n_added_roms} neue und {n_identified_roms} identifizierte",
|
||||
"roms-scanned-with-details": "Roms: {n_scanned_roms} gescannt aus {n_total_roms}, darunter {n_new_roms} neue und {n_identified_roms} identifizierte",
|
||||
"scan": "Scannen",
|
||||
"scan-options": "Scan-Optionen",
|
||||
"select-one-source": "Bitte wähle mindestens eine Metadatenquelle, wenn du die Bibliothek mit Cover-Artworks und Metadaten anreichern möchtest",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Partial metadata",
|
||||
"partial-metadata-desc": "Scan games with partial metadata matches",
|
||||
"platforms-scanned-n": "Platforms: {n} scanned",
|
||||
"platforms-scanned-with-details": "Platforms: {n_platforms} scanned, with {n_new_platforms} new and {n_identified_platforms} identified",
|
||||
"platforms-scanned-with-details": "Platforms: {n_scanned_platforms} scanned out of {n_total_platforms}, with {n_new_platforms} new and {n_identified_platforms} identified",
|
||||
"quick-scan": "Quick scan",
|
||||
"quick-scan-desc": "Scan new files only",
|
||||
"roms-scanned-n": "Roms: {n} scanned",
|
||||
"roms-scanned-with-details": "Roms: {n_roms} scanned, with {n_added_roms} new and {n_identified_roms} identified",
|
||||
"roms-scanned-with-details": "Roms: {n_scanned_roms} scanned out of {n_total_roms}, with {n_new_roms} new and {n_identified_roms} identified",
|
||||
"scan": "Scan",
|
||||
"scan-options": "Scan options",
|
||||
"select-one-source": "Please select at least one metadata source to enrich your library with artwork and metadata",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Partial metadata",
|
||||
"partial-metadata-desc": "Scan games with partial metadata matches",
|
||||
"platforms-scanned-n": "Platforms: {n} scanned",
|
||||
"platforms-scanned-with-details": "Platforms: {n_platforms} scanned, with {n_new_platforms} new and {n_identified_platforms} identified",
|
||||
"platforms-scanned-with-details": "Platforms: {n_scanned_platforms} scanned out of {n_total_platforms}, with {n_new_platforms} new and {n_identified_platforms} identified",
|
||||
"quick-scan": "Quick scan",
|
||||
"quick-scan-desc": "Scan new files only",
|
||||
"roms-scanned-n": "Roms: {n} scanned",
|
||||
"roms-scanned-with-details": "Roms: {n_roms} scanned, with {n_added_roms} new and {n_identified_roms} identified",
|
||||
"roms-scanned-with-details": "Roms: {n_scanned_roms} scanned out of {n_total_roms}, with {n_new_roms} new and {n_identified_roms} identified",
|
||||
"scan": "Scan",
|
||||
"scan-options": "Scan options",
|
||||
"select-one-source": "Please select at least one metadata source to enrich your library with artwork and metadata",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Metadatos parciales",
|
||||
"partial-metadata-desc": "Escanea únicamente juegos identificados con metadatos a medias",
|
||||
"platforms-scanned-n": "Plataformas: {n} escaneada | Plataformas: {n} escaneadas",
|
||||
"platforms-scanned-with-details": "Plataformas: {n_platforms} escaneadas, {n_new_platforms} nuevas y {n_identified_platforms} identificadas",
|
||||
"platforms-scanned-with-details": "Plataformas: {n_scanned_platforms} escaneadas de {n_total_platforms}, con {n_new_platforms} nuevas y {n_identified_platforms} identificadas",
|
||||
"quick-scan": "Escaneo rápido",
|
||||
"quick-scan-desc": "Escanea tu biblioteca en busca nuevos ficheros",
|
||||
"roms-scanned-n": "Roms: {n} escaneado | Roms: {n} escaneados",
|
||||
"roms-scanned-with-details": "Roms: {n_roms} escaneados, {n_added_roms} nuevos y {n_identified_roms} identificados",
|
||||
"roms-scanned-with-details": "Roms: {n_scanned_roms} escaneados de {n_total_roms}, con {n_new_roms} nuevos y {n_identified_roms} identificados",
|
||||
"scan": "Escanear",
|
||||
"scan-options": "Tipo de escaneo",
|
||||
"select-one-source": "Por favor, elige al menos una fuente de metadatos para enriquecer tu biblioteca con carátulas y metadatos",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Métadonnées partielles",
|
||||
"partial-metadata-desc": "Scanner uniquement les jeux identifiés avec des métadonnées partielles",
|
||||
"platforms-scanned-n": "Plateformes : {n} scannée | Plateformes : {n} scannées",
|
||||
"platforms-scanned-with-details": "Plateformes : {n_platforms} scannées, {n_new_platforms} nouvelles et {n_identified_platforms} identifiées",
|
||||
"platforms-scanned-with-details": "Plateformes : {n_scanned_platforms} scannées sur {n_total_platforms}, avec {n_new_platforms} nouvelles et {n_identified_platforms} identifiées",
|
||||
"quick-scan": "Scan rapide",
|
||||
"quick-scan-desc": "Scanner votre bibliothèque à la recherche de nouveaux fichiers",
|
||||
"roms-scanned-n": "Roms : {n} scannée | Roms : {n} scannées",
|
||||
"roms-scanned-with-details": "Roms : {n_roms} scannées, {n_added_roms} nouvelles et {n_identified_roms} identifiées",
|
||||
"roms-scanned-with-details": "Roms : {n_scanned_roms} scannées sur {n_total_roms}, avec {n_new_roms} nouvelles et {n_identified_roms} identifiées",
|
||||
"scan": "Scanner",
|
||||
"scan-options": "Type de scan",
|
||||
"select-one-source": "Veuillez choisir au moins une source de métadonnées pour enrichir votre bibliothèque avec des jaquettes et des métadonnées",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Metadati parziali",
|
||||
"partial-metadata-desc": "Scansiona i giochi con metadati parziali",
|
||||
"platforms-scanned-n": "Piattaforme: {n} scansionate",
|
||||
"platforms-scanned-with-details": "Piattaforme: {n_platforms} scansionate, con {n_new_platforms} nuove e {n_identified_platforms} identificate",
|
||||
"platforms-scanned-with-details": "Piattaforme: {n_scanned_platforms} scansionate su {n_total_platforms}, con {n_new_platforms} nuove e {n_identified_platforms} identificate",
|
||||
"quick-scan": "Scansione rapida",
|
||||
"quick-scan-desc": "Scansiona solo i nuovi file",
|
||||
"roms-scanned-n": "Rom: {n} scansionate",
|
||||
"roms-scanned-with-details": "Rom: {n_roms} scansionate, con {n_added_roms} nuove e {n_identified_roms} identificate",
|
||||
"roms-scanned-with-details": "Rom: {n_scanned_roms} scansionate su {n_total_roms}, con {n_new_roms} nuove e {n_identified_roms} identificate",
|
||||
"scan": "Scansiona",
|
||||
"scan-options": "Opzioni di scansione",
|
||||
"select-one-source": "Seleziona almeno una fonte di metadati per arricchire la tua libreria con artwork e metadati",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "部分的なメタデータ",
|
||||
"partial-metadata-desc": "メタデータが部分的に一致するゲームをスキャン",
|
||||
"platforms-scanned-n": "プラットフォーム: {n} スキャン済み",
|
||||
"platforms-scanned-with-details": "プラットフォーム: {n_platforms} スキャン済み 新規: {n_new_platforms} 識別済み: {n_identified_platforms}",
|
||||
"platforms-scanned-with-details": "プラットフォーム: {n_scanned_platforms}/{n_total_platforms} スキャン済み 新規: {n_new_platforms} 識別済み: {n_identified_platforms}",
|
||||
"quick-scan": "クイックスキャン",
|
||||
"quick-scan-desc": "新規ファイルのみを検索",
|
||||
"roms-scanned-n": "Rom: {n} スキャン済み",
|
||||
"roms-scanned-with-details": "Rom: {n_roms} スキャン済み 新規: {n_added_roms} 識別済み: {n_identified_roms}",
|
||||
"roms-scanned-with-details": "Rom: {n_scanned_roms}/{n_total_roms} スキャン済み 新規: {n_new_roms} 識別済み: {n_identified_roms}",
|
||||
"scan": "スキャン",
|
||||
"scan-options": "スキャンオプション",
|
||||
"select-one-source": "アートワークやメタデータを使用したい場合は少なくとも1つのソースを選択してください",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "일부 메타데이터",
|
||||
"partial-metadata-desc": "일부 메타데이터와 대응된 게임들 스캔",
|
||||
"platforms-scanned-n": "플랫폼: {n}개 스캔됨",
|
||||
"platforms-scanned-with-details": "플랫폼: {n_platforms}개 스캔됨, 새로운 플랫폼: {n_new_platforms}개, 확인된 플랫폼:{n_identified_platforms}개",
|
||||
"platforms-scanned-with-details": "플랫폼: {n_scanned_platforms}/{n_total_platforms}개 스캔됨, 새로운 플랫폼: {n_new_platforms}개, 확인된 플랫폼: {n_identified_platforms}개",
|
||||
"quick-scan": "빠른 스캔",
|
||||
"quick-scan-desc": "새 파일만 검색",
|
||||
"roms-scanned-n": "롬: {n}개 스캔됨",
|
||||
"roms-scanned-with-details": "롬: {n_roms}개 스캔됨, 새로운 롬: {n_added_roms}개, 확인된 롬: {n_identified_roms}개",
|
||||
"roms-scanned-with-details": "롬: {n_scanned_roms}/{n_total_roms}개 스캔됨, 새로운 롬: {n_new_roms}개, 확인된 롬: {n_identified_roms}개",
|
||||
"scan": "스캔",
|
||||
"scan-options": "스캔 옵션",
|
||||
"select-one-source": "표지와 메타데이터로 라이브러리를 꾸미고 싶으시면 메타데이터 DB를 하나 이상 선택해주세요",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Częściowe metadane",
|
||||
"partial-metadata-desc": "Skanuj gry z częściowym dopasowaniem metadanych",
|
||||
"platforms-scanned-n": "Platformy: zeskanowano {n}",
|
||||
"platforms-scanned-with-details": "Platformy: zeskanowano {n_platforms}, dodano {n_new_platforms} nowych i zidentyfikowano {n_identified_platforms}",
|
||||
"platforms-scanned-with-details": "Platformy: {n_scanned_platforms} zeskanowano z {n_total_platforms}, z {n_new_platforms} nowych i {n_identified_platforms} zidentyfikowanych",
|
||||
"quick-scan": "Szybkie skanowanie",
|
||||
"quick-scan-desc": "Skanuj tylko nowe pliki",
|
||||
"roms-scanned-n": "ROM-y: zeskanowano {n}",
|
||||
"roms-scanned-with-details": "ROM-y: zeskanowano {n_roms}, dodano {n_added_roms} nowych i zidentyfikowano {n_identified_roms}",
|
||||
"roms-scanned-with-details": "ROM-y: {n_scanned_roms} zeskanowano z {n_total_roms}, z {n_new_roms} nowych i {n_identified_roms} zidentyfikowanych",
|
||||
"scan": "Skanuj",
|
||||
"scan-options": "Opcje skanowania",
|
||||
"select-one-source": "Wybierz co najmniej jedno źródło metadanych, aby wzbogacić bibliotekę o grafiki i informacje",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Metadados parciais",
|
||||
"partial-metadata-desc": "Escanear jogos com correspondências parciais de metadados",
|
||||
"platforms-scanned-n": "Plataformas: {n} escaneada | Plataformas: {n} escaneadas",
|
||||
"platforms-scanned-with-details": "Plataformas: {n_platforms} escaneadas, com {n_new_platforms} novas e {n_identified_platforms} identificadas",
|
||||
"platforms-scanned-with-details": "Plataformas: {n_scanned_platforms} escaneadas de {n_total_platforms}, com {n_new_platforms} novas e {n_identified_platforms} identificadas",
|
||||
"quick-scan": "Escaneamento rápido",
|
||||
"quick-scan-desc": "Escanear apenas novos arquivos",
|
||||
"roms-scanned-n": "Roms: {n} escaneado | Roms: {n} escaneados",
|
||||
"roms-scanned-with-details": "Roms: {n_roms} escaneados, com {n_added_roms} novos e {n_identified_roms} identificados",
|
||||
"roms-scanned-with-details": "Roms: {n_scanned_roms} escaneados de {n_total_roms}, com {n_new_roms} novos e {n_identified_roms} identificados",
|
||||
"scan": "Escanear",
|
||||
"scan-options": "Opções de escaneamento",
|
||||
"select-one-source": "Por favor, selecione pelo menos uma fonte de metadados para enriquecer sua biblioteca com arte e metadados",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Metadate parțiale",
|
||||
"partial-metadata-desc": "Scanează doar jocurile identificate cu metadate incomplete",
|
||||
"platforms-scanned-n": "Platforme: {n} scanată | Platforme: {n} scanate",
|
||||
"platforms-scanned-with-details": "Platforme: {n_platforms} scanate, {n_new_platforms} noi și {n_identified_platforms} identificate",
|
||||
"platforms-scanned-with-details": "Platforme: {n_scanned_platforms} scanate din {n_total_platforms}, cu {n_new_platforms} noi și {n_identified_platforms} identificate",
|
||||
"quick-scan": "Scanare rapidă",
|
||||
"quick-scan-desc": "Scanează biblioteca pentru a găsi fișiere noi",
|
||||
"roms-scanned-n": "Roms: {n} scanată | Roms: {n} scanate",
|
||||
"roms-scanned-with-details": "Rom-uri: {n_roms} scanate, {n_added_roms} noi și {n_identified_roms} identificate",
|
||||
"roms-scanned-with-details": "Rom-uri: {n_scanned_roms} scanate din {n_total_roms}, cu {n_new_roms} noi și {n_identified_roms} identificate",
|
||||
"scan": "Scanează",
|
||||
"scan-options": "Tip de scanare",
|
||||
"select-one-source": "Vă rugăm să alegeți cel puțin o sursă de metadate pentru a îmbogăți biblioteca cu coperți și metadate",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "Частичные метаданные",
|
||||
"partial-metadata-desc": "Сканировать игры с частичными совпадениями метаданных",
|
||||
"platforms-scanned-n": "Платформы: {n} отсканировано",
|
||||
"platforms-scanned-with-details": "Платформы: {n_platforms} отсканировано, {n_new_platforms} новых и {n_identified_platforms} опознано",
|
||||
"platforms-scanned-with-details": "Платформы: {n_scanned_platforms} из {n_total_platforms} отсканировано, {n_new_platforms} новых и {n_identified_platforms} опознано",
|
||||
"quick-scan": "Быстрое сканирование",
|
||||
"quick-scan-desc": "Сканировать только новые файлы",
|
||||
"roms-scanned-n": "Ромы: {n} отсканировано",
|
||||
"roms-scanned-with-details": "Ромы: {n_roms} отсканировано, {n_added_roms} новых и {n_identified_roms} опознано",
|
||||
"roms-scanned-with-details": "Ромы: {n_scanned_roms} из {n_total_roms} отсканировано, {n_new_roms} новых и {n_identified_roms} опознано",
|
||||
"scan": "Сканировать",
|
||||
"scan-options": "Параметры сканирования",
|
||||
"select-one-source": "Пожалуйста, выберите хотя бы один источник метаданных, чтобы обогатить свою библиотеку иллюстрациями и метаданными",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "部分元数据",
|
||||
"partial-metadata-desc": "扫描部分元数据匹配的游戏",
|
||||
"platforms-scanned-n": "平台:{n} 已扫描",
|
||||
"platforms-scanned-with-details": "平台:{n_platforms} 已扫描,新增 {n_new_platforms},识别 {n_identified_platforms}",
|
||||
"platforms-scanned-with-details": "平台:{n_scanned_platforms}/{n_total_platforms} 已扫描,新增 {n_new_platforms},识别 {n_identified_platforms}",
|
||||
"quick-scan": "快速扫描",
|
||||
"quick-scan-desc": "仅扫描新文件",
|
||||
"roms-scanned-n": "Roms:{n} 已扫描",
|
||||
"roms-scanned-with-details": "Roms:{n_roms} 已扫描,新增 {n_added_roms},识别 {n_identified_roms}",
|
||||
"roms-scanned-with-details": "Roms:{n_scanned_roms}/{n_total_roms} 已扫描,新增 {n_new_roms},识别 {n_identified_roms}",
|
||||
"scan": "扫描",
|
||||
"scan-options": "扫描选项",
|
||||
"select-one-source": "请至少选择一个元数据源,以丰富您的游戏库",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"partial-metadata": "部分元數據",
|
||||
"partial-metadata-desc": "只掃描部分元數據匹配的遊戲",
|
||||
"platforms-scanned-n": "已掃描 {n} 個平台",
|
||||
"platforms-scanned-with-details": "平台:掃描 {n_platforms},新增 {n_new_platforms},識別 {n_identified_platforms}",
|
||||
"platforms-scanned-with-details": "平台:{n_scanned_platforms}/{n_total_platforms} 已掃描,新增 {n_new_platforms},識別 {n_identified_platforms}",
|
||||
"quick-scan": "快速掃描",
|
||||
"quick-scan-desc": "只掃描新檔案",
|
||||
"roms-scanned-n": "已掃描 {n} 個 Rom",
|
||||
"roms-scanned-with-details": "Rom:掃描 {n_roms},新增 {n_added_roms},識別 {n_identified_roms}",
|
||||
"roms-scanned-with-details": "Rom:{n_scanned_roms}/{n_total_roms} 已掃描,新增 {n_new_roms},識別 {n_identified_roms}",
|
||||
"scan": "掃描",
|
||||
"scan-options": "掃描選項",
|
||||
"select-one-source": "請至少選擇一個元數據來源,以豐富您的遊戲庫",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { defineStore } from "pinia";
|
||||
import type { ScanStats } from "@/__generated__";
|
||||
import type { SimpleRom } from "@/stores/roms";
|
||||
import type { Platform } from "./platforms";
|
||||
|
||||
@@ -10,30 +11,30 @@ export default defineStore("scanning", {
|
||||
state: () => ({
|
||||
scanning: false,
|
||||
scanningPlatforms: [] as ScanningPlatform[],
|
||||
scanStats: {
|
||||
scanned_platforms: 0,
|
||||
new_platforms: 0,
|
||||
identified_platforms: 0,
|
||||
scanned_roms: 0,
|
||||
added_roms: 0,
|
||||
identified_roms: 0,
|
||||
},
|
||||
scanStats: {} as ScanStats,
|
||||
}),
|
||||
|
||||
actions: {
|
||||
set(scanning: boolean) {
|
||||
setScanning(scanning: boolean) {
|
||||
this.scanning = scanning;
|
||||
},
|
||||
setScanStats(stats: ScanStats) {
|
||||
this.scanStats = stats;
|
||||
},
|
||||
reset() {
|
||||
this.scanning = false;
|
||||
this.scanningPlatforms = [] as ScanningPlatform[];
|
||||
this.scanStats = {
|
||||
total_platforms: 0,
|
||||
scanned_platforms: 0,
|
||||
new_platforms: 0,
|
||||
identified_platforms: 0,
|
||||
total_roms: 0,
|
||||
scanned_roms: 0,
|
||||
added_roms: 0,
|
||||
new_roms: 0,
|
||||
identified_roms: 0,
|
||||
scanned_firmware: 0,
|
||||
new_firmware: 0,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
@@ -95,7 +95,7 @@ const scanOptions = [
|
||||
const scanType = ref("quick");
|
||||
|
||||
async function scan() {
|
||||
scanningStore.set(true);
|
||||
scanningStore.setScanning(true);
|
||||
scanningPlatforms.value = [];
|
||||
|
||||
if (!socket.connected) socket.connect();
|
||||
@@ -317,13 +317,13 @@ async function stopScan() {
|
||||
</div>
|
||||
|
||||
<!-- Scan log -->
|
||||
<v-row ref="scan-log-ref" no-gutters class="scan-log overflow-y-scroll">
|
||||
<v-row
|
||||
ref="scan-log-ref"
|
||||
no-gutters
|
||||
class="scan-log overflow-y-scroll mb-4"
|
||||
>
|
||||
<v-col>
|
||||
<v-card
|
||||
elevation="0"
|
||||
class="bg-surface mx-auto mt-2 mb-14"
|
||||
max-width="800"
|
||||
>
|
||||
<v-card elevation="0" class="bg-surface mx-auto mt-2" max-width="800">
|
||||
<v-card-text class="pa-0">
|
||||
<v-expansion-panels
|
||||
ref="expansion-panels-ref"
|
||||
@@ -502,7 +502,7 @@ async function stopScan() {
|
||||
<!-- Scan stats -->
|
||||
<div
|
||||
v-if="scanningPlatforms.length > 0"
|
||||
class="text-caption position-fixed d-flex w-100 m-1 justify-center"
|
||||
class="text-caption position-sticky d-flex w-100 m-1 justify-center"
|
||||
style="bottom: 0.5rem"
|
||||
>
|
||||
<v-chip
|
||||
@@ -518,18 +518,21 @@ async function stopScan() {
|
||||
>
|
||||
<v-icon left> mdi-controller </v-icon>
|
||||
<span v-if="xs" class="ml-2">{{
|
||||
t("scan.platforms-scanned-n", scanningPlatforms.length)
|
||||
t("scan.platforms-scanned-n", scanStats.scanned_platforms)
|
||||
}}</span>
|
||||
<span v-else class="ml-2">{{
|
||||
t("scan.platforms-scanned-with-details", {
|
||||
n_platforms: scanningPlatforms.length,
|
||||
n_scanned_platforms: scanStats.scanned_platforms,
|
||||
n_total_platforms: scanStats.total_platforms,
|
||||
n_new_platforms: scanStats.new_platforms,
|
||||
n_identified_platforms: scanStats.identified_platforms,
|
||||
n_identified_platforms: Math.min(
|
||||
scanStats.identified_platforms,
|
||||
scanStats.scanned_platforms,
|
||||
),
|
||||
})
|
||||
}}</span>
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="scanningPlatforms.length > 0"
|
||||
color="primary"
|
||||
size="small"
|
||||
text-color="white"
|
||||
@@ -541,9 +544,13 @@ async function stopScan() {
|
||||
}}</span>
|
||||
<span v-else class="ml-2">{{
|
||||
t("scan.roms-scanned-with-details", {
|
||||
n_roms: scanStats.scanned_roms,
|
||||
n_added_roms: scanStats.added_roms,
|
||||
n_identified_roms: scanStats.identified_roms,
|
||||
n_scanned_roms: scanStats.scanned_roms,
|
||||
n_total_roms: scanStats.total_roms,
|
||||
n_new_roms: scanStats.new_roms,
|
||||
n_identified_roms: Math.min(
|
||||
scanStats.identified_roms,
|
||||
scanStats.scanned_roms,
|
||||
),
|
||||
})
|
||||
}}</span>
|
||||
</v-chip>
|
||||
|
||||
Reference in New Issue
Block a user