From ff2be8d58d55e299e3fa6208631121c834acd4bd Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sun, 23 Feb 2025 13:17:54 +0100 Subject: [PATCH] bundles/docker-immich: add album-auto-share script --- .../files/immich-auto-album-share.py | 80 +++++++++++++++++++ bundles/docker-immich/items.py | 3 + bundles/docker-immich/metadata.py | 28 +++++++ nodes/rottenraptor-server.toml | 3 + 4 files changed, 114 insertions(+) create mode 100644 bundles/docker-immich/files/immich-auto-album-share.py create mode 100644 bundles/docker-immich/items.py diff --git a/bundles/docker-immich/files/immich-auto-album-share.py b/bundles/docker-immich/files/immich-auto-album-share.py new file mode 100644 index 0000000..863f8b2 --- /dev/null +++ b/bundles/docker-immich/files/immich-auto-album-share.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +from json import loads +from os import environ +from subprocess import check_output +from sys import exit + +import psycopg2 + +PSQL_HOST = environ['DB_HOSTNAME'] +PSQL_USER = environ['DB_USERNAME'] +PSQL_PASS = environ['DB_PASSWORD'] +PSQL_DB = environ['DB_DATABASE_NAME'] + +docker_networks = loads(check_output(['docker', 'network', 'inspect', 'aaarghhh'])) + +container_ip = None +# why the fuck is this a list of networks, even though we have to provide +# a network name to inspect ... +for network in docker_networks: + if network['Name'] != 'aaarghhh': + continue + + for _, container in network['Containers'].items(): + if container['Name'] == PSQL_HOST: + container_ip = container['IPv4Address'].split('/')[0] + +if not container_ip: + print(f'could not find ip address for container {PSQL_HOST=} in json') + print(docker_networks) + exit(1) + +print(f'{PSQL_HOST=} {container_ip=}') + +conn = psycopg2.connect( + dbname=PSQL_DB, + host=container_ip, + password=PSQL_PASS, + user=PSQL_USER, +) + +with conn: + with conn.cursor() as cur: + cur.execute('SELECT "id","ownerId","albumName" FROM albums;') + albums = { + i[0]: { + 'owner': i[1], + 'name': i[2], + } + for i in cur.fetchall() + } + + with conn.cursor() as cur: + cur.execute('SELECT "id","name" FROM users;') + users = { + i[0]: i[1] + for i in cur.fetchall() + } + +for album_id, album in albums.items(): + print(f'----- working on album: {album["name"]}') + with conn: + with conn.cursor() as cur: + cur.execute('SELECT "usersId" FROM albums_shared_users_users WHERE "albumsId" = %s;', (album_id,)) + album_shares = [i[0] for i in cur.fetchall()] + print(f' album is shared with {len(album_shares)} users: {album_shares}') + for user_id, user_name in users.items(): + if user_id == album['owner'] or user_id in album_shares: + continue + + print(f' sharing album with user {user_name} ... ', end='') + with conn.cursor() as cur: + cur.execute( + 'INSERT INTO albums_shared_users_users ("albumsId","usersId","role") VALUES (%s, %s, %s);', + (album_id, user_id, 'viewer'), + ) + print('done') + print() + +conn.close() diff --git a/bundles/docker-immich/items.py b/bundles/docker-immich/items.py new file mode 100644 index 0000000..8c9d54e --- /dev/null +++ b/bundles/docker-immich/items.py @@ -0,0 +1,3 @@ +files['/usr/local/bin/immich-auto-album-share.py'] = { + 'mode': '0755', +} diff --git a/bundles/docker-immich/metadata.py b/bundles/docker-immich/metadata.py index 5b73f70..288b7f1 100644 --- a/bundles/docker-immich/metadata.py +++ b/bundles/docker-immich/metadata.py @@ -1,6 +1,11 @@ assert node.has_bundle('docker-engine') defaults = { + 'apt': { + 'packages': { + 'python3-psycopg2': {}, + }, + }, 'docker-engine': { 'containers': { 'immich': { @@ -45,6 +50,9 @@ defaults = { }, }, }, + 'docker-immich': { + 'enable_auto_album_share': False, + }, 'nginx': { 'vhosts': { 'immich': { @@ -59,3 +67,23 @@ defaults = { }, }, } + + +@metadata_reactor.provides( + 'systemd-timers/timers/immich-auto-album-share', +) +def auto_album_share(metadata): + if not metadata.get('docker-immich/enable_auto_album_share'): + return {} + + return { + 'systemd-timers': { + 'timers': { + 'immich-auto-album-share': { + 'command': '/usr/local/bin/immich-auto-album-share.py', + 'environment': metadata.get('docker-engine/containers/immich/environment'), + 'when': 'minutely', + }, + }, + }, + } diff --git a/nodes/rottenraptor-server.toml b/nodes/rottenraptor-server.toml index 96eb5fb..2ab03f8 100644 --- a/nodes/rottenraptor-server.toml +++ b/nodes/rottenraptor-server.toml @@ -13,6 +13,9 @@ bundles = [ "zfs", ] +[metadata.docker-immich] +enable_auto_album_share = true + [metadata.icinga_options] period = "daytime"