diff --git a/fixes/plasma-fix.nix b/fixes/plasma-fix.nix deleted file mode 100644 index 35e95f9..0000000 --- a/fixes/plasma-fix.nix +++ /dev/null @@ -1,57 +0,0 @@ -# https://github.com/NixOS/nixpkgs/issues/126590#issuecomment-3194531220 -{ - config, - pkgs, - lib, - ... -}: { - nixpkgs.overlays = lib.singleton (final: prev: { - kdePackages = - prev.kdePackages - // { - plasma-workspace = let - # the package we want to override - basePkg = prev.kdePackages.plasma-workspace; - - # a helper package that merges all the XDG_DATA_DIRS into a single directory - xdgdataPkg = pkgs.stdenv.mkDerivation { - name = "${basePkg.name}-xdgdata"; - buildInputs = [basePkg]; - dontUnpack = true; - dontFixup = true; - dontWrapQtApps = true; - installPhase = '' - mkdir -p $out/share - ( IFS=: - for DIR in $XDG_DATA_DIRS; do - if [[ -d "$DIR" ]]; then - cp -r $DIR/. $out/share/ - chmod -R u+w $out/share - fi - done - ) - ''; - }; - - # undo the XDG_DATA_DIRS injection that is usually done in the qt wrapper - # script and instead inject the path of the above helper package - derivedPkg = basePkg.overrideAttrs { - preFixup = '' - for index in "''${!qtWrapperArgs[@]}"; do - if [[ ''${qtWrapperArgs[$((index+0))]} == "--prefix" ]] && [[ ''${qtWrapperArgs[$((index+1))]} == "XDG_DATA_DIRS" ]]; then - unset -v "qtWrapperArgs[$((index+0))]" - unset -v "qtWrapperArgs[$((index+1))]" - unset -v "qtWrapperArgs[$((index+2))]" - unset -v "qtWrapperArgs[$((index+3))]" - fi - done - qtWrapperArgs=("''${qtWrapperArgs[@]}") - qtWrapperArgs+=(--prefix XDG_DATA_DIRS : "${xdgdataPkg}/share") - qtWrapperArgs+=(--prefix XDG_DATA_DIRS : "$out/share") - ''; - }; - in - derivedPkg; - }; - }); -} diff --git a/home/admin-jroeger.nix b/home/admin-jroeger.nix deleted file mode 100644 index 6dc6d51..0000000 --- a/home/admin-jroeger.nix +++ /dev/null @@ -1,51 +0,0 @@ -{lib, ...}: { - # Home Manager needs a bit of information about you and the paths it should - # manage. - home.username = "admin-jroeger"; - home.homeDirectory = "/home/admin-jroeger"; - - # hive modules - hive.kitty.enable = true; - hive.ranger.enable = true; - hive.yubikey.enable = true; - hive.yubikey.pinentry = "gnome3"; - hive.nix-scripts.enable = true; - hive.zsh.enable = true; - hive.doom.enable = true; - hive.doom.asDefaultEditor = true; - hive.doom.enableCopilot = true; - hive.doom.withNixPkgs = true; - hive.doom.withShellPkgs = true; - hive.doom.withCXXPkgs = true; - hive.doom.withPythonPkgs = true; - hive.jj.enable = true; - - # This value determines the Home Manager release that your configuration is - # compatible with. This helps avoid breakage when a new Home Manager release - # introduces backwards incompatible changes. - # - # You should not change this value, even if you update Home Manager. If you do - # want to update the value, then make sure to first check the Home Manager - # release notes. - home.stateVersion = "24.11"; # Please read the comment before changing. - - home.sessionVariables = { - EDITOR = lib.mkDefault "vim"; - }; - - # Let Home Manager install and manage itself. - programs.home-manager.enable = true; - - # Git - programs.difftastic.enable = true; - programs.difftastic.git.enable = true; - programs.git = { - enable = true; - settings.user.name = "Jonas Röger"; - settings.user.email = "jonas.kieran.roeger@iml.fraunhofer.de"; - signing = { - signByDefault = true; - key = "4000EB35E1AE0F07"; - }; - }; -} diff --git a/home/jonas@comfy-station.nix b/home/jonas@comfy-station.nix deleted file mode 100644 index e983cc9..0000000 --- a/home/jonas@comfy-station.nix +++ /dev/null @@ -1,105 +0,0 @@ -{ - config, - lib, - ... -}: { - imports = [ - (./. + "/jonas@comfy-station/" + /borg.nix) - ]; - - # Home Manager needs a bit of information about you and the paths it should - # manage. - home.username = "jonas"; - home.homeDirectory = "/home/jonas"; - - sops = { - age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt"; - }; - - # hive modules - hive.themes.layan.enable = true; - hive.themes.layan.pkgsInHome = true; - hive.hyprland.enable = true; - hive.swaync.enable = true; - hive.waybar.enable = true; - hive.wlogout.enable = true; - hive.wofi.enable = true; - hive.kitty.enable = true; - hive.nextcloud.enable = true; - hive.firefox = { - enable = true; - plasmaIntegration = true; - passFF = true; - }; - hive.kdeconnect.enable = true; - hive.ranger.enable = true; - hive.ssh = { - enable = true; - sopsFile = ../secrets/jonas/ssh.yaml; - keys = ["borg" "passgit"]; - }; - hive.yubikey.enable = true; - hive.yubikey.withCCID = false; - hive.zsh.enable = true; - hive.nix-scripts.enable = true; - hive.doom.enable = true; - hive.doom.asDefaultEditor = true; - hive.doom.enableCopilot = true; - hive.doom.withNixPkgs = true; - hive.doom.withShellPkgs = true; - hive.doom.withPythonPkgs = true; - hive.jj.enable = true; - - # Make session variables available in systemd units - # SEE: https://github.com/nix-community/home-manager/pull/5543 - # systemd.user.settings.Manager.DefaultEnvironment = - # lib.mapAttrs (_: lib.mkDefault) config.home.sessionVariables; - - xdg.mimeApps = { - enable = true; - - defaultApplications = { - "text/html" = "firefox.desktop"; - "x-scheme-handler/http" = "firefox.desktop"; - "x-scheme-handler/https" = "firefox.desktop"; - "x-scheme-handler/about" = "firefox.desktop"; - "x-scheme-handler/unknown" = "firefox.desktop"; - }; - }; - xdg.userDirs.enable = true; - xdg.userDirs.createDirectories = true; - xdg.userDirs.extraConfig = { - XDG_WORKSPACES_DIR = "${config.home.homeDirectory}/Workspaces"; - XDG_NEXTCLOUD_DIR = "${config.home.homeDirectory}/Nextcloud"; - XDG_NOTES_DIR = "${config.home.homeDirectory}/Notes"; - }; - - # This value determines the Home Manager release that your configuration is - # compatible with. This helps avoid breakage when a new Home Manager release - # introduces backwards incompatible changes. - # - # You should not change this value, even if you update Home Manager. If you do - # want to update the value, then make sure to first check the Home Manager - # release notes. - home.stateVersion = "24.11"; # Please read the comment before changing. - - home.sessionVariables = { - EDITOR = lib.mkDefault "vim"; - }; - - # Let Home Manager install and manage itself. - programs.home-manager.enable = true; - - # Git - programs.difftastic.enable = true; - programs.difftastic.git.enable = true; - programs.git = { - enable = true; - settings.user.name = "Jonas Röger"; - settings.user.email = "jonas.roeger@tu-dortmund.de"; - signing = { - signByDefault = true; - key = "4000EB35E1AE0F07"; - }; - }; -} diff --git a/home/jonas@comfy-station/borg.nix b/home/jonas@comfy-station/borg.nix deleted file mode 100644 index fb1fcfa..0000000 --- a/home/jonas@comfy-station/borg.nix +++ /dev/null @@ -1,131 +0,0 @@ -{config, ...}: let - defaultChecks = [ - { - name = "repository"; - frequency = "2 weeks"; - } - { - name = "archives"; - frequency = "4 weeks"; - } - { - name = "data"; - frequency = "6 weeks"; - } - { - name = "extract"; - frequency = "6 weeks"; - } - ]; - passwordFile = "${config.home.homeDirectory}/.config/borg/password"; - encCmd = ''cat ${passwordFile}''; - repo = "ssh://borg.jroeger.de/./comfy-station"; -in { - sops.secrets = { - "borg/password" = { - sopsFile = ../../secrets/jonas/borg.yaml; - key = "password"; - path = passwordFile; - }; - }; - - services.borgmatic.enable = true; - services.borgmatic.frequency = "hourly"; - - programs.borgmatic.enable = true; - programs.borgmatic.backups = { - workspaces = { - location = { - sourceDirectories = ["${config.xdg.userDirs.extraConfig.XDG_WORKSPACES_DIR}"]; - repositories = [repo]; - excludeHomeManagerSymlinks = true; - extraConfig = { - archive_name_format = "{hostname}-workspaces-{now}"; - exclude_patterns = [ - "*/.venv" - "__pycache__" - ]; - }; - }; - retention = { - keepDaily = 7; - keepHourly = 12; - keepWeekly = 4; - keepMonthly = 6; - }; - storage = { - encryptionPasscommand = encCmd; - }; - consistency.checks = defaultChecks; - }; - media = { - location = { - sourceDirectories = [ - "${config.xdg.userDirs.documents}" - "${config.xdg.userDirs.music}" - "${config.home.homeDirectory}/org" - "${config.home.homeDirectory}/Obsidian" - "${config.home.homeDirectory}/Zotero" - ]; - repositories = [repo]; - excludeHomeManagerSymlinks = true; - extraConfig = { - archive_name_format = "{hostname}-media-{now}"; - }; - }; - retention = { - keepDaily = 7; - keepWeekly = 2; - keepMonthly = 6; - }; - storage = { - encryptionPasscommand = encCmd; - }; - consistency.checks = defaultChecks; - }; - sec = { - location = { - sourceDirectories = [ - "${config.xdg.configHome}/sops" - "${config.home.homeDirectory}/Stuff/sec" - "${config.home.homeDirectory}/.password-store" - ]; - repositories = [repo]; - excludeHomeManagerSymlinks = true; - extraConfig = { - archive_name_format = "{hostname}-sec-{now}"; - }; - }; - retention = { - keepDaily = 7; - keepWeekly = 2; - keepMonthly = 6; - }; - storage = { - encryptionPasscommand = encCmd; - }; - consistency.checks = defaultChecks; - }; - var = { - location = { - sourceDirectories = [ - "${config.xdg.userDirs.desktop}" - ]; - repositories = [repo]; - excludeHomeManagerSymlinks = true; - extraConfig = { - archive_name_format = "{hostname}-var-{now}"; - }; - }; - retention = { - keepDaily = 7; - keepWeekly = 2; - keepMonthly = 6; - }; - storage = { - encryptionPasscommand = encCmd; - }; - consistency.checks = defaultChecks; - }; - }; -} diff --git a/home/jonas@harbor.nix b/home/jonas@harbor.nix deleted file mode 100644 index ce0b482..0000000 --- a/home/jonas@harbor.nix +++ /dev/null @@ -1,44 +0,0 @@ -{lib, ...}: { - # Home Manager needs a bit of information about you and the paths it should - # manage. - home.username = "jonas"; - home.homeDirectory = "/home/jonas"; - - # hive modules - hive.zsh.enable = true; - hive.nix-scripts.enable = true; - hive.ranger.enable = true; - hive.doom.enable = true; - hive.doom.asDefaultEditor = true; - hive.doom.withNixPkgs = true; - hive.doom.withShellPkgs = true; - - # This value determines the Home Manager release that your configuration is - # compatible with. This helps avoid breakage when a new Home Manager release - # introduces backwards incompatible changes. - # - # You should not change this value, even if you update Home Manager. If you do - # want to update the value, then make sure to first check the Home Manager - # release notes. - home.stateVersion = "24.11"; # Please read the comment before changing. - - home.sessionVariables = { - EDITOR = lib.mkDefault "vim"; - }; - - # Let Home Manager install and manage itself. - programs.home-manager.enable = true; - - # Git - programs.difftastic.enable = true; - programs.difftastic.git.enable = true; - programs.git = { - enable = true; - settings.user.name = "Jonas Röger"; - settings.user.email = "jonas.roeger@tu-dortmund.de"; - signing = { - signByDefault = true; - key = "4000EB35E1AE0F07"; - }; - }; -} diff --git a/home/jonas@monolith.nix b/home/jonas@monolith.nix deleted file mode 100644 index 0b2863a..0000000 --- a/home/jonas@monolith.nix +++ /dev/null @@ -1,105 +0,0 @@ -{ - config, - lib, - ... -}: rec { - # Home Manager needs a bit of information about you and the paths it should - # manage. - home.username = "jonas"; - home.homeDirectory = "/home/jonas"; - - sops = { - age.keyFile = "${home.homeDirectory}/.config/sops/age/keys.txt"; - }; - sops.secrets.gotifyDaemonToken = { - sopsFile = ../secrets/jonas/gotify.yaml; - key = "monolithDesktopToken"; - }; - sops.secrets.gotifyCLIToken = { - sopsFile = ../secrets/jonas/gotify.yaml; - key = "cliToken"; - }; - - # hive moduless - hive.doom.enable = true; - hive.doom.asDefaultEditor = true; - hive.doom.enableCopilot = false; - hive.doom.enableTidal = false; - hive.doom.withNixPkgs = true; - hive.doom.withShellPkgs = true; - hive.doom.withPythonPkgs = true; - hive.firefox = { - enable = true; - plasmaIntegration = false; - passFF = true; - }; - hive.kdeconnect.enable = false; - hive.kdeconnect.indicatorOnly = false; - hive.nextcloud.enable = false; # kwallet bug - hive.nix-scripts.enable = true; - hive.ranger.enable = true; - hive.themes.layan.enable = true; - hive.yubikey.enable = true; - hive.zsh.enable = true; - hive.jj.enable = true; - hive.gotify = { - cli.enable = true; - daemon.enable = true; - cli.tokenSopsKey = config.sops.secrets.gotifyCLIToken.name; - daemon.tokenSopsKey = config.sops.secrets.gotifyDaemonToken.name; - host = "gotify.jroeger.de"; - }; - - # Make session variables available in systemd units - # SEE: https://github.com/nix-community/home-manager/pull/5543 - # systemd.user.settings.Manager.DefaultEnvironment = - # lib.mapAttrs (_: lib.mkDefault) config.home.sessionVariables; - - xdg.mimeApps = { - enable = true; - - defaultApplications = { - "text/html" = "firefox.desktop"; - "x-scheme-handler/http" = "firefox.desktop"; - "x-scheme-handler/https" = "firefox.desktop"; - "x-scheme-handler/about" = "firefox.desktop"; - "x-scheme-handler/unknown" = "firefox.desktop"; - }; - }; - xdg.userDirs.enable = true; - xdg.userDirs.createDirectories = true; - xdg.userDirs.extraConfig = { - XDG_WORKSPACES_DIR = "${config.home.homeDirectory}/Workspaces"; - XDG_NEXTCLOUD_DIR = "${config.home.homeDirectory}/Nextcloud"; - XDG_NOTES_DIR = "${config.home.homeDirectory}/Notes"; - }; - - # This value determines the Home Manager release that your configuration is - # compatible with. This helps avoid breakage when a new Home Manager release - # introduces backwards incompatible changes. - # - # You should not change this value, even if you update Home Manager. If you do - # want to update the value, then make sure to first check the Home Manager - # release notes. - home.stateVersion = "24.11"; # Please read the comment before changing. - - home.sessionVariables = { - EDITOR = lib.mkDefault "vim"; - }; - - # Let Home Manager install and manage itself. - programs.home-manager.enable = true; - - # Git - programs.difftastic.enable = true; - programs.difftastic.git.enable = true; - programs.git = { - enable = true; - settings.user.name = "Jonas Röger"; - settings.user.email = "jonas.roeger@tu-dortmund.de"; - signing = { - signByDefault = true; - key = "4000EB35E1AE0F07"; - }; - }; -} diff --git a/overlays/unstable.nix b/overlays/unstable.nix deleted file mode 100644 index 3cb2730..0000000 --- a/overlays/unstable.nix +++ /dev/null @@ -1,8 +0,0 @@ -{inputs, ...}: { - flake.overlays.unstable = final: prev: { - unstable = import inputs.nixpkgs-unstable { - system = prev.system; - config.allowUnfree = true; - }; - }; -} diff --git a/packages/bulk-transcode/.envrc b/packages/bulk-transcode/.envrc deleted file mode 100644 index 7ee6560..0000000 --- a/packages/bulk-transcode/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake ../../#bulk-transcode --show-trace diff --git a/packages/bulk-transcode/bulk-transcode.sh b/packages/bulk-transcode/bulk-transcode.sh deleted file mode 100644 index b8c6d5b..0000000 --- a/packages/bulk-transcode/bulk-transcode.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env bash - -declare -rA presets=( - [davinci-resolve]="-c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p -c:a pcm_s16le" - [instagram]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)':flags=lanczos -r 30 -c:v libx264 -profile:v high -level 4.1 -pix_fmt yuv420p -preset slow -crf 18 -bf 2 -g 15 -keyint_min 15 -x264-params \"open-gop=0:cabac=1:b-pyramid=none\" -movflags +faststart -c:a aac -b:a 96k" - [insta-4k]="-r 30 -c:v libx264 -profile:v high -level 4.1 -pix_fmt yuv420p -preset slow -crf 18 -bf 2 -g 15 -keyint_min 15 -x264-params \"open-gop=0:cabac=1:b-pyramid=none\" -movflags +faststart -c:a aac -b:a 96k" - [storage-hevc]="-c:v libx265 -preset slower -crf 18 -pix_fmt yuv420p10le -x265-params aq-mode=3:aq-strength=1.0:psy-rd=1.8:psy-rdoq=1.0 -c:a copy" - [storage-av1]="-c:v libsvtav1 -preset 6 -crf 28 -pix_fmt yuv420p -g 240 -svtav1-params tune=0:aq-mode=2 -c:a copy" - [storage-av1-1080p]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -c:v libsvtav1 -preset 6 -crf 28 -pix_fmt yuv420p -g 240 -svtav1-params tune=0:aq-mode=2 -c:a copy" - [storage-av1-nvenc]="-c:v av1_nvenc -cq 28 -preset slow -pix_fmt yuv420p10le -c:a copy" - [network]="-c:v libx264 -preset slow -crf 22 -pix_fmt yuv420p -c:a aac -b:a 128k" - [network-1080p]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -c:v libx264 -preset slow -crf 22 -pix_fmt yuv420p -c:a aac -b:a 128k" - [whatsapp]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -c:v libx264 -preset slow -crf 30 -profile:v baseline -level 3.0 -pix_fmt yuv420p -r 25 -g 50 -c:a aac -b:a 160k -r:a 44100" -) - -declare -rA containers=( - [davinci-resolve]="mov" - [instagram]="mp4" - [insta-4k]="mp4" - [storage-hevc]="mkv" - [storage-av1]="mkv" - [storage-av1-1080p]="mkv" - [storage-av1-nvenc]="mkv" - [network]="mp4" - [network-1080p]="mp4" - [whatsapp]="mp4" -) - -where="${1:-.}" -dest="${2:-$where}" - -selection=$(find "$where" -type f | fzf --multi --preview 'ffprobe -v error -show_format -show_streams {}' --preview-window=up:wrap) - -preset=$( - printf '%s\n' "${!presets[@]}" | \ - fzf --multi --prompt "Select a preset" -) -flags="${presets[$preset]}" -container="${containers[$preset]}" - -output_dir=$(find "$dest" -type d ! -name '.*' ! -path '*/.*/*' | fzf --preview 'tree -C {}' --preview-window=up:wrap --prompt "Select output directory: ") - -if gum confirm "Flatten the directory structure?"; -then - flatten=true -else - flatten=false -fi - - -function transcode_job { - local ifile="$1" - local output_dir="$2" - local flatten="$3" - local where="$4" - local flags="$5" - local container="$6" - local fname=$(basename "$ifile") - local segment=$(realpath --relative-to="$where" "$ifile") - - - if [ "$flatten" = true ]; then - output_file="$output_dir/$fname.$container" - else - output_file="$output_dir/$segment.$container" - fi - - tmp_file=$(mktemp) - - echo "Running Command: ffmpeg -y -i $ifile $flags $output_file" >> "$tmp_file" - - mkdir -p "$(dirname "$output_file")" - - if ffmpeg -y -i "$ifile" $(echo -n "$flags") "$output_file" 2>> "$tmp_file"; - then - rm -f "$tmp_file" - else - # gum log "Failed to transcode $ifile. Check ./error.log for details." - cat "$tmp_file" >> error.log - rm -f "$tmp_file" - - fi -} -export -f transcode_job - -mapfile -t files <<< "$selection" -len=${#files[@]} -i=1 -for file in "${files[@]}"; do - if [[ -f "$file" ]]; then - gum spin --spinner dot --title "[$i/$len] Transcoding $file" -- bash -c "source <(declare -f transcode_job); transcode_job \"$file\" \"$output_dir\" \"$flatten\" \"$where\" \"$flags\" \"$container\"" - else - echo "Skipping invalid file: $file" >&2 - fi - ((i++)) -done diff --git a/packages/bulk-transcode/default.nix b/packages/bulk-transcode/default.nix deleted file mode 100644 index ec76987..0000000 --- a/packages/bulk-transcode/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ - flake.overlays.bulk-transcode = final: prev: { - bulk-transcode = import ./overlay.nix {inherit final prev;}; - }; - perSystem = {pkgs, ...}: { - packages.bulk-transcode = pkgs.callPackage ./derivation.nix {}; - devShells.bulk-transcode = import ./shell.nix {inherit pkgs;}; - }; -} diff --git a/packages/bulk-transcode/derivation.nix b/packages/bulk-transcode/derivation.nix deleted file mode 100644 index 1e1d8c0..0000000 --- a/packages/bulk-transcode/derivation.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - bash, - coreutils, - ffmpeg, - findutils, - fzf, - gum, - lib, - makeWrapper, - stdenv, - tree, - ... -}: -stdenv.mkDerivation (finalAttrs: { - name = "bulk-transcode"; - src = ./.; - - buildInputs = [ - bash - coreutils - ffmpeg - findutils - fzf - gum - makeWrapper - tree - ]; - - installPhase = '' - install -Dm755 bulk-transcode.sh $out/bin/bulk-transcode - - wrapProgram $out/bin/bulk-transcode \ - --set PATH "${lib.makeBinPath finalAttrs.buildInputs}" - ''; -}) diff --git a/packages/bulk-transcode/shell.nix b/packages/bulk-transcode/shell.nix deleted file mode 100644 index d1ee79e..0000000 --- a/packages/bulk-transcode/shell.nix +++ /dev/null @@ -1,7 +0,0 @@ -{pkgs ? import {}}: let - bin = pkgs.callPackage ./derivation.nix {}; -in - pkgs.mkShell { - name = "bulk-transcode"; - inputsFrom = [bin]; - } diff --git a/packages/crossover.nix b/packages/crossover.nix deleted file mode 100644 index d9185d0..0000000 --- a/packages/crossover.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ - appimageTools, - fetchurl, - makeWrapper, - ... -}: let - pname = "crossover"; - version = "3.1.5"; - src = fetchurl { - url = "https://github.com/lacymorrow/crossover/releases/download/v${version}/CrossOver-${version}-x86_64.AppImage"; - sha256 = "sha256-64RPal8n1PJh1LB+CTyNFt04Pw1lVgcsyc63S8yQ/DA="; - }; - appimageContents = appimageTools.extract { - inherit pname version src; - }; -in - appimageTools.wrapType2 { - inherit pname version src; - - nativeBuildInputs = [makeWrapper]; - extraInstallCommands = '' - wrapProgram $out/bin/${pname} --add-flags "--no-sandbox" - - # Create a minimal .desktop file manually - mkdir -p $out/share/applications - cat > $out/share/applications/${pname}.desktop < {}}: -pkgs.callPackage ./derivation.nix {} diff --git a/packages/spotify-shortcuts/derivation.nix b/packages/spotify-shortcuts/derivation.nix deleted file mode 100644 index 4bfa123..0000000 --- a/packages/spotify-shortcuts/derivation.nix +++ /dev/null @@ -1,9 +0,0 @@ -{python3Packages}: -with python3Packages; - buildPythonApplication { - name = "spotify-shortcuts"; - propagatedBuildInputs = [spotipy pyxdg desktop-notifier]; - pyproject = true; - build-system = [setuptools]; - src = ./.; - } diff --git a/packages/spotify-shortcuts/setup.py b/packages/spotify-shortcuts/setup.py deleted file mode 100644 index 474c0fe..0000000 --- a/packages/spotify-shortcuts/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup, find_packages - -setup( - name="spotify_shortcuts", - version="1.0", - 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/packages/spotify-shortcuts/shell.nix b/packages/spotify-shortcuts/shell.nix deleted file mode 100644 index a863d83..0000000 --- a/packages/spotify-shortcuts/shell.nix +++ /dev/null @@ -1,15 +0,0 @@ -{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/packages/spotify-shortcuts/spotify_shortcuts/__init__.py b/packages/spotify-shortcuts/spotify_shortcuts/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/packages/spotify-shortcuts/spotify_shortcuts/__main__.py b/packages/spotify-shortcuts/spotify_shortcuts/__main__.py deleted file mode 100644 index 8f3c09e..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/__main__.py +++ /dev/null @@ -1,4 +0,0 @@ -from spotify_shortcuts.run import main - -if __name__ == "__main__": - main() diff --git a/packages/spotify-shortcuts/spotify_shortcuts/config.py b/packages/spotify-shortcuts/spotify_shortcuts/config.py deleted file mode 100644 index 69901e1..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/config.py +++ /dev/null @@ -1,74 +0,0 @@ -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 -from json import loads - - -@dataclass -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): - 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") - 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", - ) - 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 := 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/packages/spotify-shortcuts/spotify_shortcuts/registry.py b/packages/spotify-shortcuts/spotify_shortcuts/registry.py deleted file mode 100644 index 7e6f694..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/registry.py +++ /dev/null @@ -1,7 +0,0 @@ -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/packages/spotify-shortcuts/spotify_shortcuts/run.py b/packages/spotify-shortcuts/spotify_shortcuts/run.py deleted file mode 100644 index 423ff6a..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/run.py +++ /dev/null @@ -1,47 +0,0 @@ -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/packages/spotify-shortcuts/spotify_shortcuts/shortcut.py b/packages/spotify-shortcuts/spotify_shortcuts/shortcut.py deleted file mode 100644 index e8d871b..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/shortcut.py +++ /dev/null @@ -1,21 +0,0 @@ -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 diff --git a/packages/spotify-shortcuts/spotify_shortcuts/spotify_auth.py b/packages/spotify-shortcuts/spotify_shortcuts/spotify_auth.py deleted file mode 100644 index f4f6574..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/spotify_auth.py +++ /dev/null @@ -1,20 +0,0 @@ -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, scopes: list[str]) -> 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=CALLBACK_URI, - scope=" ".join(scopes), - cache_path=cfg.cache_file, - ) - ) diff --git a/packages/spotify-shortcuts/spotify_shortcuts/spotify_like.py b/packages/spotify-shortcuts/spotify_shortcuts/spotify_like.py deleted file mode 100644 index 32787ce..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/spotify_like.py +++ /dev/null @@ -1,46 +0,0 @@ -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(): - run_shortcut(SpotifyLike(), load_config()) - - -if __name__ == "__main__": - main() diff --git a/packages/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py b/packages/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py deleted file mode 100644 index 63d5426..0000000 --- a/packages/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py +++ /dev/null @@ -1,57 +0,0 @@ -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(): - run_shortcut(SpotifyPlAdd(), load_config()) - - -if __name__ == "__main__": - main() diff --git a/pkgs/bulk-transcode/.envrc b/pkgs/bulk-transcode/.envrc deleted file mode 100644 index 7ee6560..0000000 --- a/pkgs/bulk-transcode/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake ../../#bulk-transcode --show-trace diff --git a/pkgs/bulk-transcode/bulk-transcode.sh b/pkgs/bulk-transcode/bulk-transcode.sh deleted file mode 100644 index b8c6d5b..0000000 --- a/pkgs/bulk-transcode/bulk-transcode.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env bash - -declare -rA presets=( - [davinci-resolve]="-c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p -c:a pcm_s16le" - [instagram]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)':flags=lanczos -r 30 -c:v libx264 -profile:v high -level 4.1 -pix_fmt yuv420p -preset slow -crf 18 -bf 2 -g 15 -keyint_min 15 -x264-params \"open-gop=0:cabac=1:b-pyramid=none\" -movflags +faststart -c:a aac -b:a 96k" - [insta-4k]="-r 30 -c:v libx264 -profile:v high -level 4.1 -pix_fmt yuv420p -preset slow -crf 18 -bf 2 -g 15 -keyint_min 15 -x264-params \"open-gop=0:cabac=1:b-pyramid=none\" -movflags +faststart -c:a aac -b:a 96k" - [storage-hevc]="-c:v libx265 -preset slower -crf 18 -pix_fmt yuv420p10le -x265-params aq-mode=3:aq-strength=1.0:psy-rd=1.8:psy-rdoq=1.0 -c:a copy" - [storage-av1]="-c:v libsvtav1 -preset 6 -crf 28 -pix_fmt yuv420p -g 240 -svtav1-params tune=0:aq-mode=2 -c:a copy" - [storage-av1-1080p]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -c:v libsvtav1 -preset 6 -crf 28 -pix_fmt yuv420p -g 240 -svtav1-params tune=0:aq-mode=2 -c:a copy" - [storage-av1-nvenc]="-c:v av1_nvenc -cq 28 -preset slow -pix_fmt yuv420p10le -c:a copy" - [network]="-c:v libx264 -preset slow -crf 22 -pix_fmt yuv420p -c:a aac -b:a 128k" - [network-1080p]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -c:v libx264 -preset slow -crf 22 -pix_fmt yuv420p -c:a aac -b:a 128k" - [whatsapp]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -c:v libx264 -preset slow -crf 30 -profile:v baseline -level 3.0 -pix_fmt yuv420p -r 25 -g 50 -c:a aac -b:a 160k -r:a 44100" -) - -declare -rA containers=( - [davinci-resolve]="mov" - [instagram]="mp4" - [insta-4k]="mp4" - [storage-hevc]="mkv" - [storage-av1]="mkv" - [storage-av1-1080p]="mkv" - [storage-av1-nvenc]="mkv" - [network]="mp4" - [network-1080p]="mp4" - [whatsapp]="mp4" -) - -where="${1:-.}" -dest="${2:-$where}" - -selection=$(find "$where" -type f | fzf --multi --preview 'ffprobe -v error -show_format -show_streams {}' --preview-window=up:wrap) - -preset=$( - printf '%s\n' "${!presets[@]}" | \ - fzf --multi --prompt "Select a preset" -) -flags="${presets[$preset]}" -container="${containers[$preset]}" - -output_dir=$(find "$dest" -type d ! -name '.*' ! -path '*/.*/*' | fzf --preview 'tree -C {}' --preview-window=up:wrap --prompt "Select output directory: ") - -if gum confirm "Flatten the directory structure?"; -then - flatten=true -else - flatten=false -fi - - -function transcode_job { - local ifile="$1" - local output_dir="$2" - local flatten="$3" - local where="$4" - local flags="$5" - local container="$6" - local fname=$(basename "$ifile") - local segment=$(realpath --relative-to="$where" "$ifile") - - - if [ "$flatten" = true ]; then - output_file="$output_dir/$fname.$container" - else - output_file="$output_dir/$segment.$container" - fi - - tmp_file=$(mktemp) - - echo "Running Command: ffmpeg -y -i $ifile $flags $output_file" >> "$tmp_file" - - mkdir -p "$(dirname "$output_file")" - - if ffmpeg -y -i "$ifile" $(echo -n "$flags") "$output_file" 2>> "$tmp_file"; - then - rm -f "$tmp_file" - else - # gum log "Failed to transcode $ifile. Check ./error.log for details." - cat "$tmp_file" >> error.log - rm -f "$tmp_file" - - fi -} -export -f transcode_job - -mapfile -t files <<< "$selection" -len=${#files[@]} -i=1 -for file in "${files[@]}"; do - if [[ -f "$file" ]]; then - gum spin --spinner dot --title "[$i/$len] Transcoding $file" -- bash -c "source <(declare -f transcode_job); transcode_job \"$file\" \"$output_dir\" \"$flatten\" \"$where\" \"$flags\" \"$container\"" - else - echo "Skipping invalid file: $file" >&2 - fi - ((i++)) -done diff --git a/pkgs/bulk-transcode/default.nix b/pkgs/bulk-transcode/default.nix deleted file mode 100644 index 1e1d8c0..0000000 --- a/pkgs/bulk-transcode/default.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - bash, - coreutils, - ffmpeg, - findutils, - fzf, - gum, - lib, - makeWrapper, - stdenv, - tree, - ... -}: -stdenv.mkDerivation (finalAttrs: { - name = "bulk-transcode"; - src = ./.; - - buildInputs = [ - bash - coreutils - ffmpeg - findutils - fzf - gum - makeWrapper - tree - ]; - - installPhase = '' - install -Dm755 bulk-transcode.sh $out/bin/bulk-transcode - - wrapProgram $out/bin/bulk-transcode \ - --set PATH "${lib.makeBinPath finalAttrs.buildInputs}" - ''; -}) diff --git a/pkgs/bulk-transcode/shell.nix b/pkgs/bulk-transcode/shell.nix deleted file mode 100644 index 327a200..0000000 --- a/pkgs/bulk-transcode/shell.nix +++ /dev/null @@ -1,7 +0,0 @@ -{pkgs ? import {}}: let - bin = pkgs.callPackage ./default.nix {}; -in - pkgs.mkShell { - name = "bulk-transcode"; - inputsFrom = [bin]; - } diff --git a/pkgs/crossover.nix b/pkgs/crossover.nix deleted file mode 100644 index d9185d0..0000000 --- a/pkgs/crossover.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ - appimageTools, - fetchurl, - makeWrapper, - ... -}: let - pname = "crossover"; - version = "3.1.5"; - src = fetchurl { - url = "https://github.com/lacymorrow/crossover/releases/download/v${version}/CrossOver-${version}-x86_64.AppImage"; - sha256 = "sha256-64RPal8n1PJh1LB+CTyNFt04Pw1lVgcsyc63S8yQ/DA="; - }; - appimageContents = appimageTools.extract { - inherit pname version src; - }; -in - appimageTools.wrapType2 { - inherit pname version src; - - nativeBuildInputs = [makeWrapper]; - extraInstallCommands = '' - wrapProgram $out/bin/${pname} --add-flags "--no-sandbox" - - # Create a minimal .desktop file manually - mkdir -p $out/share/applications - cat > $out/share/applications/${pname}.desktop < {}}: -pkgs.callPackage ./derivation.nix {} diff --git a/pkgs/spotify-shortcuts/derivation.nix b/pkgs/spotify-shortcuts/derivation.nix deleted file mode 100644 index 4bfa123..0000000 --- a/pkgs/spotify-shortcuts/derivation.nix +++ /dev/null @@ -1,9 +0,0 @@ -{python3Packages}: -with python3Packages; - buildPythonApplication { - name = "spotify-shortcuts"; - propagatedBuildInputs = [spotipy pyxdg desktop-notifier]; - pyproject = true; - build-system = [setuptools]; - src = ./.; - } diff --git a/pkgs/spotify-shortcuts/setup.py b/pkgs/spotify-shortcuts/setup.py deleted file mode 100644 index 474c0fe..0000000 --- a/pkgs/spotify-shortcuts/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup, find_packages - -setup( - name="spotify_shortcuts", - version="1.0", - 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/shell.nix b/pkgs/spotify-shortcuts/shell.nix deleted file mode 100644 index a863d83..0000000 --- a/pkgs/spotify-shortcuts/shell.nix +++ /dev/null @@ -1,15 +0,0 @@ -{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/__init__.py b/pkgs/spotify-shortcuts/spotify_shortcuts/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/__main__.py b/pkgs/spotify-shortcuts/spotify_shortcuts/__main__.py deleted file mode 100644 index 8f3c09e..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/__main__.py +++ /dev/null @@ -1,4 +0,0 @@ -from spotify_shortcuts.run import main - -if __name__ == "__main__": - main() diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/config.py b/pkgs/spotify-shortcuts/spotify_shortcuts/config.py deleted file mode 100644 index 69901e1..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/config.py +++ /dev/null @@ -1,74 +0,0 @@ -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 -from json import loads - - -@dataclass -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): - 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") - 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", - ) - 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 := 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/registry.py b/pkgs/spotify-shortcuts/spotify_shortcuts/registry.py deleted file mode 100644 index 7e6f694..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/registry.py +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index 423ff6a..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/run.py +++ /dev/null @@ -1,47 +0,0 @@ -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 deleted file mode 100644 index e8d871b..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/shortcut.py +++ /dev/null @@ -1,21 +0,0 @@ -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 diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py deleted file mode 100644 index f4f6574..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_auth.py +++ /dev/null @@ -1,20 +0,0 @@ -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, scopes: list[str]) -> 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=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 deleted file mode 100644 index 32787ce..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_like.py +++ /dev/null @@ -1,46 +0,0 @@ -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(): - run_shortcut(SpotifyLike(), load_config()) - - -if __name__ == "__main__": - main() diff --git a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py b/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py deleted file mode 100644 index 63d5426..0000000 --- a/pkgs/spotify-shortcuts/spotify_shortcuts/spotify_pl_add.py +++ /dev/null @@ -1,57 +0,0 @@ -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(): - run_shortcut(SpotifyPlAdd(), load_config()) - - -if __name__ == "__main__": - main() diff --git a/static/keys/borg-jonas@comfy-station.pub b/static/keys/borg-jonas@comfy-station.pub deleted file mode 100644 index e286cb7..0000000 --- a/static/keys/borg-jonas@comfy-station.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNYmQ4HspLsunLyryI/ZbX4tTuRI6cRv0n/ai6+DNCc borg@jroeger.de diff --git a/static/keys/my_pub.asc b/static/keys/my_pub.asc deleted file mode 100644 index 3eecce5..0000000 --- a/static/keys/my_pub.asc +++ /dev/null @@ -1,448 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Comment: Hostname: -Version: Hockeypuck 2.1.1-10-gec3b0e7 - -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 -=JVtR ------END PGP PUBLIC KEY BLOCK----- diff --git a/static/keys/passgit-jonas@comfy-station.pub b/static/keys/passgit-jonas@comfy-station.pub deleted file mode 100644 index a16c7c6..0000000 --- a/static/keys/passgit-jonas@comfy-station.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBodNTvEGT2J+w6qpJNvmwZuHCshzq2nwU92+VqRcyn4 jonas@comfy-station diff --git a/static/wallpaper/nord.png b/static/wallpaper/nord.png deleted file mode 100644 index 464e50e..0000000 Binary files a/static/wallpaper/nord.png and /dev/null differ diff --git a/static/wallpaper/stones.jpg b/static/wallpaper/stones.jpg deleted file mode 100644 index 1e199ca..0000000 Binary files a/static/wallpaper/stones.jpg and /dev/null differ diff --git a/templates/cmake-c/.gitignore b/templates/cmake-c/.gitignore deleted file mode 100644 index 378eac2..0000000 --- a/templates/cmake-c/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/templates/cmake-c/CMakeLists.txt b/templates/cmake-c/CMakeLists.txt deleted file mode 100644 index 1f0e64f..0000000 --- a/templates/cmake-c/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.15) - -project(Hello - DESCRIPTION "Hello World" - LANGUAGES C -) - -add_executable(hello src/main.c) - -install(TARGETS hello) diff --git a/templates/cmake-c/flake.nix b/templates/cmake-c/flake.nix deleted file mode 100644 index 1a56dc3..0000000 --- a/templates/cmake-c/flake.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ - description = "Cmake C Flake"; - - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - }; - - outputs = inputs @ { - self, - flake-parts, - ... - }: - flake-parts.lib.mkFlake {inherit inputs;} ( - top: { - imports = []; - - flake = { - overlays.default = final: prev: { - my-derivation = final.callPackage ./nix/derivation.nix {}; - }; - }; - - systems = [ - "x86_64-linux" - ]; - - perSystem = { - self', - pkgs, - system, - ... - }: { - _module.args.pkgs = import inputs.nixpkgs { - inherit system; - overlays = [self.overlays.default]; - }; - - packages.default = pkgs.my-derivation; - - devShells.default = pkgs.mkShell { - packages = [ - pkgs.cmake-language-server - pkgs.cmake-format - pkgs.clang-tools - pkgs.gdb - ]; - inputsFrom = [self'.packages.default]; - shellHook = '' - export CMAKE_EXPORT_COMPILE_COMMANDS=ON - ''; - }; - }; - } - ); -} diff --git a/templates/cmake-c/nix/derivation.nix b/templates/cmake-c/nix/derivation.nix deleted file mode 100644 index c1d08b8..0000000 --- a/templates/cmake-c/nix/derivation.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - cmake, - stdenv, - ... -}: -stdenv.mkDerivation (finalAttrs: { - pname = "my-derivation"; - version = "0.1.0"; - src = ../.; - nativeBuildInputs = [cmake]; - buildInputs = []; - - meta = { - description = "Hello World Binary"; - mainProgram = "hello"; - }; -}) diff --git a/templates/cmake-c/src/main.c b/templates/cmake-c/src/main.c deleted file mode 100644 index 39ccd04..0000000 --- a/templates/cmake-c/src/main.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() { - puts("Hello, Flake!"); - return 0; -} diff --git a/templates/rust/.envrc b/templates/rust/.envrc deleted file mode 100644 index 412cbef..0000000 --- a/templates/rust/.envrc +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# ^ make editor happy - -# -# Use https://direnv.net/ to automatically load the dev shell. -# - -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi - -watch_file nix/** -watch_file -- **/*.nix -# Adding files to git includes them in a flake -# But it is also a bit much reloading. -# watch_file .git/index .git/HEAD -use flake . --show-trace diff --git a/templates/rust/.gitignore b/templates/rust/.gitignore deleted file mode 100644 index 80c4fce..0000000 --- a/templates/rust/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.direnv/ -target/ -result/ diff --git a/templates/rust/Cargo.toml b/templates/rust/Cargo.toml deleted file mode 100644 index 9322e5e..0000000 --- a/templates/rust/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "hello" -description = "A test rust binary" -publish = false -version = "0.1.0" - -edition = "2021" - -[[bin]] -name = "hello" -path = "src/main.rs" diff --git a/templates/rust/flake.nix b/templates/rust/flake.nix deleted file mode 100644 index 2d1b81a..0000000 --- a/templates/rust/flake.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - description = "Rust-Hello"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - flake-utils.url = "github:numtide/flake-utils"; - crate2nix = { - url = "github:nix-community/crate2nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - outputs = inputs @ { - crate2nix, - flake-utils, - nixpkgs, - rust-overlay, - ... - }: - flake-utils.lib.eachDefaultSystem ( - system: let - # Overlay pkgs with rust-bin - overlays = [(import rust-overlay)]; - pkgs = import nixpkgs { - inherit system overlays; - }; - - # Use rust-bin to generate the toolchain from rust-toolchain.toml - rust-toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; - - buildRustCrateForPkgs = _: - pkgs.buildRustCrate.override { - rustc = rust-toolchain; # Use rustc from toolchain - cargo = rust-toolchain; # Use cargo from toolchain - }; - - # Cargo.nix for IFD - generatedCargoNix = crate2nix.tools.${system}.generatedCargoNix { - name = "rustnix"; - src = ./.; - }; - - cargoNix = import generatedCargoNix { - inherit pkgs buildRustCrateForPkgs; - }; - in { - packages = rec { - hello = cargoNix.rootCrate.build; - default = hello; - }; - - devShell = pkgs.mkShell { - buildInputs = [rust-toolchain]; - }; - } - ); -} diff --git a/templates/rust/rust-toolchain.toml b/templates/rust/rust-toolchain.toml deleted file mode 100644 index 535db1f..0000000 --- a/templates/rust/rust-toolchain.toml +++ /dev/null @@ -1,3 +0,0 @@ -[toolchain] -channel = "1.85.0" -components = [ "rustfmt", "rustc-dev", "rust-analyzer", "rust-src"] diff --git a/templates/rust/src/main.rs b/templates/rust/src/main.rs deleted file mode 100644 index ea5b5d8..0000000 --- a/templates/rust/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("{}", "Hello, world!"); -}