diff --git a/plugin.json b/plugin.json index 14c4c1f..4b89ab9 100644 --- a/plugin.json +++ b/plugin.json @@ -4,7 +4,7 @@ "Name": "Steam Search", "Description": "Search and launch your Steam Game library", "Author": "Garulf", - "Version": "7.2.0", + "Version": "8.0.0", "Language": "executable", "Website": "https://github.com/Garulf/Steam-Search", "IcoPath": "run.exe", diff --git a/plugin/library.py b/plugin/library.py index a6a2b79..48a2177 100644 --- a/plugin/library.py +++ b/plugin/library.py @@ -23,6 +23,7 @@ def games(self): Return a list of games in this library. """ games = [] + image_dir = LibraryImageDir(Path(self.steam.path).joinpath('appcache', 'librarycache')) for appmanifest in Path(self.path).joinpath('steamapps').glob('appmanifest_*.acf'): try: manifest = VDF(appmanifest) @@ -45,22 +46,44 @@ def games(self): path=Path(self.path).joinpath( manifest['AppState']['installdir']), id=manifest['AppState']['appid'], - image_dir=Path(self.steam.path).joinpath( - 'appcache', 'librarycache'), + image_dir=image_dir, ) ) return games +class LibraryImageDir: + """ + Caches the filesystem access of a library image directory + """ + + def __init__(self, image_dir: Union[str, Path]): + image_dir = Path(image_dir) + self.grid = image_dir.name == 'grid' + self._files_cache = {} + self._iterdir = image_dir.iterdir() + + def get_image(self, id: str, type: str, sep='_') -> Path: + + prefix = f'{id}{sep}{type}' + if prefix in self._files_cache: + return self._files_cache[prefix] + else: + for file in self._iterdir: + haystack_prefix = file.name.split(".", 1)[0] + self._files_cache[haystack_prefix] = file + if prefix == haystack_prefix: + return file + return None class LibraryItem: """ Base class for all library items. """ - def __init__(self, name: str, path: Union[str, Path], image_dir: Union[str, Path], id: str = None): + def __init__(self, name: str, path: Union[str, Path], image_dir: LibraryImageDir, id: str = None): self.name = name self.path = Path(path) - self.image_dir = Path(image_dir) + self.image_dir = image_dir self._id = id self._image_id = self.id @@ -88,10 +111,10 @@ def launch(self) -> None: def get_image(self, type: str, sep='_') -> Path: id = self.id - if Path(self.image_dir).name == 'grid': - # Grid images use short ID format + if self.image_dir.grid: + # Grid images use the short ID id = self.short_id() - return next(Path(self.image_dir).glob(f'{id}{sep}{type}.*'), None) + return self.image_dir.get_image(id, type, sep) @cached_property def icon(self) -> Path: diff --git a/plugin/loginusers.py b/plugin/loginusers.py index d2bc673..0daef4b 100644 --- a/plugin/loginusers.py +++ b/plugin/loginusers.py @@ -5,7 +5,7 @@ from collections import UserList from .vdfs import VDF -from .library import LibraryItem +from .library import LibraryItem, LibraryImageDir if TYPE_CHECKING: from steam import Steam @@ -75,12 +75,13 @@ def shortcuts(self) -> list: split = _shortcuts.split(b'AppName\x00')[1:] if len(split) == 0: return _list + image_dir = LibraryImageDir(self.grid_path) for shortcut in _shortcuts.split(b'AppName\x00')[1:]: _list.append( LibraryItem( name=shortcut.split(b'\x00')[0].decode('utf-8'), path=shortcut.split(b'\x00')[2].decode('utf-8'), - image_dir=self.grid_path + image_dir=image_dir ) ) return _list