From 579c8ea37a04e77f2d7a3a48fd12149d0d8f6d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Wed, 25 Jun 2025 15:16:36 +0200 Subject: [PATCH 01/33] Home Gen27 @ 2025-06-25-15:16 by jroeger@T14-OE130-7-ubuntu --- home/jroeger.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/home/jroeger.nix b/home/jroeger.nix index 86cd977..c6d7085 100644 --- a/home/jroeger.nix +++ b/home/jroeger.nix @@ -16,10 +16,6 @@ hive.doom.withNixPkgs = true; hive.doom.withShellPkgs = true; hive.doom.withCXXPkgs = true; - hive.programs.creative = { - enable = true; - video-editing-light = true; - }; # This value determines the Home Manager release that your configuration is # compatible with. This helps avoid breakage when a new Home Manager release From b7f19ae61a3202e55de0c7325bba0b4cf23e84e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Wed, 25 Jun 2025 15:24:06 +0200 Subject: [PATCH 02/33] Home Gen28 @ 2025-06-25-15:23 by jroeger@T14-OE130-7-ubuntu --- modules/home/doom/static/config.el | 2 ++ modules/home/doom/static/packages.el | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/modules/home/doom/static/config.el b/modules/home/doom/static/config.el index 9043ec9..1746110 100644 --- a/modules/home/doom/static/config.el +++ b/modules/home/doom/static/config.el @@ -244,6 +244,8 @@ (bash-ts-mode . lsp-deferred) (json-ts-mode . lsp-deferred))) +(setq auto-mode-alist (cons '("\\.smt$" . smtlib-mode) auto-mode-alist)) +(autoload 'smtlib-mode "smtlib" "Major mode for SMTLIB" t) (let ((config-dir (expand-file-name "config.d" doom-user-dir))) (when (file-directory-p config-dir) diff --git a/modules/home/doom/static/packages.el b/modules/home/doom/static/packages.el index e08b8f4..a2d21e1 100644 --- a/modules/home/doom/static/packages.el +++ b/modules/home/doom/static/packages.el @@ -62,6 +62,13 @@ :local-repo "ws-butler") :pin "9ee5a7657a22e836618813c2e2b64a548d27d2ff") +(package! smtlib-mode + :recipe (:host github + :repo "chsticksel/smtlib-mode" + :branch "master" + :local-repo "smtlib-mode") + :pin "ed387e63b64091228e6a8a429b02b8fba165f5b5") + (package! direnv) (package! pdf-tools) (package! eww) From a344a09c531add0f540b9e3bf3bee5c2e743786a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Wed, 2 Jul 2025 14:10:09 +0200 Subject: [PATCH 03/33] Home Gen30 @ 2025-07-02-14:10 by jroeger@T14-OE130-7-ubuntu --- modules/home/doom/static/config.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/home/doom/static/config.el b/modules/home/doom/static/config.el index 1746110..fec267a 100644 --- a/modules/home/doom/static/config.el +++ b/modules/home/doom/static/config.el @@ -140,6 +140,9 @@ (setq ccls-initialization-options '(:index (:comments 2) :completion (:detailedLabel t) :compilationDatabaseDirectory "build" :cache (:directory ".cache/ccls" :format "binary"))) (set-lsp-priority! 'ccls 1)) + +(setq apheleia-formatters-respect-indent-level nil) + (defun my-ui-doc-glance-then-focus () "Glances UI-Doc if not present, otherwise focus" (interactive) From b4b209eacabbaa034e0c027958f8fd4a46bf5492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Fri, 18 Jul 2025 21:24:28 +0200 Subject: [PATCH 04/33] System Gen82 @ 2025-07-18-21:24:27 by jonas@monolith --- modules/programs/creative.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/programs/creative.nix b/modules/programs/creative.nix index 033f7ba..363ee22 100644 --- a/modules/programs/creative.nix +++ b/modules/programs/creative.nix @@ -49,7 +49,12 @@ in { environment.systemPackages = with pkgs; lib.optionals cfg.image-editing [gimp krita drawio] ++ lib.optional cfg.image-management digikam - ++ lib.optionals cfg.image-raw-processing [darktable hdrmerge] + ++ lib.optionals cfg.image-raw-processing [ + darktable + enblend-enfuse + hdrmerge + hugin + ] ++ lib.optionals cfg.video-editing-light [ffmpeg losslesscut-bin] ++ lib.optionals cfg.video-editing-heavy [ davinci-resolve From 234a70cd7848328fe74caaf57f2e1bdbac7b3e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 20 Jul 2025 16:14:13 +0200 Subject: [PATCH 05/33] System Gen83 @ 2025-07-20-16:14:12 by jonas@monolith --- hosts/monolith/configuration.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index a9897d9..546c3ba 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -114,6 +114,9 @@ services.udev.packages = [pkgs.openhantek6022]; virtualisation.docker.enable = true; + # Corsair drivers + hardware.ckb-next.enable = true; + # dpi correction services.xserver.dpi = 91; environment.variables = { From b31e767134bb9039404e2b68e5d090bee5a1efa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Thu, 24 Jul 2025 02:00:40 +0200 Subject: [PATCH 06/33] System Gen84 @ 2025-07-24-02:00:39 by jonas@monolith --- flake.nix | 1 + hosts/monolith/configuration.nix | 14 +++++- modules/default.nix | 1 + modules/programs/spotify-shortcuts.nix | 28 +++++++++++ pkgs/default.nix | 1 + pkgs/spotify-shortcuts/.envrc | 1 + pkgs/spotify-shortcuts/default.nix | 2 + pkgs/spotify-shortcuts/derivation.nix | 7 +++ pkgs/spotify-shortcuts/setup.py | 14 ++++++ pkgs/spotify-shortcuts/shell.nix | 8 +++ .../spotify_shortcuts/__init__.py | 0 .../spotify_shortcuts/config.py | 50 +++++++++++++++++++ .../spotify_shortcuts/spotify_auth.py | 18 +++++++ .../spotify_shortcuts/spotify_like.py | 21 ++++++++ secrets/spotify-shortcuts.yaml | 44 ++++++++++++++++ 15 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 modules/programs/spotify-shortcuts.nix create mode 100644 pkgs/spotify-shortcuts/.envrc create mode 100644 pkgs/spotify-shortcuts/default.nix create mode 100644 pkgs/spotify-shortcuts/derivation.nix create mode 100644 pkgs/spotify-shortcuts/setup.py create mode 100644 pkgs/spotify-shortcuts/shell.nix create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/__init__.py create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/config.py create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py create mode 100644 secrets/spotify-shortcuts.yaml diff --git a/flake.nix b/flake.nix index 064d4b0..9580c2d 100644 --- a/flake.nix +++ b/flake.nix @@ -209,6 +209,7 @@ devShells.${system} = { transcode-davinci-resolve = (import ./pkgs/transcode-davinci-resolve/shell.nix) {pkgs = nixpkgs.legacyPackages.${system};}; + spotify-shortcuts = (import ./pkgs/spotify-shortcuts/shell.nix) {pkgs = nixpkgs.legacyPackages.${system};}; }; overlays.default = import ./pkgs; diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index 546c3ba..e973118 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -3,7 +3,6 @@ # and in the NixOS manual (accessible by running ‘nixos-help’). { config, - inputs, pkgs, ... }: { @@ -18,6 +17,14 @@ sopsFile = ../../secrets/monolith/wg.yaml; key = "privateKey"; }; + sops.secrets.spotify-shortcuts-clientId = { + sopsFile = ../../secrets/spotify-shortcuts.yaml; + key = "clientId"; + }; + sops.secrets.spotify-shortcuts-clientSecret = { + sopsFile = ../../secrets/spotify-shortcuts.yaml; + key = "clientSecret"; + }; # Users users.users.jonas = { @@ -70,6 +77,11 @@ video-editing-light = true; video-editing-heavy = true; }; + hive.programs.spotify-shortcuts = { + enable = true; + clientIdFile = config.sops.secrets.spotify-shortcuts-clientId.path; + clientSecretFile = config.sops.secrets.spotify-shortcuts-clientSecret.path; + }; # system packages environment.systemPackages = with pkgs; [ diff --git a/modules/default.nix b/modules/default.nix index 9ea1834..6604626 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -24,6 +24,7 @@ ./networking/wireguard ./programs/creative.nix ./programs/games.nix + ./programs/spotify-shortcuts.nix ./services/borg-server.nix ./services/kdeconnect.nix ./services/nextcloud-instance.nix diff --git a/modules/programs/spotify-shortcuts.nix b/modules/programs/spotify-shortcuts.nix new file mode 100644 index 0000000..30fe4ef --- /dev/null +++ b/modules/programs/spotify-shortcuts.nix @@ -0,0 +1,28 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.hive.programs.spotify-shortcuts; +in { + options.hive.programs.spotify-shortcuts = { + enable = lib.mkEnableOption "Enable Spotify Shortcuts"; + clientIdFile = lib.mkOption { + type = lib.types.path; + description = "Spotify API Client ID Path"; + }; + clientSecretFile = lib.mkOption { + type = lib.types.path; + description = "Spotify API Client Secret Path"; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [pkgs.hive.spotify-shortcuts]; + environment.etc."profile.d/spotify-shortcuts.sh".text = '' + export SPOTIFY_SHORTCUTS_CLIENT_ID=$(cat ${cfg.clientIdFile}) + export SPOTIFY_SHORTCUTS_CLIENT_SECRET=$(cat ${cfg.clientSecretFile}) + ''; + }; +} diff --git a/pkgs/default.nix b/pkgs/default.nix index 1b17d63..3c24567 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -2,5 +2,6 @@ final: _: { hive = { crossover = final.callPackage ./crossover.nix {}; transcode-davinci-resolve = final.callPackage ./transcode-davinci-resolve {}; + spotify-shortcuts = final.callPackage ./spotify-shortcuts {}; }; } diff --git a/pkgs/spotify-shortcuts/.envrc b/pkgs/spotify-shortcuts/.envrc new file mode 100644 index 0000000..110dc74 --- /dev/null +++ b/pkgs/spotify-shortcuts/.envrc @@ -0,0 +1 @@ +use flake ../../#spotify-shortcuts --show-trace diff --git a/pkgs/spotify-shortcuts/default.nix b/pkgs/spotify-shortcuts/default.nix new file mode 100644 index 0000000..dfb7691 --- /dev/null +++ b/pkgs/spotify-shortcuts/default.nix @@ -0,0 +1,2 @@ +{pkgs ? import {}}: +pkgs.callPackage ./derivation.nix {} diff --git a/pkgs/spotify-shortcuts/derivation.nix b/pkgs/spotify-shortcuts/derivation.nix new file mode 100644 index 0000000..f4cb8a5 --- /dev/null +++ b/pkgs/spotify-shortcuts/derivation.nix @@ -0,0 +1,7 @@ +{python3Packages}: +with python3Packages; + buildPythonApplication { + name = "spotify-shortcuts"; + propagatedBuildInputs = [spotipy pyxdg]; + src = ./.; + } diff --git a/pkgs/spotify-shortcuts/setup.py b/pkgs/spotify-shortcuts/setup.py new file mode 100644 index 0000000..9a280e0 --- /dev/null +++ b/pkgs/spotify-shortcuts/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from setuptools import setup, find_packages + +setup( + name="spotify_shortcuts", + version="1.0", + packages=find_packages(), + entry_points={ + "console_scripts": [ + "spotify-like=spotify_shortcuts.spotify_like:main", + ], + }, +) diff --git a/pkgs/spotify-shortcuts/shell.nix b/pkgs/spotify-shortcuts/shell.nix new file mode 100644 index 0000000..c41f7d0 --- /dev/null +++ b/pkgs/spotify-shortcuts/shell.nix @@ -0,0 +1,8 @@ +{pkgs ? import {}}: +pkgs.mkShell { + packages = [ + pkgs.pyright + pkgs.black + ]; + inputsFrom = [(pkgs.callPackage ./derivation.nix {})]; +} diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/__init__.py b/pkgs/spotify-shortcuts/spotify_shortcuts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/config.py b/pkgs/spotify-shortcuts/spotify_shortcuts/config.py new file mode 100644 index 0000000..dbaeb31 --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/config.py @@ -0,0 +1,50 @@ +from pathlib import Path +from dataclasses import dataclass +from argparse import ArgumentParser +from typing import List +from os import getenv +from sys import argv +from xdg.BaseDirectory import xdg_cache_home + + +@dataclass +class Config: + cache_file: Path = Path(xdg_cache_home) / Path("spotify-shortcuts.json") + client_id: str | None = None + client_secret: str | None = None + + +def load_config(args: List[str] = argv[1:]) -> Config: + parser = ArgumentParser(description="Spotify CLI Tool") + parser.add_argument( + "--cache-file", + type=Path, + default=Config.cache_file, + help="Path to the cache file for Spotify authentication", + ) + parser.add_argument( + "--client-id", + type=str, + default=Config.client_id, + help="Spotify API Client ID", + ) + parser.add_argument( + "--client-secret", + type=str, + default=Config.client_secret, + help="Spotify API Client Secret", + ) + + ns = parser.parse_args(args) + + cfg = Config( + cache_file=ns.cache_file, + client_id=ns.client_id, + client_secret=ns.client_secret, + ) + + return Config( + cache_file=Path(getenv("SPOTIFY_SHORTCUTS_CACHE_FILE", cfg.cache_file)), + client_id=getenv("SPOTIFY_SHORTCUTS_CLIENT_ID", cfg.client_id), + client_secret=getenv("SPOTIFY_SHORTCUTS_CLIENT_SECRET", cfg.client_secret), + ) diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py new file mode 100644 index 0000000..810bfc6 --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py @@ -0,0 +1,18 @@ +from spotipy.oauth2 import SpotifyOAuth +from spotipy import Spotify +from spotify_shortcuts.config import Config + + +def authenticated_session(cfg: Config) -> Spotify: + assert cfg.client_id, "Spotify client ID is required" + assert cfg.client_secret, "Spotify client secret is required" + + return Spotify( + auth_manager=SpotifyOAuth( + client_id=cfg.client_id, + client_secret=cfg.client_secret, + redirect_uri="http://127.0.0.1:45632/callback", + scope="user-library-read user-library-modify user-read-playback-state", + cache_path=cfg.cache_file, + ) + ) diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py new file mode 100644 index 0000000..b0ebd78 --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py @@ -0,0 +1,21 @@ +from spotify_shortcuts.spotify_auth import authenticated_session +from spotify_shortcuts.config import load_config + + +def main(): + cfg = load_config() + sp = authenticated_session(cfg) + + if (playback := sp.current_playback()) is None: + print("No current playback found.") + return + + if (uri := playback.get("item", {}).get("uri", None)) is None: + print("No track URI found in current playback.") + return + + sp.current_user_saved_tracks_add(tracks=[uri]) + + +if __name__ == "__main__": + main() diff --git a/secrets/spotify-shortcuts.yaml b/secrets/spotify-shortcuts.yaml new file mode 100644 index 0000000..a6570d4 --- /dev/null +++ b/secrets/spotify-shortcuts.yaml @@ -0,0 +1,44 @@ +clientId: ENC[AES256_GCM,data:YJYM62aqGafgqsS2rFQZlS8REuR21biiGtQUaUG18Qg=,iv:TIL+rlKbBVo2/JlaGRDqLFwQ+ETx3jkqSqmGu6kyvJc=,tag:0J29BXv0kppcmqm5xbAvew==,type:str] +clientSecret: ENC[AES256_GCM,data:3pw6QRC+cjZlQ3iGnzLVjQh3sHPld6UC2jC8yq+J+34=,iv:9xctJRA4RFGy7x18Y2aPVuSC1lZ0Rko0R8Hr/gE2YIw=,tag:nB4VENRf0YeZCpMM5QFA9Q==,type:str] +sops: + age: + - recipient: age1expg8vyduf290pz7l4f3mjzvk9f0azfdn48pyjzs3m6p7v4qjq0qwtn36z + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBodVlLVW5PODFLcUh2anlU + Yys2czJSVzc3cHdpL3RZU01HcXhEUkNRcVV3CjcvNTROVStid2x0TUt6eEpQanJD + NkNSTlVkLzBqMUZQSUdHQyt4VUZZQW8KLS0tIEZiTm9HNUdtelNrVTUwSmFnb0p5 + K2NsMnZ3WDJIWWpmYml5cjNWZWFPWEUKfP9HxpJ35R/SiI5lzdRiVPIJUnhdbPJl + OtEUHJOrAYnKgX0uOo1argaQxN/8V0Py5njSdiiLd+mw1OCY4xef8w== + -----END AGE ENCRYPTED FILE----- + - recipient: age1wf0rq27v0n27zfy0es8ns3n25e2fdt063dgn68tt3f89rgrtu9csq4yhsp + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLY1N5aXZzRzVaU2QzcmxS + cjBTSlA1dlNMRGhhRDUrQWphR2ZJcHhTZjBBCmxjR3g0NVc4UUxBV25rNFVCSzhM + Tk5xeHZtZGkxRlpwRElZa0c4eUFKcXcKLS0tIHlCSXBKQ3BSSWNEeklBdmw1VHBI + RHVwTmd2dDlWSkZia2t6cE01bGxKUUkKQ9QuzfhuoGd7x42p5bP2E8Tatw1Ihqu2 + XFem9XLMIX1gNqRJkL7DmVybI/hE34pcAhALUKEG/K1vr51I/nKdGA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1xkmnvzus6fhundn4c0f6hyuwrj0f0m7x3hxtuhnez6cecr6m032qalw308 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMVWFwcE5GcHVnQzlCa2hz + UXlsMEFBRURlUWdRTXJUcktFRytzV0VWK3kwCnFDc0U3MzV1Mnhvek1DWmtvVXdW + bEJVM3ZpSm9IR2F2d0FtZHptOHlwWVEKLS0tIEJrL2YycVFGbGNuQ0JQZy80aFJa + YnNjSi9lSm1VWDlRRnJwb2U4cUhPWHcKXUB9ExCEgw29CvbT/OHZJa9F+DChep3r + twET8VbrV19O5zscu0OJ5s7hrobm+eWzPkoYlBXPC3bfwgeRRbsIvA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1clh2c489j7mx94aqr44u6k2cx5axqme9rlshqu9l2mcynluwhq6qwn0sv0 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqWENabXAwRlF0QmlRMGlS + SGx2UEFYcXJ6aWE0TDlrQ3FQNXFucTlVQXlBCmZSRERNMlFacUNDcHRtdVd1aFlh + WElZenhMT3JBMUhFK21MOEJhT083TVEKLS0tIEFHNzZZUzJtTkE3TEZNMlJreG1l + cHQxWXFCWlkvUFRvWUZycTdWMWRVMUEKN0jKYMQ9ARfnUUXprSYWdAAbVdOng8Yn + nV9sKYlTQ4fFBZ7w8hIBoJP3pWdIuZfEwKgA/7OyE02dts5wxIAuQw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-23T23:55:41Z" + mac: ENC[AES256_GCM,data:dS+rBxe/+Qce4rqQB8dhtuMmAnmUzvXOXPMTWH2tglxxdYcJrQgatGC+0qNdJIa4vEi1cb9IcHiQE4fv615OSQuc4uDIPzLyLK7eDFz9DkK/eXehK6V7t1ZUPYKiSswZYLBcApJTQFYzaG5OqcFm7rcFIz4toXo4TNM94s0dRH8=,iv:CWv9zYvMOn3qvkHnpT+Bk67VJbQs5daMxjpjYm6dr8I=,tag:+0ENRlYqliohdf7ytH7IcA==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 From 9a641f55cd196c23155b275fa2663409f83f606f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Thu, 24 Jul 2025 02:05:45 +0200 Subject: [PATCH 07/33] System Gen85 @ 2025-07-24-02:05:44 by jonas@monolith --- hosts/monolith/configuration.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index e973118..a606fb1 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -20,10 +20,12 @@ sops.secrets.spotify-shortcuts-clientId = { sopsFile = ../../secrets/spotify-shortcuts.yaml; key = "clientId"; + mode = "0644"; }; sops.secrets.spotify-shortcuts-clientSecret = { sopsFile = ../../secrets/spotify-shortcuts.yaml; key = "clientSecret"; + mode = "0644"; }; # Users From 680378e6913811a4d918740781bb98cf9abe16b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Thu, 24 Jul 2025 20:32:00 +0200 Subject: [PATCH 08/33] System Gen86 @ 2025-07-24-20:32:00 by jonas@monolith --- hosts/monolith/configuration.nix | 8 +++--- modules/programs/spotify-shortcuts.nix | 23 +++++++++------ .../spotify_shortcuts/config.py | 28 +++++++++++++------ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index a606fb1..53f9bb8 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -17,12 +17,12 @@ sopsFile = ../../secrets/monolith/wg.yaml; key = "privateKey"; }; - sops.secrets.spotify-shortcuts-clientId = { + sops.secrets.spotifyShortcutsClientId = { sopsFile = ../../secrets/spotify-shortcuts.yaml; key = "clientId"; mode = "0644"; }; - sops.secrets.spotify-shortcuts-clientSecret = { + sops.secrets.spotifyShortcutsClientSecret = { sopsFile = ../../secrets/spotify-shortcuts.yaml; key = "clientSecret"; mode = "0644"; @@ -81,8 +81,8 @@ }; hive.programs.spotify-shortcuts = { enable = true; - clientIdFile = config.sops.secrets.spotify-shortcuts-clientId.path; - clientSecretFile = config.sops.secrets.spotify-shortcuts-clientSecret.path; + clientIdSopsKey = config.sops.secrets.spotifyShortcutsClientId.name; + clientSecretSopsKey = config.sops.secrets.spotifyShortcutsClientSecret.name; }; # system packages diff --git a/modules/programs/spotify-shortcuts.nix b/modules/programs/spotify-shortcuts.nix index 30fe4ef..37cd980 100644 --- a/modules/programs/spotify-shortcuts.nix +++ b/modules/programs/spotify-shortcuts.nix @@ -8,21 +8,26 @@ in { options.hive.programs.spotify-shortcuts = { enable = lib.mkEnableOption "Enable Spotify Shortcuts"; - clientIdFile = lib.mkOption { - type = lib.types.path; - description = "Spotify API Client ID Path"; + clientIdSopsKey = lib.mkOption { + type = lib.types.singleLineStr; + description = "Spotify API Client ID sops secret name"; }; - clientSecretFile = lib.mkOption { - type = lib.types.path; - description = "Spotify API Client Secret Path"; + clientSecretSopsKey = lib.mkOption { + type = lib.types.singleLineStr; + description = "Spotify API Client Secret Path sops secret name"; }; }; config = lib.mkIf cfg.enable { environment.systemPackages = [pkgs.hive.spotify-shortcuts]; - environment.etc."profile.d/spotify-shortcuts.sh".text = '' - export SPOTIFY_SHORTCUTS_CLIENT_ID=$(cat ${cfg.clientIdFile}) - export SPOTIFY_SHORTCUTS_CLIENT_SECRET=$(cat ${cfg.clientSecretFile}) + environment.variables = { + SPOTIFY_SHORTCUTS_CONFIG = config.sops.templates."spotify-shortcuts-client.json".path; + }; + sops.templates."spotify-shortcuts-client.json".content = '' + { + "clientId": "${config.sops.placeholder.${cfg.clientIdSopsKey}}", + "clientSecret": "${config.sops.placeholder.${cfg.clientSecretSopsKey}}" + } ''; }; } diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/config.py b/pkgs/spotify-shortcuts/spotify_shortcuts/config.py index dbaeb31..c997893 100644 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/config.py +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/config.py @@ -5,6 +5,7 @@ from typing import List from os import getenv from sys import argv from xdg.BaseDirectory import xdg_cache_home +from json import loads @dataclass @@ -13,6 +14,19 @@ class Config: client_id: str | None = None client_secret: str | None = None + @staticmethod + def from_file(path: Path): + if not path.exists(): + raise FileNotFoundError(f"Configuration file {path} does not exist.") + with open(path, "r") as f: + data = loads(f.read()) + + return Config( + cache_file=Path(data.get("cacheFile", Config.cache_file)), + client_id=data.get("clientId", Config.client_id), + client_secret=data.get("clientSecret", Config.client_secret), + ) + def load_config(args: List[str] = argv[1:]) -> Config: parser = ArgumentParser(description="Spotify CLI Tool") @@ -37,14 +51,12 @@ def load_config(args: List[str] = argv[1:]) -> Config: ns = parser.parse_args(args) - cfg = Config( - cache_file=ns.cache_file, - client_id=ns.client_id, - client_secret=ns.client_secret, - ) + cfg = Config() + if (cfg_file := getenv("SPOTIFY_SHORTCUTS_CONFIG", None)) != None: + cfg = Config.from_file(Path(cfg_file)) return Config( - cache_file=Path(getenv("SPOTIFY_SHORTCUTS_CACHE_FILE", cfg.cache_file)), - client_id=getenv("SPOTIFY_SHORTCUTS_CLIENT_ID", cfg.client_id), - client_secret=getenv("SPOTIFY_SHORTCUTS_CLIENT_SECRET", cfg.client_secret), + cache_file=ns.cache_file or cfg.cache_file, + client_id=ns.client_id or cfg.client_id, + client_secret=ns.client_secret or cfg.client_secret, ) From 2cb614c1bfdb6fbd749bd373f7ad7869399de411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Thu, 24 Jul 2025 20:34:38 +0200 Subject: [PATCH 09/33] System Gen87 @ 2025-07-24-20:34:37 by jonas@monolith --- hosts/monolith/configuration.nix | 2 -- modules/programs/spotify-shortcuts.nix | 15 +++++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index 53f9bb8..3f0537c 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -20,12 +20,10 @@ sops.secrets.spotifyShortcutsClientId = { sopsFile = ../../secrets/spotify-shortcuts.yaml; key = "clientId"; - mode = "0644"; }; sops.secrets.spotifyShortcutsClientSecret = { sopsFile = ../../secrets/spotify-shortcuts.yaml; key = "clientSecret"; - mode = "0644"; }; # Users diff --git a/modules/programs/spotify-shortcuts.nix b/modules/programs/spotify-shortcuts.nix index 37cd980..111fc88 100644 --- a/modules/programs/spotify-shortcuts.nix +++ b/modules/programs/spotify-shortcuts.nix @@ -23,11 +23,14 @@ in { environment.variables = { SPOTIFY_SHORTCUTS_CONFIG = config.sops.templates."spotify-shortcuts-client.json".path; }; - sops.templates."spotify-shortcuts-client.json".content = '' - { - "clientId": "${config.sops.placeholder.${cfg.clientIdSopsKey}}", - "clientSecret": "${config.sops.placeholder.${cfg.clientSecretSopsKey}}" - } - ''; + sops.templates."spotify-shortcuts-client.json" = { + mode = "644"; + content = '' + { + "clientId": "${config.sops.placeholder.${cfg.clientIdSopsKey}}", + "clientSecret": "${config.sops.placeholder.${cfg.clientSecretSopsKey}}" + } + ''; + }; }; } From 7857c36e1c555e9ec553adc7b5b8c4bb83044aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Thu, 24 Jul 2025 20:35:51 +0200 Subject: [PATCH 10/33] System Gen88 @ 2025-07-24-20:35:50 by jonas@monolith --- modules/programs/spotify-shortcuts.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/spotify-shortcuts.nix b/modules/programs/spotify-shortcuts.nix index 111fc88..39214c3 100644 --- a/modules/programs/spotify-shortcuts.nix +++ b/modules/programs/spotify-shortcuts.nix @@ -24,7 +24,7 @@ in { SPOTIFY_SHORTCUTS_CONFIG = config.sops.templates."spotify-shortcuts-client.json".path; }; sops.templates."spotify-shortcuts-client.json" = { - mode = "644"; + mode = "444"; content = '' { "clientId": "${config.sops.placeholder.${cfg.clientIdSopsKey}}", From 87e526dec70e3d21023a6597acc059772bb7b83d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Fri, 25 Jul 2025 01:02:06 +0200 Subject: [PATCH 11/33] System Gen89 @ 2025-07-25-01:02:05 by jonas@monolith --- pkgs/spotify-shortcuts/derivation.nix | 2 +- pkgs/spotify-shortcuts/shell.nix | 23 ++++++++++++------- .../spotify_shortcuts/config.py | 14 ++++++++++- .../spotify_shortcuts/spotify_like.py | 10 ++++++++ 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/pkgs/spotify-shortcuts/derivation.nix b/pkgs/spotify-shortcuts/derivation.nix index f4cb8a5..8906869 100644 --- a/pkgs/spotify-shortcuts/derivation.nix +++ b/pkgs/spotify-shortcuts/derivation.nix @@ -2,6 +2,6 @@ with python3Packages; buildPythonApplication { name = "spotify-shortcuts"; - propagatedBuildInputs = [spotipy pyxdg]; + propagatedBuildInputs = [spotipy pyxdg desktop-notifier]; src = ./.; } diff --git a/pkgs/spotify-shortcuts/shell.nix b/pkgs/spotify-shortcuts/shell.nix index c41f7d0..a863d83 100644 --- a/pkgs/spotify-shortcuts/shell.nix +++ b/pkgs/spotify-shortcuts/shell.nix @@ -1,8 +1,15 @@ -{pkgs ? import {}}: -pkgs.mkShell { - packages = [ - pkgs.pyright - pkgs.black - ]; - inputsFrom = [(pkgs.callPackage ./derivation.nix {})]; -} +{pkgs ? import {}}: let + drv = pkgs.callPackage ./derivation.nix {}; +in + pkgs.mkShell { + packages = [ + pkgs.pyright + pkgs.black + ]; + + inputsFrom = [drv]; + + shellHook = '' + export PYTHONPATH="$PYTHONPATH:$(pwd)" + ''; + } diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/config.py b/pkgs/spotify-shortcuts/spotify_shortcuts/config.py index c997893..69901e1 100644 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/config.py +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/config.py @@ -13,6 +13,7 @@ class Config: cache_file: Path = Path(xdg_cache_home) / Path("spotify-shortcuts.json") client_id: str | None = None client_secret: str | None = None + notifications: bool = True @staticmethod def from_file(path: Path): @@ -48,15 +49,26 @@ def load_config(args: List[str] = argv[1:]) -> Config: default=Config.client_secret, help="Spotify API Client Secret", ) + parser.add_argument( + "--config-file", + type=str, + help="Path to a json configuration file with keys clientId and clientSecret", + ) + parser.add_argument( + "--no-notifications", + action="store_true", + help="Disable desktop notifications", + ) ns = parser.parse_args(args) cfg = Config() - if (cfg_file := getenv("SPOTIFY_SHORTCUTS_CONFIG", None)) != None: + if (cfg_file := ns.config_file or getenv("SPOTIFY_SHORTCUTS_CONFIG", None)) != None: cfg = Config.from_file(Path(cfg_file)) return Config( cache_file=ns.cache_file or cfg.cache_file, client_id=ns.client_id or cfg.client_id, client_secret=ns.client_secret or cfg.client_secret, + notifications=not ns.no_notifications or cfg.notifications, ) diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py index b0ebd78..a38ad2a 100644 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py @@ -1,5 +1,6 @@ from spotify_shortcuts.spotify_auth import authenticated_session from spotify_shortcuts.config import load_config +from desktop_notifier import DesktopNotifierSync def main(): @@ -16,6 +17,15 @@ def main(): sp.current_user_saved_tracks_add(tracks=[uri]) + if cfg.notifications: + dn = DesktopNotifierSync() + dn.send( + title="Track Liked", + message=f"Track \"{playback.get('item', {}).get('name', '')}\" by \"{ + ", ".join(a.get('name', '') for a in playback.get('item', {}).get('artists', [])) + }\" has been liked.", + ) + if __name__ == "__main__": main() From 818c0176145c09df76ca7e8e8d42fdce475cfe99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 27 Jul 2025 18:27:34 +0200 Subject: [PATCH 12/33] System Gen90 @ 2025-07-27-18:27:33 by jonas@monolith --- pkgs/spotify-shortcuts/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/spotify-shortcuts/setup.py b/pkgs/spotify-shortcuts/setup.py index 9a280e0..2dcce4c 100644 --- a/pkgs/spotify-shortcuts/setup.py +++ b/pkgs/spotify-shortcuts/setup.py @@ -9,6 +9,7 @@ setup( entry_points={ "console_scripts": [ "spotify-like=spotify_shortcuts.spotify_like:main", + "spotify-pl-add=spotify_shortcuts.spotify_pl_add:main", ], }, ) From 283f0febef371ee769fd25c24555382158c386f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 27 Jul 2025 18:31:27 +0200 Subject: [PATCH 13/33] System Gen91 @ 2025-07-27-18:31:26 by jonas@monolith --- .../spotify_shortcuts/spotify_pl_add.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py new file mode 100644 index 0000000..8e32844 --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py @@ -0,0 +1,40 @@ +from spotify_shortcuts.spotify_auth import authenticated_session +from spotify_shortcuts.config import load_config +from desktop_notifier import DesktopNotifierSync + + +def main(): + cfg = load_config() + sp = authenticated_session(cfg) + + if (playback := sp.current_playback()) is None: + print("No current playback found.") + return + + if (track_uri := playback.get("item", {}).get("uri", None)) is None: + print("No track URI found in current playback.") + return + + if (context_uri := playback.get("context", {}).get("uri", None)) is None: + print("No context URI found in current playback.") + return + + sp.playlist_add_items(context_uri, items=[track_uri]) + + if cfg.notifications: + track_name = playback.get("item", {}).get("name", "") + artists = ", ".join( + a.get("name", "") + for a in playback.get("item", {}).get("artists", []) + ) + playlist_name = (sp.playlist(context_uri) or {}).get("name", "") + + dn = DesktopNotifierSync() + dn.send( + title="Track Added to Playlist", + message=f'Track "{track_name}" by "{artists}" has been added to {playlist_name}.', + ) + + +if __name__ == "__main__": + main() From 0f8c6fc562d27ecfb2b1a6e42ed51b693f131b0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Tue, 29 Jul 2025 20:21:25 +0200 Subject: [PATCH 14/33] System Gen92 @ 2025-07-29-20:21:24 by jonas@monolith --- hosts/monolith/configuration.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index 3f0537c..499dac7 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -97,6 +97,7 @@ feh firefox git + gramps insomnia libreoffice mosquitto From 9a056ce6b0c749cd5269123014fbb4932d2eafd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Fri, 1 Aug 2025 00:56:55 +0200 Subject: [PATCH 15/33] System Gen93 @ 2025-08-01-00:56:55 by jonas@monolith --- pkgs/spotify-shortcuts/setup.py | 1 + .../spotify_shortcuts/spotify_auth.py | 8 +- .../spotify_shortcuts/spotify_like.py | 59 ++++++++------ .../spotify_shortcuts/spotify_pl_add.py | 79 +++++++++++-------- 4 files changed, 91 insertions(+), 56 deletions(-) diff --git a/pkgs/spotify-shortcuts/setup.py b/pkgs/spotify-shortcuts/setup.py index 2dcce4c..474c0fe 100644 --- a/pkgs/spotify-shortcuts/setup.py +++ b/pkgs/spotify-shortcuts/setup.py @@ -8,6 +8,7 @@ setup( packages=find_packages(), entry_points={ "console_scripts": [ + "spotisc=spotify_shortcuts.run:main", "spotify-like=spotify_shortcuts.spotify_like:main", "spotify-pl-add=spotify_shortcuts.spotify_pl_add:main", ], diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py index 810bfc6..f4f6574 100644 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py @@ -2,8 +2,10 @@ from spotipy.oauth2 import SpotifyOAuth from spotipy import Spotify from spotify_shortcuts.config import Config +CALLBACK_URI = "http://127.0.0.1:45632/callback" -def authenticated_session(cfg: Config) -> Spotify: + +def authenticated_session(cfg: Config, scopes: list[str]) -> Spotify: assert cfg.client_id, "Spotify client ID is required" assert cfg.client_secret, "Spotify client secret is required" @@ -11,8 +13,8 @@ def authenticated_session(cfg: Config) -> Spotify: auth_manager=SpotifyOAuth( client_id=cfg.client_id, client_secret=cfg.client_secret, - redirect_uri="http://127.0.0.1:45632/callback", - scope="user-library-read user-library-modify user-read-playback-state", + redirect_uri=CALLBACK_URI, + scope=" ".join(scopes), cache_path=cfg.cache_file, ) ) diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py index a38ad2a..32787ce 100644 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py @@ -1,30 +1,45 @@ -from spotify_shortcuts.spotify_auth import authenticated_session +from spotify_shortcuts.run import run_shortcut +from spotify_shortcuts.shortcut import Shortcut from spotify_shortcuts.config import load_config from desktop_notifier import DesktopNotifierSync +SCOPES = [ + "user-library-read", + "user-library-modify", + "user-read-playback-state", +] + + +class SpotifyLike(Shortcut): + def execute(self, client, config): + if (playback := client.current_playback()) is None: + print("No current playback found.") + return + + if (uri := playback.get("item", {}).get("uri", None)) is None: + print("No track URI found in current playback.") + return + + client.current_user_saved_tracks_add(tracks=[uri]) + + if config.notifications: + dn = DesktopNotifierSync() + dn.send( + title="Track Liked", + message=f"Track \"{playback.get('item', {}).get('name', '')}\" by \"{ + ", ".join(a.get('name', '') for a in playback.get('item', {}).get('artists', [])) + }\" has been liked.", + ) + + def get_help(self) -> str: + return "Like the currently playing track." + + def get_scopes(self) -> list[str]: + return SCOPES + def main(): - cfg = load_config() - sp = authenticated_session(cfg) - - if (playback := sp.current_playback()) is None: - print("No current playback found.") - return - - if (uri := playback.get("item", {}).get("uri", None)) is None: - print("No track URI found in current playback.") - return - - sp.current_user_saved_tracks_add(tracks=[uri]) - - if cfg.notifications: - dn = DesktopNotifierSync() - dn.send( - title="Track Liked", - message=f"Track \"{playback.get('item', {}).get('name', '')}\" by \"{ - ", ".join(a.get('name', '') for a in playback.get('item', {}).get('artists', [])) - }\" has been liked.", - ) + run_shortcut(SpotifyLike(), load_config()) if __name__ == "__main__": diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py index 8e32844..63d5426 100644 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py @@ -1,39 +1,56 @@ -from spotify_shortcuts.spotify_auth import authenticated_session +from spotify_shortcuts.shortcut import Shortcut from spotify_shortcuts.config import load_config from desktop_notifier import DesktopNotifierSync +from spotify_shortcuts.run import run_shortcut + +SCOPES = [ + "playlist-modify-public", + "playlist-modify-private", + "user-read-playback-state", +] + + +class SpotifyPlAdd(Shortcut): + def execute(self, client, config): + if (playback := client.current_playback()) is None: + print("No current playback found.") + return + + if (track_uri := playback.get("item", {}).get("uri", None)) is None: + print("No track URI found in current playback.") + return + + if (context_uri := playback.get("context", {}).get("uri", None)) is None: + print("No context URI found in current playback.") + return + + client.playlist_add_items(context_uri, items=[track_uri]) + + if config.notifications: + track_name = playback.get("item", {}).get("name", "") + artists = ", ".join( + a.get("name", "") + for a in playback.get("item", {}).get("artists", []) + ) + playlist_name = (client.playlist(context_uri) or {}).get( + "name", "" + ) + + dn = DesktopNotifierSync() + dn.send( + title="Track Added to Playlist", + message=f'Track "{track_name}" by "{artists}" has been added to {playlist_name}.', + ) + + def get_help(self) -> str: + return "Add the currently playing track to the current playlist." + + def get_scopes(self) -> list[str]: + return SCOPES def main(): - cfg = load_config() - sp = authenticated_session(cfg) - - if (playback := sp.current_playback()) is None: - print("No current playback found.") - return - - if (track_uri := playback.get("item", {}).get("uri", None)) is None: - print("No track URI found in current playback.") - return - - if (context_uri := playback.get("context", {}).get("uri", None)) is None: - print("No context URI found in current playback.") - return - - sp.playlist_add_items(context_uri, items=[track_uri]) - - if cfg.notifications: - track_name = playback.get("item", {}).get("name", "") - artists = ", ".join( - a.get("name", "") - for a in playback.get("item", {}).get("artists", []) - ) - playlist_name = (sp.playlist(context_uri) or {}).get("name", "") - - dn = DesktopNotifierSync() - dn.send( - title="Track Added to Playlist", - message=f'Track "{track_name}" by "{artists}" has been added to {playlist_name}.', - ) + run_shortcut(SpotifyPlAdd(), load_config()) if __name__ == "__main__": From 1616d78385eade1d5bee56296da82e2f256cda3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Fri, 1 Aug 2025 00:58:27 +0200 Subject: [PATCH 16/33] System Gen94 @ 2025-08-01-00:58:27 by jonas@monolith --- .../spotify_shortcuts/__main__.py | 4 ++ .../spotify_shortcuts/registry.py | 7 +++ .../spotify_shortcuts/run.py | 47 +++++++++++++++++++ .../spotify_shortcuts/shortcut.py | 21 +++++++++ 4 files changed, 79 insertions(+) create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/__main__.py create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/registry.py create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/run.py create mode 100644 pkgs/spotify-shortcuts/spotify_shortcuts/shortcut.py diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/__main__.py b/pkgs/spotify-shortcuts/spotify_shortcuts/__main__.py new file mode 100644 index 0000000..8f3c09e --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/__main__.py @@ -0,0 +1,4 @@ +from spotify_shortcuts.run import main + +if __name__ == "__main__": + main() diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/registry.py b/pkgs/spotify-shortcuts/spotify_shortcuts/registry.py new file mode 100644 index 0000000..7e6f694 --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/registry.py @@ -0,0 +1,7 @@ +from spotify_shortcuts.spotify_like import SpotifyLike +from spotify_shortcuts.spotify_pl_add import SpotifyPlAdd + +SHORTCUT_REGISTRY = { + "like": SpotifyLike(), + "pl_add": SpotifyPlAdd(), +} diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/run.py b/pkgs/spotify-shortcuts/spotify_shortcuts/run.py new file mode 100644 index 0000000..423ff6a --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/run.py @@ -0,0 +1,47 @@ +from spotify_shortcuts.config import Config, load_config +from spotify_shortcuts.shortcut import Shortcut +from spotify_shortcuts.spotify_auth import authenticated_session +from itertools import chain + + +def all_scopes() -> list[str]: + from spotify_shortcuts.registry import SHORTCUT_REGISTRY + + return list( + set( + chain.from_iterable( + shortcut.get_scopes() for shortcut in SHORTCUT_REGISTRY.values() + ) + ) + ) + + +def run_shortcut(shortcut: Shortcut, config: Config): + client = authenticated_session( + config, scopes=all_scopes() # use all scopes to avoid re-authentication + ) + + shortcut.execute(client, config) + + +def main(): + from spotify_shortcuts.registry import SHORTCUT_REGISTRY + import sys + + if len(sys.argv) < 2: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + + shortcut_name = sys.argv[1] + if shortcut_name not in SHORTCUT_REGISTRY: + print(f"Shortcut '{shortcut_name}' not found.") + sys.exit(1) + + shortcut = SHORTCUT_REGISTRY[shortcut_name] + config = load_config(args=sys.argv[2:]) + + run_shortcut(shortcut, config) + + +if __name__ == "__main__": + main() diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/shortcut.py b/pkgs/spotify-shortcuts/spotify_shortcuts/shortcut.py new file mode 100644 index 0000000..e8d871b --- /dev/null +++ b/pkgs/spotify-shortcuts/spotify_shortcuts/shortcut.py @@ -0,0 +1,21 @@ +from abc import ABC, abstractmethod + +from spotify_shortcuts.config import Config +from spotipy import Spotify + + +class Shortcut(ABC): + @abstractmethod + def execute(self, client: Spotify, config: Config): + """Execute the shortcut action.""" + pass + + @abstractmethod + def get_help(self) -> str: + """Return a description of the shortcut.""" + pass + + @abstractmethod + def get_scopes(self) -> list[str]: + """Return the spotify API scopes required for the shortcut.""" + pass From 9627f73ed2f6112720b3d51b0118d4092bb35c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Mon, 11 Aug 2025 02:10:43 +0200 Subject: [PATCH 17/33] System Gen95 @ 2025-08-11-02:10:43 by jonas@monolith --- modules/programs/creative.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/programs/creative.nix b/modules/programs/creative.nix index 363ee22..e31b8b0 100644 --- a/modules/programs/creative.nix +++ b/modules/programs/creative.nix @@ -51,6 +51,7 @@ in { ++ lib.optional cfg.image-management digikam ++ lib.optionals cfg.image-raw-processing [ darktable + rawtherapee enblend-enfuse hdrmerge hugin From fc6a8e723a973fab6f8d8af7c39940936c0d62c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Mon, 11 Aug 2025 14:45:52 +0200 Subject: [PATCH 18/33] Upgrade Gen96 @ 2025-08-11-14:45:51 by jonas@monolith --- flake.lock | 132 ++++++++++++++++++++++++++--------------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/flake.lock b/flake.lock index 531c637..f928494 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ ] }, "locked": { - "lastModified": 1750372185, - "narHash": "sha256-lVBKxd9dsZOH1fA6kSE5WNnt8e+09fN+NL/Q3BjTWHY=", + "lastModified": 1753216019, + "narHash": "sha256-zik7WISrR1ks2l6T1MZqZHb/OqroHdJnSnAehkE0kCk=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "7cef49d261cbbe537e8cb662485e76d29ac4cbca", + "rev": "be166e11d86ba4186db93e10c54a141058bdce49", "type": "github" }, "original": { @@ -61,11 +61,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1750737804, - "narHash": "sha256-wClGd2PhxdjjphR6wIgoiDcR+Gfg4/+FyseSOjIIzVU=", + "lastModified": 1754512310, + "narHash": "sha256-gXE5lTYMOhpDJo+siLXW/3BzySPmLMD12GVB1QFVbyw=", "owner": "rycee", "repo": "nur-expressions", - "rev": "aaaf4fec792bad465ea4a35c0be5bc2a54f33095", + "rev": "2008f9aa7a5ccde48bfc1de5a919be5898da09c2", "type": "gitlab" }, "original": { @@ -78,11 +78,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", "owner": "edolstra", "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", "type": "github" }, "original": { @@ -136,11 +136,11 @@ ] }, "locked": { - "lastModified": 1750783375, - "narHash": "sha256-oKccVOF1igIwTncVTHZ9RHgjOQEMbg8NK5am2IjOCCI=", + "lastModified": 1753592768, + "narHash": "sha256-oV695RvbAE4+R9pcsT9shmp6zE/+IZe6evHWX63f2Qg=", "owner": "nix-community", "repo": "home-manager", - "rev": "d457fa3c764e53e7bdd7354467c605766407620d", + "rev": "fc3add429f21450359369af74c2375cb34a2d204", "type": "github" }, "original": { @@ -166,11 +166,11 @@ ] }, "locked": { - "lastModified": 1749155331, - "narHash": "sha256-XR9fsI0zwLiFWfqi/pdS/VD+YNorKb3XIykgTg4l1nA=", + "lastModified": 1753964049, + "narHash": "sha256-lIqabfBY7z/OANxHoPeIrDJrFyYy9jAM4GQLzZ2feCM=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "45fcc10b4c282746d93ec406a740c43b48b4ef80", + "rev": "44e91d467bdad8dcf8bbd2ac7cf49972540980a5", "type": "github" }, "original": { @@ -195,11 +195,11 @@ ] }, "locked": { - "lastModified": 1750371717, - "narHash": "sha256-cNP+bVq8m5x2Rl6MTjwfQLCdwbVmKvTH7yqVc1SpiJM=", + "lastModified": 1754305013, + "narHash": "sha256-u+M2f0Xf1lVHzIPQ7DsNCDkM1NYxykOSsRr4t3TbSM4=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "15c6f8f3a567fec9a0f732cd310a7ff456deef88", + "rev": "4c1d63a0f22135db123fc789f174b89544c6ec2d", "type": "github" }, "original": { @@ -226,11 +226,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1750771433, - "narHash": "sha256-AG2TRRcc84066tAOdJ1hdy1ZbpR53UbqGxmaL3VecRc=", + "lastModified": 1754844749, + "narHash": "sha256-QNT0yXHyjvZ++vrJICAWFBMrcrTVbgRIZLplmOv1W7s=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "aea81320015130bf850242d5a8695fcdcbf4f0c1", + "rev": "584b844aaf72cd7ea6851117f1bd598b7467ffc1", "type": "github" }, "original": { @@ -256,11 +256,11 @@ ] }, "locked": { - "lastModified": 1750778528, - "narHash": "sha256-X0QpVEhpkhf0RvU0n5+qsBH3JIXY2uZ8m56HhP7FzU8=", + "lastModified": 1754766309, + "narHash": "sha256-pANfQZ22RNF6sCFxrMahjE70v/HbGfA4lPZ7pTmfwUQ=", "owner": "hyprwm", "repo": "hyprland-plugins", - "rev": "aa23323de3325e3026fc26f9c23205954be4d337", + "rev": "833af8e8c6f035a53a167aff59e5e85bf0386d93", "type": "github" }, "original": { @@ -349,11 +349,11 @@ ] }, "locked": { - "lastModified": 1750371812, - "narHash": "sha256-D868K1dVEACw17elVxRgXC6hOxY+54wIEjURztDWLk8=", + "lastModified": 1753819801, + "narHash": "sha256-tHe6XeNeVeKapkNM3tcjW4RuD+tB2iwwoogWJOtsqTI=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "b13c7481e37856f322177010bdf75fccacd1adc8", + "rev": "b308a818b9dcaa7ab8ccab891c1b84ebde2152bc", "type": "github" }, "original": { @@ -378,11 +378,11 @@ ] }, "locked": { - "lastModified": 1750371198, - "narHash": "sha256-/iuJ1paQOBoSLqHflRNNGyroqfF/yvPNurxzcCT0cAE=", + "lastModified": 1753622892, + "narHash": "sha256-0K+A+gmOI8IklSg5It1nyRNv0kCNL51duwnhUO/B8JA=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "cee01452bca58d6cadb3224e21e370de8bc20f0b", + "rev": "23f0debd2003f17bd65f851cd3f930cff8a8c809", "type": "github" }, "original": { @@ -403,11 +403,11 @@ ] }, "locked": { - "lastModified": 1750371096, - "narHash": "sha256-JB1IeJ41y7kWc/dPGV6RMcCUM0Xj2NEK26A2Ap7EM9c=", + "lastModified": 1754481650, + "narHash": "sha256-6u6HdEFJh5gY6VfyMQbhP7zDdVcqOrCDTkbiHJmAtMI=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "38f3a211657ce82a1123bf19402199b67a410f08", + "rev": "df6b8820c4a0835d83d0c7c7be86fbc555f1f7fd", "type": "github" }, "original": { @@ -428,11 +428,11 @@ ] }, "locked": { - "lastModified": 1750371869, - "narHash": "sha256-lGk4gLjgZQ/rndUkzmPYcgbHr8gKU5u71vyrjnwfpB4=", + "lastModified": 1751897909, + "narHash": "sha256-FnhBENxihITZldThvbO7883PdXC/2dzW4eiNvtoV5Ao=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "aa38edd6e3e277ae6a97ea83a69261a5c3aab9fd", + "rev": "fcca0c61f988a9d092cbb33e906775014c61579d", "type": "github" }, "original": { @@ -451,11 +451,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1750763263, - "narHash": "sha256-3JW7xEfobw0qXZsOZ0BwGV5+JMzOE+fZ3+v0ypOwKt0=", + "lastModified": 1751591814, + "narHash": "sha256-A4lgvuj4v+Pr8MniXz1FBG0DXOygi8tTECR+j53FMhM=", "owner": "lilyinstarlight", "repo": "nixos-cosmic", - "rev": "dabf86334f0eab8ced9a5e7219d34a28b055bb2a", + "rev": "fef2d0c78c4e4d6c600a88795af193131ff51bdc", "type": "github" }, "original": { @@ -466,11 +466,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1750431636, - "narHash": "sha256-vnzzBDbCGvInmfn2ijC4HsIY/3W1CWbwS/YQoFgdgPg=", + "lastModified": 1754564048, + "narHash": "sha256-dz303vGuzWjzOPOaYkS9xSW+B93PSAJxvBd6CambXVA=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "1552a9f4513f3f0ceedcf90320e48d3d47165712", + "rev": "26ed7a0d4b8741fe1ef1ee6fa64453ca056ce113", "type": "github" }, "original": { @@ -482,11 +482,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1750622754, - "narHash": "sha256-kMhs+YzV4vPGfuTpD3mwzibWUE6jotw5Al2wczI0Pv8=", + "lastModified": 1754767907, + "narHash": "sha256-8OnUzRQZkqtUol9vuUuQC30hzpMreKptNyET2T9lB6g=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c7ab75210cb8cb16ddd8f290755d9558edde7ee1", + "rev": "c5f08b62ed75415439d48152c2a784e36909b1bc", "type": "github" }, "original": { @@ -498,11 +498,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1750646418, - "narHash": "sha256-4UAN+W0Lp4xnUiHYXUXAPX18t+bn6c4Btry2RqM9JHY=", + "lastModified": 1751048012, + "narHash": "sha256-MYbotu4UjWpTsq01wglhN5xDRfZYLFtNk7SBY0BcjkU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1f426f65ac4e6bf808923eb6f8b8c2bfba3d18c5", + "rev": "a684c58d46ebbede49f280b653b9e56100aa3877", "type": "github" }, "original": { @@ -514,11 +514,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1750506804, - "narHash": "sha256-VLFNc4egNjovYVxDGyBYTrvVCgDYgENp5bVi9fPTDYc=", + "lastModified": 1754725699, + "narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=", "owner": "nixos", "repo": "nixpkgs", - "rev": "4206c4cb56751df534751b058295ea61357bbbaa", + "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054", "type": "github" }, "original": { @@ -538,11 +538,11 @@ ] }, "locked": { - "lastModified": 1748196248, - "narHash": "sha256-1iHjsH6/5UOerJEoZKE+Gx1BgAoge/YcnUsOA4wQ/BU=", + "lastModified": 1754501628, + "narHash": "sha256-FExJ54tVB5iu7Dh2tLcyCSWpaV+lmUzzWKZUkemwXvo=", "owner": "pjones", "repo": "plasma-manager", - "rev": "b7697abe89967839b273a863a3805345ea54ab56", + "rev": "cca090f8115c4172b9aef6c5299ae784bdd5e133", "type": "github" }, "original": { @@ -561,11 +561,11 @@ ] }, "locked": { - "lastModified": 1749636823, - "narHash": "sha256-WUaIlOlPLyPgz9be7fqWJA5iG6rHcGRtLERSCfUDne4=", + "lastModified": 1754416808, + "narHash": "sha256-c6yg0EQ9xVESx6HGDOCMcyRSjaTpNJP10ef+6fRcofA=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "623c56286de5a3193aa38891a6991b28f9bab056", + "rev": "9c52372878df6911f9afc1e2a1391f55e4dfc864", "type": "github" }, "original": { @@ -597,11 +597,11 @@ ] }, "locked": { - "lastModified": 1750732748, - "narHash": "sha256-HR2b3RHsPeJm+Fb+1ui8nXibgniVj7hBNvUbXEyz0DU=", + "lastModified": 1751251399, + "narHash": "sha256-y+viCuy/eKKpkX1K2gDvXIJI/yzvy6zA3HObapz9XZ0=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "4b4494b2ba7e8a8041b2e28320b2ee02c115c75f", + "rev": "b22d5ee8c60ed1291521f2dde48784edd6bf695b", "type": "github" }, "original": { @@ -617,11 +617,11 @@ ] }, "locked": { - "lastModified": 1750119275, - "narHash": "sha256-Rr7Pooz9zQbhdVxux16h7URa6mA80Pb/G07T4lHvh0M=", + "lastModified": 1754328224, + "narHash": "sha256-glPK8DF329/dXtosV7YSzRlF4n35WDjaVwdOMEoEXHA=", "owner": "Mic92", "repo": "sops-nix", - "rev": "77c423a03b9b2b79709ea2cb63336312e78b72e2", + "rev": "49021900e69812ba7ddb9e40f9170218a7eca9f4", "type": "github" }, "original": { @@ -673,11 +673,11 @@ ] }, "locked": { - "lastModified": 1750372504, - "narHash": "sha256-VBeZb1oqZM1cqCAZnFz/WyYhO8aF/ImagI7WWg/Z3Og=", + "lastModified": 1753633878, + "narHash": "sha256-js2sLRtsOUA/aT10OCDaTjO80yplqwOIaLUqEe0nMx0=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "400308fc4f9d12e0a93e483c2e7a649e12af1a92", + "rev": "371b96bd11ad2006ed4f21229dbd1be69bed3e8a", "type": "github" }, "original": { From 41d4f40b7b61b29a25270ad9bc153ae616dc14d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:20:02 +0200 Subject: [PATCH 19/33] System Gen98 @ 2025-08-17-14:20:01 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index 7090f11..3651e76 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -20,7 +20,7 @@ stdenv.mkDerivation rec { # Propagate sddm theme dependencies to user env otherwise sddm does # not find them. Putting them in buildInputs is not enough. propagatedUserEnvPkgs = [ - kdeclarative + kdeclarative.bin libplasma plasma-workspace ]; From 447499e37b92d08de0e3db89baadf7c1da2cf83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:24:05 +0200 Subject: [PATCH 20/33] System Gen98 @ 2025-08-17-14:20:01 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index 3651e76..da61a2d 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -4,7 +4,7 @@ fetchFromGitHub, gitUpdater, kdeclarative, - libplasma, + plasma-framework, plasma-workspace, }: stdenv.mkDerivation rec { @@ -21,7 +21,7 @@ stdenv.mkDerivation rec { # not find them. Putting them in buildInputs is not enough. propagatedUserEnvPkgs = [ kdeclarative.bin - libplasma + plasma-framework plasma-workspace ]; From ba8d13bf4fe6833f51fcb1bb084fba8868b980df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:30:16 +0200 Subject: [PATCH 21/33] System Gen98 @ 2025-08-17-14:20:01 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index da61a2d..fae4806 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -3,9 +3,7 @@ lib, fetchFromGitHub, gitUpdater, - kdeclarative, - plasma-framework, - plasma-workspace, + libsForQt6, }: stdenv.mkDerivation rec { pname = "layan-kde"; @@ -19,7 +17,7 @@ stdenv.mkDerivation rec { # Propagate sddm theme dependencies to user env otherwise sddm does # not find them. Putting them in buildInputs is not enough. - propagatedUserEnvPkgs = [ + propagatedUserEnvPkgs = with libsForQt6; [ kdeclarative.bin plasma-framework plasma-workspace From d9afe380c6e5c654f0ed96074ae2bc1605e32e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:33:09 +0200 Subject: [PATCH 22/33] Home Gen37 @ 2025-06-24-20:34 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index fae4806..e94b53a 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -3,7 +3,7 @@ lib, fetchFromGitHub, gitUpdater, - libsForQt6, + kdePackages, }: stdenv.mkDerivation rec { pname = "layan-kde"; @@ -17,9 +17,9 @@ stdenv.mkDerivation rec { # Propagate sddm theme dependencies to user env otherwise sddm does # not find them. Putting them in buildInputs is not enough. - propagatedUserEnvPkgs = with libsForQt6; [ - kdeclarative.bin - plasma-framework + propagatedUserEnvPkgs = with kdePackages; [ + kdeclarative + libplasma plasma-workspace ]; From 43c284514ced5a76225bc6fa52185c0b66ea366b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:40:10 +0200 Subject: [PATCH 23/33] Home Gen37 @ 2025-06-24-20:34 by jonas@monolith --- modules/home/themes/layan.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/home/themes/layan.nix b/modules/home/themes/layan.nix index aee12f9..f0cd58e 100644 --- a/modules/home/themes/layan.nix +++ b/modules/home/themes/layan.nix @@ -13,7 +13,7 @@ in { config = lib.mkIf cfg.enable { home.packages = [ - layan-qt6 + # layan-qt6 pkgs.kdePackages.qtstyleplugin-kvantum pkgs.unstable.layan-cursors pkgs.layan-gtk-theme From b3a9fbee74e94cc17e54970a0d2e2689d0fa7f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:43:11 +0200 Subject: [PATCH 24/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- home/jonas@monolith.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/jonas@monolith.nix b/home/jonas@monolith.nix index 0785d9b..93386b3 100644 --- a/home/jonas@monolith.nix +++ b/home/jonas@monolith.nix @@ -23,7 +23,7 @@ hive.nextcloud.enable = false; # kwallet bug hive.nix-scripts.enable = true; hive.ranger.enable = true; - hive.themes.layan.enable = true; + hive.themes.layan.enable = false; hive.yubikey.enable = true; hive.zsh.enable = true; From 6aeadc9d08ad1e984f4d05c59a0a272d41efe50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:47:49 +0200 Subject: [PATCH 25/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- home/jonas@monolith.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/jonas@monolith.nix b/home/jonas@monolith.nix index 93386b3..0785d9b 100644 --- a/home/jonas@monolith.nix +++ b/home/jonas@monolith.nix @@ -23,7 +23,7 @@ hive.nextcloud.enable = false; # kwallet bug hive.nix-scripts.enable = true; hive.ranger.enable = true; - hive.themes.layan.enable = false; + hive.themes.layan.enable = true; hive.yubikey.enable = true; hive.zsh.enable = true; From c0d31fe22072eb4bd7cd9a4dd5916f8619c81d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:50:11 +0200 Subject: [PATCH 26/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 9 ++++----- modules/home/themes/layan.nix | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index e94b53a..f9dc9af 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -3,7 +3,9 @@ lib, fetchFromGitHub, gitUpdater, - kdePackages, + kdeclarative, + libplasma, + plasma-workspace, }: stdenv.mkDerivation rec { pname = "layan-kde"; @@ -17,10 +19,7 @@ stdenv.mkDerivation rec { # Propagate sddm theme dependencies to user env otherwise sddm does # not find them. Putting them in buildInputs is not enough. - propagatedUserEnvPkgs = with kdePackages; [ - kdeclarative - libplasma - plasma-workspace + propagatedUserEnvPkgs = [ ]; postPatch = '' diff --git a/modules/home/themes/layan.nix b/modules/home/themes/layan.nix index f0cd58e..aee12f9 100644 --- a/modules/home/themes/layan.nix +++ b/modules/home/themes/layan.nix @@ -13,7 +13,7 @@ in { config = lib.mkIf cfg.enable { home.packages = [ - # layan-qt6 + layan-qt6 pkgs.kdePackages.qtstyleplugin-kvantum pkgs.unstable.layan-cursors pkgs.layan-gtk-theme From b1aa40c7d898d51eaf1b2088412d50994df6a489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 14:51:24 +0200 Subject: [PATCH 27/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index f9dc9af..c571781 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -8,7 +8,7 @@ plasma-workspace, }: stdenv.mkDerivation rec { - pname = "layan-kde"; + pname = "layan-kde-qt6"; version = "2025-02-13"; src = fetchFromGitHub { owner = "vinceliuice"; From 96f8715f7e4f4d7ed6941d993a895c306918f6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 15:02:58 +0200 Subject: [PATCH 28/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index c571781..ad850f6 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -4,7 +4,6 @@ fetchFromGitHub, gitUpdater, kdeclarative, - libplasma, plasma-workspace, }: stdenv.mkDerivation rec { @@ -20,6 +19,8 @@ stdenv.mkDerivation rec { # Propagate sddm theme dependencies to user env otherwise sddm does # not find them. Putting them in buildInputs is not enough. propagatedUserEnvPkgs = [ + kdeclarative + plasma-workspace ]; postPatch = '' From e57a17a4279d7d85491dbf5db2d7469f63a790f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 15:03:50 +0200 Subject: [PATCH 29/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index ad850f6..15eb3b2 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -20,7 +20,6 @@ stdenv.mkDerivation rec { # not find them. Putting them in buildInputs is not enough. propagatedUserEnvPkgs = [ kdeclarative - plasma-workspace ]; postPatch = '' From 9ffd68a9cf7ad6e8caffbd4dc89483b1efb1d48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 15:04:12 +0200 Subject: [PATCH 30/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- modules/home/themes/layan-qt6.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/home/themes/layan-qt6.nix b/modules/home/themes/layan-qt6.nix index 15eb3b2..7de9dc5 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/modules/home/themes/layan-qt6.nix @@ -4,7 +4,6 @@ fetchFromGitHub, gitUpdater, kdeclarative, - plasma-workspace, }: stdenv.mkDerivation rec { pname = "layan-kde-qt6"; From d58dca0cfa55a3d0ba285b636d8918015673b4f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 15:16:36 +0200 Subject: [PATCH 31/33] System Gen99 @ 2025-08-17-15:16:36 by jonas@monolith --- hosts/monolith/configuration.nix | 1 + pkgs/default.nix | 1 + {modules/home/themes => pkgs}/layan-qt6.nix | 4 ++++ 3 files changed, 6 insertions(+) rename {modules/home/themes => pkgs}/layan-qt6.nix (94%) diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index 499dac7..84ce7c5 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -98,6 +98,7 @@ firefox git gramps + hive.layan-qt6 insomnia libreoffice mosquitto diff --git a/pkgs/default.nix b/pkgs/default.nix index 3c24567..2ef740f 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -3,5 +3,6 @@ final: _: { crossover = final.callPackage ./crossover.nix {}; transcode-davinci-resolve = final.callPackage ./transcode-davinci-resolve {}; spotify-shortcuts = final.callPackage ./spotify-shortcuts {}; + layan-qt6 = final.kdePackages.callPackage ./layan-qt6.nix {}; }; } diff --git a/modules/home/themes/layan-qt6.nix b/pkgs/layan-qt6.nix similarity index 94% rename from modules/home/themes/layan-qt6.nix rename to pkgs/layan-qt6.nix index 7de9dc5..0b52051 100644 --- a/modules/home/themes/layan-qt6.nix +++ b/pkgs/layan-qt6.nix @@ -4,6 +4,8 @@ fetchFromGitHub, gitUpdater, kdeclarative, + libplasma, + plasma-workspace, }: stdenv.mkDerivation rec { pname = "layan-kde-qt6"; @@ -19,6 +21,8 @@ stdenv.mkDerivation rec { # not find them. Putting them in buildInputs is not enough. propagatedUserEnvPkgs = [ kdeclarative + libplasma + plasma-workspace ]; postPatch = '' From f06bae025640cbb5f9571609e77260b34b5c806d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 15:17:37 +0200 Subject: [PATCH 32/33] Home Gen38 @ 2025-08-17-14:42 by jonas@monolith --- modules/home/themes/layan.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/home/themes/layan.nix b/modules/home/themes/layan.nix index aee12f9..28affad 100644 --- a/modules/home/themes/layan.nix +++ b/modules/home/themes/layan.nix @@ -5,7 +5,6 @@ ... }: let cfg = config.hive.themes.layan; - layan-qt6 = pkgs.kdePackages.callPackage ./layan-qt6.nix {}; in { options.hive.themes.layan = { enable = lib.mkEnableOption "Layan theme configuration"; @@ -13,7 +12,6 @@ in { config = lib.mkIf cfg.enable { home.packages = [ - layan-qt6 pkgs.kdePackages.qtstyleplugin-kvantum pkgs.unstable.layan-cursors pkgs.layan-gtk-theme From ffb23dc187fe0cb381b31edc797ef607524c76c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 17 Aug 2025 15:39:55 +0200 Subject: [PATCH 33/33] System Gen100 @ 2025-08-17-15:39:54 by jonas@monolith --- hosts/monolith/configuration.nix | 2 +- modules/default.nix | 1 + modules/desktop/themes/default.nix | 5 +++++ modules/desktop/themes/layan.nix | 21 +++++++++++++++++++++ modules/home/themes/layan.nix | 7 ------- 5 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 modules/desktop/themes/default.nix create mode 100644 modules/desktop/themes/layan.nix diff --git a/hosts/monolith/configuration.nix b/hosts/monolith/configuration.nix index 84ce7c5..adb144b 100644 --- a/hosts/monolith/configuration.nix +++ b/hosts/monolith/configuration.nix @@ -51,6 +51,7 @@ # hive modules hive.nix-scripts.enable = true; hive.displayManager.name = "sddm"; + hive.themes.layan.enable = true; hive.plasma.enable = true; hive.kwallet.enable = true; hive.kwallet.forUsers = ["jonas"]; @@ -98,7 +99,6 @@ firefox git gramps - hive.layan-qt6 insomnia libreoffice mosquitto diff --git a/modules/default.nix b/modules/default.nix index 6604626..ccc3b8e 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -18,6 +18,7 @@ # pure system modules ./desktop/de ./desktop/dm + ./desktop/themes ./hardware/bluetooth.nix ./hardware/sound.nix ./hardware/yubikey.nix diff --git a/modules/desktop/themes/default.nix b/modules/desktop/themes/default.nix new file mode 100644 index 0000000..65faac2 --- /dev/null +++ b/modules/desktop/themes/default.nix @@ -0,0 +1,5 @@ +{...}: { + imports = [ + ./layan.nix + ]; +} diff --git a/modules/desktop/themes/layan.nix b/modules/desktop/themes/layan.nix new file mode 100644 index 0000000..a89573c --- /dev/null +++ b/modules/desktop/themes/layan.nix @@ -0,0 +1,21 @@ +{ + lib, + config, + pkgs, + ... +}: let + cfg = config.hive.themes.layan; +in { + options.hive.themes.layan = { + enable = lib.mkEnableOption "Layan theme configuration"; + }; + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.hive.layan-qt6 + pkgs.kdePackages.qtstyleplugin-kvantum + pkgs.unstable.layan-cursors + pkgs.layan-gtk-theme + pkgs.tela-circle-icon-theme + ]; + }; +} diff --git a/modules/home/themes/layan.nix b/modules/home/themes/layan.nix index 28affad..b81470f 100644 --- a/modules/home/themes/layan.nix +++ b/modules/home/themes/layan.nix @@ -11,13 +11,6 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ - pkgs.kdePackages.qtstyleplugin-kvantum - pkgs.unstable.layan-cursors - pkgs.layan-gtk-theme - pkgs.tela-circle-icon-theme - ]; - qt.enable = false; qt.style.name = "kvantum"; qt.style.package = pkgs.kdePackages.qtstyleplugin-kvantum;