Files
romm/backend/handler/filesystem/platforms_handler.py
Michael Manganiello f20a9ffe34 fix: Avoid recursive os.walk calls
`os.walk` is a generator that can iteratively navigate from the
specified path, top-bottom. However, most of the calls to `os.walk` in
the project cast the call to `list()`, which makes it traverse the path
and recursively find all nested directories.

This is commonly not needed, as we end up just using a `[0]` index to
only access the root path.

This change adds a few utils that simplifies listing files/directories,
and by default does it non-recursively. Performance gains shouldn't be
noticeable in systems with high-speed storage, but we can avoid the edge
cases of users having too many nested directories, by avoiding unneeded
I/O.
2024-07-13 15:30:04 -03:00

59 lines
1.8 KiB
Python

import os
from pathlib import Path
from config import LIBRARY_BASE_PATH
from config.config_manager import Config
from config.config_manager import config_manager as cm
from exceptions.fs_exceptions import (
FolderStructureNotMatchException,
PlatformAlreadyExistsException,
)
from utils.filesystem import iter_directories
from .base_handler import FSHandler
class FSPlatformsHandler(FSHandler):
def __init__(self) -> None:
pass
def _exclude_platforms(self, config: Config, platforms: list):
return [
platform
for platform in platforms
if platform not in config.EXCLUDED_PLATFORMS
]
def add_platforms(self, fs_slug: str) -> None:
cnfg = cm.get_config()
try:
(
os.mkdir(f"{cnfg.HIGH_PRIO_STRUCTURE_PATH}/{fs_slug}")
if os.path.exists(cnfg.HIGH_PRIO_STRUCTURE_PATH)
else Path(os.path.join(LIBRARY_BASE_PATH, fs_slug, "roms")).mkdir(
parents=True
)
)
except FileExistsError as exc:
raise PlatformAlreadyExistsException(fs_slug) from exc
def get_platforms(self) -> list[str]:
"""Gets all filesystem platforms
Returns list with all the filesystem platforms found in the LIBRARY_BASE_PATH.
Automatically exclude folders defined in user config.
"""
cnfg = cm.get_config()
platforms_dir = (
cnfg.HIGH_PRIO_STRUCTURE_PATH
if os.path.exists(cnfg.HIGH_PRIO_STRUCTURE_PATH)
else LIBRARY_BASE_PATH
)
try:
platforms = [d for _, d in iter_directories(platforms_dir)]
return self._exclude_platforms(cnfg, platforms)
except IndexError as exc:
raise FolderStructureNotMatchException from exc