From ce64f1a42c9570efa75cc2f568e59d683f499bdd Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Fri, 20 Jun 2025 22:32:28 -0500 Subject: config update and more endpoints for api fromtend --- flaskapi.py | 27 ++++++++++++++++++++++----- immich.py | 7 +++++++ lazycachelist.py | 2 ++ manager.py | 19 +++++++++++++++---- settings.py | 16 +++++----------- todo | 2 ++ 6 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 todo diff --git a/flaskapi.py b/flaskapi.py index beabea0..a539dc5 100644 --- a/flaskapi.py +++ b/flaskapi.py @@ -30,16 +30,33 @@ def seek(increment): return { "imageIndex": display.current_texture_index } +@api.route("/albums/update", methods=["POST"]) +def albums_update(): + return { "success": PixMan().update_config(album_list=request.json) } + @api.route("/albums") -def get_albums(): +def albums_get(): if not (ic := PixMan().immich_connector): return {} keys = [ "albumName", "albumThumbnailAssetId", "id", "startDate", "endDate", "assetCount", "shared", ] + selected_albums = PixMan().config.album_list return [{ - key: album[key] for key in keys - } for album in ic.load_all_albums() ] + key: album.get(key, None) for key in keys + } | { "selected": album in selected_albums } for album in ic.load_all_albums() if album["assetCount"] ] + + +@api.route("/asset//filename") +def get_asset_name(key): + if not (ic := PixMan().immich_connector): + return {} + # TODO ensure getting actual album thumb + name = ic.load_image_filename(key) + if name is None: + abort(400) + return { "filename": name } +@api.route("/asset//fullsize", defaults={ "size": "fullsize" }) @api.route("/asset//thumbnail", defaults={ "size": "thumbnail" }) @api.route("/asset/", defaults={ "size": "preview" }) def get_asset(key, size): @@ -61,10 +78,10 @@ def immich_redirect(path): @api.route("/config/update", methods=["POST"]) def config_update(): - return { "success": PixMan().update_config(Config(**request.json)) } + return { "success": PixMan().update_config(**request.json) } @api.route("/config") -def config(): +def config_get(): return jsonify(PixMan().config) diff --git a/immich.py b/immich.py index ad39942..0f319c5 100644 --- a/immich.py +++ b/immich.py @@ -40,6 +40,13 @@ class ImmichConnector: mimetype = response.headers.get("Content-Type") return image_data, mimetype + def load_image_filename(self, key): + response = self._request(f"assets/{key}") + if not response or response.status_code != 200: return None, None + + data = response.json() + return data["originalFileName"] + def load_texture_async(self, texture_list, image_texture): self.texture_load_queue.put((texture_list, image_texture)) diff --git a/lazycachelist.py b/lazycachelist.py index 3b2744d..5243def 100644 --- a/lazycachelist.py +++ b/lazycachelist.py @@ -20,6 +20,7 @@ class CallbackStateData: asset_index: int movement: int assets: list[str] + current_asset: str @classmethod def from_lctl(cls, l): @@ -31,6 +32,7 @@ class CallbackStateData: asset_index=l.asset_index, movement=l.last_movement, assets=assets, + current_asset=assets[5], ) diff --git a/manager.py b/manager.py index b2e101f..27ebab3 100644 --- a/manager.py +++ b/manager.py @@ -52,7 +52,7 @@ class PixMan: config = Config.load(self.configfile) if os.path.exists(self.configfile) else Config() self.init_web(host, port) - self.update_config(config) + self.replace_config(config) def init_web(self, host, port): self.t_flask = Thread(target=self.app.run, kwargs={ "host": host, "port": port }) @@ -78,16 +78,27 @@ class PixMan: self.display = PixDisplay(self.texture_list) self.display.main({}) # TODO glut args - def update_config(self, config): + def replace_config(self, config): #old_config = self.config self.config = config # Initialize window if immich parameters are valid - if config.immich_url and config.immich_api_key and not self.display: + if self.config.immich_url and self.config.immich_api_key and not self.display: self.init_window() # If all goes well - config.save(self.configfile) + self.config.save(self.configfile) + return True + + def update_config(self, **config): + self.config.update(**config) + + # Initialize window if immich parameters are valid + if self.config.immich_url and self.config.immich_api_key and not self.display: + self.init_window() + + # If all goes well + self.config.save(self.configfile) return True diff --git a/settings.py b/settings.py index f11e930..e6b3df8 100644 --- a/settings.py +++ b/settings.py @@ -2,12 +2,6 @@ from dataclasses import dataclass, asdict, field import json -@dataclass -class AlbumList: - name: str - album_keys: list[str] - - @dataclass class Config: # Immich server @@ -22,11 +16,7 @@ class Config: # Cache max_cache_assets: int = 100 # Albums data - album_lists: list[AlbumList] = field(default_factory=list) - album_list_selected: int = None - - def __post_init__(self): - self.album_lists = [ AlbumList(*a) for a in self.album_lists ] + album_list: list[str] = field(default_factory=list) def __dict__(self): return asdict(self) @@ -39,3 +29,7 @@ class Config: def save(self, filepath): with open(filepath, "w") as fp: json.dump(asdict(self), fp, indent=2) + + def update(self, **config): + for key, value in config.items(): + setattr(self, key, value) diff --git a/todo b/todo new file mode 100644 index 0000000..0970123 --- /dev/null +++ b/todo @@ -0,0 +1,2 @@ +push current images data on new socket connection opening up +decrease size of assets in memory -- cgit v1.2.3