2022-09-07 22:33:02 +02:00
|
|
|
{
|
2023-07-10 05:09:43 +02:00
|
|
|
config,
|
2022-09-07 22:33:02 +02:00
|
|
|
lib,
|
|
|
|
pkgs,
|
2022-09-10 21:19:32 +02:00
|
|
|
homeage,
|
2022-09-07 22:33:02 +02:00
|
|
|
...
|
2022-12-03 20:41:37 +01:00
|
|
|
}: let
|
|
|
|
hostName = "surtur";
|
|
|
|
in {
|
2022-09-06 17:50:26 +02:00
|
|
|
home.username = "$USER";
|
2022-12-03 20:41:37 +01:00
|
|
|
home.sessionVariables.HOSTNAME = "${hostName}";
|
2022-09-06 17:50:26 +02:00
|
|
|
home.homeDirectory = "/home/$USER";
|
2023-08-03 11:50:06 +02:00
|
|
|
home.stateVersion = "23.11";
|
2022-09-06 17:51:26 +02:00
|
|
|
|
2023-08-03 11:45:47 +02:00
|
|
|
# build configuration and switch:
|
|
|
|
# ➜ home-manager switch --no-out-link -b backup --flake~/utils/dotfiles#$HOST
|
|
|
|
|
|
|
|
# alternatively, install HM with:
|
|
|
|
# nix profile install --priority 0 home-manager
|
|
|
|
# hit the issue described here, waiting until resolved:
|
|
|
|
# https://github.com/nix-community/home-manager/issues/2848
|
|
|
|
programs.home-manager.enable = true;
|
|
|
|
|
2023-08-02 12:58:21 +02:00
|
|
|
home.packages = with pkgs; [
|
2023-08-03 11:46:14 +02:00
|
|
|
direnv
|
|
|
|
# lorri and arion are apparently provided by cachix#devenv
|
2023-08-02 12:58:21 +02:00
|
|
|
alejandra
|
|
|
|
statix
|
2023-08-03 11:46:14 +02:00
|
|
|
niv
|
|
|
|
rnix-lsp
|
2023-08-02 12:58:21 +02:00
|
|
|
duf
|
|
|
|
dua
|
|
|
|
du-dust
|
|
|
|
zellij
|
|
|
|
cloak
|
|
|
|
headscale
|
|
|
|
btop
|
|
|
|
sops
|
2023-08-03 11:46:53 +02:00
|
|
|
neovim
|
2023-08-03 11:46:14 +02:00
|
|
|
ccache
|
2023-08-02 12:58:21 +02:00
|
|
|
];
|
|
|
|
|
2022-09-10 21:19:32 +02:00
|
|
|
homeage = {
|
|
|
|
# Absolute path to identity (created not through home-manager)
|
|
|
|
identityPaths = [
|
|
|
|
"~/.ssh/theEd"
|
|
|
|
];
|
|
|
|
|
|
|
|
# "activation" if system doesn't support systemd
|
2023-07-10 03:43:00 +02:00
|
|
|
installationType = "systemd";
|
2022-09-10 21:19:32 +02:00
|
|
|
|
|
|
|
file."sops-age-keys.txt" = {
|
|
|
|
# Path to encrypted file tracked by the git repository
|
|
|
|
source = ./secrets/sops-keys.age;
|
|
|
|
# can be "copies" or "symlink"
|
|
|
|
symlinks = [".config/sops/age/keys.txt"];
|
|
|
|
};
|
2023-07-10 03:40:02 +02:00
|
|
|
|
|
|
|
file."envs" = {
|
|
|
|
source = ./secrets/envs.age;
|
|
|
|
};
|
|
|
|
|
|
|
|
# infra secrets.
|
|
|
|
file."infra-backend" = {
|
|
|
|
source = ./secrets/infra-backend.age;
|
|
|
|
};
|
|
|
|
file."infra-vars" = {
|
|
|
|
source = ./secrets/infra-vars.age;
|
|
|
|
};
|
2023-08-05 16:07:27 +02:00
|
|
|
|
|
|
|
file."pcmt_gitea_token" = {
|
|
|
|
source = ./secrets/pcmt_gitea_token.age;
|
|
|
|
};
|
2022-09-10 21:19:32 +02:00
|
|
|
};
|
|
|
|
|
2022-09-01 22:23:39 +02:00
|
|
|
|
2022-09-02 23:42:00 +02:00
|
|
|
imports = [
|
2022-09-05 23:29:36 +02:00
|
|
|
./nix/programs.nix
|
2022-09-02 23:42:00 +02:00
|
|
|
];
|
|
|
|
|
2022-09-02 18:01:13 +02:00
|
|
|
home.file = {
|
2022-09-02 23:12:22 +02:00
|
|
|
".config/kitty/kitty.conf" = {
|
|
|
|
source = .config/kitty/kitty.conf;
|
|
|
|
};
|
|
|
|
|
2023-07-10 00:38:37 +02:00
|
|
|
".vimrc" = {
|
|
|
|
source = ./.vim/vimrc;
|
|
|
|
};
|
2022-12-03 20:41:37 +01:00
|
|
|
".vim/deoplete.vimrc.vim" = {
|
|
|
|
source = ./.vim/deoplete.vimrc.vim;
|
|
|
|
};
|
|
|
|
".vim/gotags.vimrc.vim" = {
|
|
|
|
source = ./.vim/gotags.vimrc.vim;
|
|
|
|
};
|
2023-07-10 00:38:37 +02:00
|
|
|
".vim/python.vimrc.vim" = {
|
|
|
|
source = ./.vim/python.vimrc.vim;
|
|
|
|
};
|
2022-12-03 20:41:37 +01:00
|
|
|
|
2023-08-03 11:46:53 +02:00
|
|
|
".config/nvim/init.vim" = {
|
|
|
|
source = ./.config/nvim/init.vim;
|
|
|
|
};
|
|
|
|
|
2023-07-10 04:18:04 +02:00
|
|
|
".config/sway/config" = {
|
|
|
|
source = ./.config/sway/config;
|
|
|
|
};
|
|
|
|
".config/sway/env" = {
|
|
|
|
source = ./.config/sway/env;
|
|
|
|
};
|
|
|
|
".config/sway/inputs" = {
|
|
|
|
source = ./.config/sway/inputs;
|
|
|
|
};
|
2023-07-10 05:09:43 +02:00
|
|
|
".config/sway/config.d/dracula.sway" = {
|
|
|
|
source = ./.config/sway/config.d/dracula.sway;
|
|
|
|
};
|
2023-07-10 04:18:04 +02:00
|
|
|
".config/waybar/config" = {
|
|
|
|
source = ./.config/waybar/config;
|
|
|
|
};
|
|
|
|
".config/waybar/style.css" = {
|
|
|
|
source = ./.config/waybar/style.css;
|
|
|
|
};
|
|
|
|
".config/waybar/modules/storage.sh" = {
|
|
|
|
source = ./.config/waybar/modules/storage.sh;
|
|
|
|
};
|
|
|
|
".config/kanshi/config" = {
|
|
|
|
source = ./.config/kanshi/config;
|
|
|
|
};
|
|
|
|
".config/mako/config" = {
|
|
|
|
source = ./.config/mako/config;
|
|
|
|
};
|
|
|
|
".local/bin/swws.py" = {
|
|
|
|
source = ./bin/swws.py;
|
|
|
|
};
|
|
|
|
".local/bin/sway-locker" = {
|
|
|
|
source = ./bin/sway-locker;
|
|
|
|
};
|
|
|
|
|
2023-08-03 12:09:17 +02:00
|
|
|
".config/direnv/direnv.toml" = {
|
|
|
|
source = ./.config/direnv/direnv.toml;
|
|
|
|
};
|
|
|
|
|
2022-12-03 20:41:37 +01:00
|
|
|
".config/fusuma/config-wl.yml" = {
|
|
|
|
source = ./.config/fusuma/config-wl.yml;
|
|
|
|
};
|
|
|
|
".config/fusuma/config.yml" = {
|
|
|
|
source = ./.config/fusuma/config.yml;
|
|
|
|
};
|
|
|
|
|
2023-07-10 04:27:55 +02:00
|
|
|
".config/git/config-common" = {
|
|
|
|
source = ./.config/git/config;
|
|
|
|
};
|
|
|
|
# host-specific gitconfig.
|
|
|
|
".config/git/config.${hostName}" = {
|
|
|
|
text = ''
|
|
|
|
[user]
|
|
|
|
name = ${hostName}
|
|
|
|
email = wanderer@dotya.ml
|
|
|
|
signingkey = ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
".config/git/config" = {
|
|
|
|
text = ''
|
|
|
|
[include]
|
|
|
|
path = ~/.config/git/config-common
|
|
|
|
[include]
|
|
|
|
path = ~/.config/git/config.${hostName}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
".config/git/allowed_signers" = {
|
|
|
|
source = ./.config/git/allowed_signers;
|
|
|
|
};
|
|
|
|
|
2022-09-07 22:33:02 +02:00
|
|
|
# begin zsh-related.
|
2023-07-10 05:37:57 +02:00
|
|
|
".zshrc" = {
|
|
|
|
source = ./.zshrc;
|
|
|
|
};
|
2022-09-07 22:33:02 +02:00
|
|
|
".zshenv" = {
|
|
|
|
source = ./.zshenv;
|
|
|
|
};
|
2023-07-10 05:37:57 +02:00
|
|
|
".zprofile" = {
|
|
|
|
source = ./.zprofile;
|
|
|
|
};
|
2022-12-03 20:41:37 +01:00
|
|
|
".zsh" = {
|
|
|
|
source = ./.zsh;
|
|
|
|
recursive = true;
|
2022-09-07 22:33:02 +02:00
|
|
|
};
|
2022-12-03 20:41:37 +01:00
|
|
|
".zsh/bemenu-dracula" = {
|
|
|
|
source = pkgs.fetchFromGitHub {
|
|
|
|
owner = "dracula";
|
|
|
|
repo = "bemenu";
|
|
|
|
rev = "9b1165b3d97e3b2a74c6ce220781b78d8a11febf";
|
|
|
|
sha256 = "sha256-TwfkEZ1aTkHur+jCqRsaqvzOw6qpH0L4pvYqkx7iCDk=";
|
|
|
|
};
|
2022-09-07 22:33:02 +02:00
|
|
|
};
|
|
|
|
# end zsh-related.
|
|
|
|
|
2022-09-16 12:58:46 +02:00
|
|
|
".cargo/config.toml" = {
|
|
|
|
source = .cargo/config.toml;
|
|
|
|
};
|
|
|
|
|
2023-07-10 04:35:03 +02:00
|
|
|
".npmrc" = {
|
|
|
|
text = ''
|
|
|
|
prefix=''${HOME}/.npm-packages
|
|
|
|
audit=false
|
|
|
|
fund=false
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2022-09-15 11:34:51 +02:00
|
|
|
".config/swaylock/config" = {
|
|
|
|
source = .config/swaylock/config;
|
2022-09-09 20:59:43 +02:00
|
|
|
};
|
2022-09-09 21:02:19 +02:00
|
|
|
".config/tridactyl/tridactylrc" = {
|
|
|
|
source = .config/tridactyl/tridactylrc;
|
|
|
|
};
|
2022-09-09 20:59:43 +02:00
|
|
|
|
2023-07-10 04:35:03 +02:00
|
|
|
".config/bat/config" = {
|
|
|
|
source = .config/bat/config;
|
|
|
|
};
|
|
|
|
|
|
|
|
".ncpamixer.conf" = {
|
|
|
|
source = .config/ncpamixer.conf;
|
|
|
|
};
|
|
|
|
|
|
|
|
".gdbinit" = {
|
|
|
|
text = ''
|
|
|
|
set auto-load safe-path /nix/store
|
|
|
|
set history save on
|
|
|
|
set history size 10000
|
|
|
|
set history remove-duplicates 100
|
|
|
|
set history filename ~/.gdb_history
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
".local/bin/fuzzypassage" = {
|
|
|
|
executable = true;
|
|
|
|
text = ''
|
|
|
|
PREFIX="''${PASSAGE_DIR:-$HOME/.passage/store}"
|
|
|
|
FZF_DEFAULT_OPTS=""
|
|
|
|
name="$(find "$PREFIX" -type f -name '*.age' | \
|
|
|
|
sed -e "s|$PREFIX/||" -e 's|\.age$||' | \
|
|
|
|
fzf --height 40% --reverse --no-multi)"
|
|
|
|
passage "''${@}" "$name"
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2022-09-02 18:01:13 +02:00
|
|
|
".local/bin/battery.sh" = {
|
|
|
|
source = bin/battery.sh;
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
".local/bin/localbsync" = {
|
|
|
|
source = bin/localbsync;
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
".local/bin/parec-wr" = {
|
|
|
|
source = bin/parec-wr;
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
".local/bin/pscbg" = {
|
|
|
|
source = bin/pscbg;
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
".local/bin/qst_up" = {
|
|
|
|
source = bin/qst_up;
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
".local/bin/winprint.sh" = {
|
|
|
|
source = bin/winprint.sh;
|
|
|
|
executable = true;
|
|
|
|
};
|
2022-09-02 18:11:18 +02:00
|
|
|
|
|
|
|
".local/bin/authenticator.sh" = {
|
|
|
|
text = ''
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
# adopted from https://wiki.archlinux.org/index.php/Google_Authenticator
|
|
|
|
# This is the path to the Google Authenticator app file. It's typically located
|
|
|
|
# in /data under Android. Copy it to your PC in a safe location and specify the
|
|
|
|
# path to it here.
|
|
|
|
#DB="/path/to/com.google.android.apps.authenticator/databases/databases"
|
|
|
|
DB="$1"
|
|
|
|
|
|
|
|
|
|
|
|
if [ $# -ne 1 ]; then
|
|
|
|
printf "authenticator\n"
|
|
|
|
printf "usage: authenticator <path/to/org.authenticator/databases/databases>\n"
|
|
|
|
printf "\tThis is the path to the Authenticator app owned SQLite db file.\n"
|
|
|
|
printf "\tCopy it to your PC to a safe location and specify the path to it here.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# On most Android systems with sufficient user access, the Google Authenticator
|
|
|
|
# database can be copied off the device and accessed directly, as it is an
|
|
|
|
# sqlite3 database. This shell script will read a Google Authenticator database
|
|
|
|
# and generate live codes for each key found:
|
|
|
|
|
|
|
|
|
|
|
|
sqlite3 "$DB" 'SELECT email,secret FROM accounts;' | while read A
|
|
|
|
do
|
|
|
|
NAME=`echo "$A" | cut -d '|' -f 1`
|
|
|
|
KEY=`echo "$A" | cut -d '|' -f 2`
|
|
|
|
CODE=`oathtool --totp -b "$KEY"`
|
|
|
|
echo -e "\e[1;32m$CODE\e[0m - \e[1;33m$NAME\e[0m"
|
|
|
|
done
|
|
|
|
'';
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
".local/bin/createarchive.sh" = {
|
|
|
|
text = ''
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
if [ $# -ne 1 ]; then
|
|
|
|
printf "createarchive\n"
|
|
|
|
printf "usage: createarchive <folder to be archived>\n"
|
|
|
|
printf "warning: the archive will be moved to "backups" directory (`echo $dest`)\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# what this does in short: tar, compress, timestamp, shred the tar, mv .xz to pwd and display it
|
|
|
|
logdate="$(date +%Y%m%dT%H%M%S)"
|
|
|
|
basedir="$1"
|
|
|
|
tmpdir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXX")
|
|
|
|
#/run/user/$(id -u) tmpfs 0700 perms
|
|
|
|
f="`cd $basedir; pwd | tr '/' ' ' | sed 's/^.* / /' | cut -c2-`" > /dev/null
|
|
|
|
g="$logdate-$f.tar"
|
|
|
|
dest=~/MEGA/Private/backups
|
|
|
|
|
|
|
|
doathing() {
|
|
|
|
cd $basedir/..
|
|
|
|
tar cfv "$tmpdir/$g" "$f" && \
|
|
|
|
xz -vzk9e "$tmpdir/$g" -S .xz && \
|
|
|
|
rsync -avP "$tmpdir/$g.xz" "$dest" && \
|
|
|
|
shred -zuv "$tmpdir/$g" "$tmpdir/$g.xz" && \
|
|
|
|
printf "\n"
|
|
|
|
ls -latr "$dest/$g.xz"
|
|
|
|
}
|
|
|
|
|
|
|
|
if [ ! -d $1 ]; then
|
|
|
|
echo "$1 is not a directory"
|
|
|
|
exit 1
|
|
|
|
else
|
|
|
|
echo `pwd`
|
|
|
|
echo "$f"
|
|
|
|
echo "$1"
|
|
|
|
|
|
|
|
doathing
|
|
|
|
trap "rm -rfv $tmpdir" 0 1 3 15
|
|
|
|
exit $?
|
|
|
|
fi
|
|
|
|
'';
|
|
|
|
executable = true;
|
|
|
|
};
|
2022-10-30 02:21:39 +01:00
|
|
|
".config/qutebrowser/userscripts/localhost" = {
|
|
|
|
executable = true;
|
|
|
|
text = ''
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
export BEMENU_OPTS="--tb '#6272a4' --tf '#f8f8f2' --fb '#282a36' --ff '#f8f8f2'
|
|
|
|
--nb '#282a36' --nf '#6272a4' --hb '#44475a' --hf '#50fa7b' --sb '#44475a' --sf
|
|
|
|
'#50fa7b' --scb '#282a36' --scf '#ff79c6' -p 'localhost:<port> ▶' --fork -l 5
|
|
|
|
--fn 'FiraCode Retina 17'"
|
|
|
|
|
|
|
|
if [[ $1 -eq 'list' ]] && [[ -z $QUTE_COUNT ]];
|
|
|
|
then
|
|
|
|
PORTS="$(ss -nltp | tail -n +2 | awk '{print $4}' | awk -F: '{print $2}')"
|
|
|
|
QUTE_COUNT=$(echo "$PORTS" | bemenu -n )
|
|
|
|
fi
|
|
|
|
|
|
|
|
# echo open -t localhost:''${QUTE_COUNT:-8080} > $QUTE_FIFO
|
|
|
|
[ -n "$QUTE_COUNT" ] && echo open -t localhost:"''${QUTE_COUNT}" > $QUTE_FIFO
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
".config/qutebrowser/userscripts/speak" = {
|
|
|
|
executable = true;
|
|
|
|
text = ''
|
|
|
|
#!/bin/bash
|
|
|
|
export IFS=$'\n'
|
|
|
|
pkill -f qute_speak || {
|
|
|
|
~/.local/bin/gtts-cli "$QUTE_SELECTED_TEXT" | mpv --no-video --speed=1.26 -
|
|
|
|
# ~/.local/bin/gtts-cli "$QUTE_SELECTED_TEXT" > /tmp/qute_speak.mp3
|
|
|
|
# mpv /tmp/qute_speak.mp3
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
".config/qutebrowser/userscripts/dark_mode.user" = {
|
|
|
|
executable = true;
|
|
|
|
text = ''
|
|
|
|
#!/bin/zsh
|
|
|
|
|
|
|
|
# on a new system cp DR.js DarkReader.user.js
|
|
|
|
darkreader_file="$HOME/.config/qutebrowser/greasemonkey/DarkReader.user.js"
|
|
|
|
enabled="^//DarkReader.disable();"
|
|
|
|
darkreader_enabled="$(grep -q -e "$enabled" $darkreader_file; echo $?)"
|
|
|
|
# echo $darkreader_enabled
|
|
|
|
|
|
|
|
if [[ "$(echo $darkreader_enabled)" == "1" ]]; then
|
|
|
|
# enable DarkReader by commenting out the line that disables it.
|
|
|
|
sed -i --follow-symlink 's/DarkReader.disable()/\/\/DarkReader.disable()/' "$darkreader_file"
|
|
|
|
else
|
|
|
|
# disable DarkReader
|
|
|
|
sed -i --follow-symlink 's/\/\/DarkReader.disable()/DarkReader.disable()/' "$darkreader_file"
|
|
|
|
fi
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
".config/qutebrowser/greasemonkey/DR.js" = {
|
|
|
|
text = ''
|
|
|
|
// ==UserScript==
|
|
|
|
// @name Dark Reader (Unofficial)
|
|
|
|
// @icon https://darkreader.org/images/darkreader-icon-256x256.png
|
|
|
|
// @namespace DarkReader
|
|
|
|
// @description Inverts the brightness of pages to reduce eye strain
|
|
|
|
// @version 4.9.52
|
|
|
|
// @author https://github.com/darkreader/darkreader#contributors
|
|
|
|
// @homepageURL https://darkreader.org/ | https://github.com/darkreader/darkreader
|
|
|
|
// @run-at document-end
|
|
|
|
// @grant none
|
|
|
|
// @exclude https://git.dotya.ml*
|
|
|
|
// @exclude https://dotya.ml*
|
|
|
|
// @exclude https://status.dotya.ml*
|
|
|
|
// @exclude https://searxng.dotya.ml*
|
|
|
|
// @exclude https://grafana.dotya.ml*
|
|
|
|
// @exclude https://github.com*
|
|
|
|
// @exclude https://dnswatch.com*
|
|
|
|
// @exclude https://docs.immudb.io*
|
|
|
|
// @exclude https://woodpecker-ci.org*
|
|
|
|
// @exclude https://duckduckgo.com*
|
|
|
|
// @exclude https://www.redit.com*
|
|
|
|
// @exclude https://codeberg.org*
|
|
|
|
// @include http*
|
|
|
|
// @require https://cdn.jsdelivr.net/npm/darkreader/darkreader.min.js
|
|
|
|
// @noframes
|
|
|
|
// ==/UserScript==
|
|
|
|
|
|
|
|
DarkReader.enable({
|
|
|
|
brightness: 105,
|
|
|
|
contrast: 105,
|
|
|
|
sepia: 0
|
|
|
|
});
|
|
|
|
DarkReader.disable();
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
".config/qutebrowser/userscripts/code_select.py" = {
|
|
|
|
executable = true;
|
|
|
|
source = .local/share/qutebrowser/userscripts/code_select.py;
|
|
|
|
};
|
|
|
|
".config/qutebrowser/userscripts/getbib" = {
|
|
|
|
executable = true;
|
|
|
|
source = .local/share/qutebrowser/userscripts/getbib;
|
|
|
|
};
|
|
|
|
".config/qutebrowser/userscripts/qute-gemini" = {
|
|
|
|
executable = true;
|
|
|
|
source = .local/share/qutebrowser/userscripts/qute-gemini;
|
|
|
|
};
|
|
|
|
".config/qutebrowser/userscripts/qute-gemini-tab" = {
|
|
|
|
executable = true;
|
|
|
|
source = .local/share/qutebrowser/userscripts/qute-gemini;
|
|
|
|
};
|
2022-10-30 02:27:16 +01:00
|
|
|
".config/qutebrowser/config.py" = {
|
|
|
|
source = .config/qutebrowser/config.py;
|
|
|
|
};
|
2022-10-30 02:21:39 +01:00
|
|
|
|
2022-10-25 10:39:09 +02:00
|
|
|
".local/bin/workqb" = {
|
|
|
|
text = ''
|
|
|
|
#!/bin/zsh
|
|
|
|
|
|
|
|
qutebrowser \
|
|
|
|
--restore work \
|
|
|
|
--config ~/.config/qutebrowser/config.py \
|
|
|
|
--basedir ~/.config/qutebrowser-work \
|
|
|
|
&
|
|
|
|
disown
|
|
|
|
'';
|
|
|
|
executable = true;
|
|
|
|
};
|
2023-07-10 04:39:21 +02:00
|
|
|
|
|
|
|
# ref: https://go.dev/blog/pprof
|
|
|
|
".local/bin/xtime" = {
|
|
|
|
text = ''
|
|
|
|
#!/bin/sh
|
|
|
|
/usr/bin/time -f '%Uu %Ss %er %MkB %C' "$@"
|
|
|
|
'';
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
".local/bin/xdp-screen-cast" = {
|
|
|
|
text = ''
|
|
|
|
#!/usr/bin/python3
|
|
|
|
|
|
|
|
# ref: https://gitlab.gnome.org/-/snippets/19
|
|
|
|
|
|
|
|
import re
|
|
|
|
import signal
|
|
|
|
import dbus
|
|
|
|
from gi.repository import GLib
|
|
|
|
from dbus.mainloop.glib import DBusGMainLoop
|
|
|
|
|
|
|
|
import gi
|
|
|
|
gi.require_version('Gst', '1.0')
|
|
|
|
from gi.repository import GObject, Gst
|
|
|
|
|
|
|
|
DBusGMainLoop(set_as_default=True)
|
|
|
|
Gst.init(None)
|
|
|
|
|
|
|
|
loop = GLib.MainLoop()
|
|
|
|
|
|
|
|
bus = dbus.SessionBus()
|
|
|
|
request_iface = 'org.freedesktop.portal.Request'
|
|
|
|
screen_cast_iface = 'org.freedesktop.portal.ScreenCast'
|
|
|
|
|
|
|
|
pipeline = None
|
|
|
|
|
|
|
|
def terminate():
|
|
|
|
if pipeline is not None:
|
|
|
|
self.player.set_state(Gst.State.NULL)
|
|
|
|
loop.quit()
|
|
|
|
|
|
|
|
request_token_counter = 0
|
|
|
|
session_token_counter = 0
|
|
|
|
sender_name = re.sub(r'\.', r'_', bus.get_unique_name()[1:])
|
|
|
|
|
|
|
|
def new_request_path():
|
|
|
|
global request_token_counter
|
|
|
|
request_token_counter = request_token_counter + 1
|
|
|
|
token = 'u%d'%request_token_counter
|
|
|
|
path = '/org/freedesktop/portal/desktop/request/%s/%s'%(sender_name, token)
|
|
|
|
return (path, token)
|
|
|
|
|
|
|
|
def new_session_path():
|
|
|
|
global session_token_counter
|
|
|
|
session_token_counter = session_token_counter + 1
|
|
|
|
token = 'u%d'%session_token_counter
|
|
|
|
path = '/org/freedesktop/portal/desktop/session/%s/%s'%(sender_name, token)
|
|
|
|
return (path, token)
|
|
|
|
|
|
|
|
def screen_cast_call(method, callback, *args, options={}):
|
|
|
|
(request_path, request_token) = new_request_path()
|
|
|
|
bus.add_signal_receiver(callback,
|
|
|
|
'Response',
|
|
|
|
request_iface,
|
|
|
|
'org.freedesktop.portal.Desktop',
|
|
|
|
request_path)
|
|
|
|
options['handle_token'] = request_token
|
|
|
|
method(*(args + (options, )),
|
|
|
|
dbus_interface=screen_cast_iface)
|
|
|
|
|
|
|
|
def on_gst_message(bus, message):
|
|
|
|
type = message.type
|
|
|
|
if type == Gst.MessageType.EOS or type == Gst.MessageType.ERROR:
|
|
|
|
terminate()
|
|
|
|
|
|
|
|
def play_pipewire_stream(node_id):
|
|
|
|
empty_dict = dbus.Dictionary(signature="sv")
|
|
|
|
fd_object = portal.OpenPipeWireRemote(session, empty_dict,
|
|
|
|
dbus_interface=screen_cast_iface)
|
|
|
|
fd = fd_object.take()
|
|
|
|
pipeline = Gst.parse_launch('pipewiresrc fd=%d path=%u ! videoconvert ! xvimagesink'%(fd, node_id))
|
|
|
|
pipeline.set_state(Gst.State.PLAYING)
|
|
|
|
pipeline.get_bus().connect('message', on_gst_message)
|
|
|
|
|
|
|
|
def on_start_response(response, results):
|
|
|
|
if response != 0:
|
|
|
|
print("Failed to start: %s"%response)
|
|
|
|
terminate()
|
|
|
|
return
|
|
|
|
|
|
|
|
print("streams:")
|
|
|
|
for (node_id, stream_properties) in results['streams']:
|
|
|
|
print("stream {}".format(node_id))
|
|
|
|
play_pipewire_stream(node_id)
|
|
|
|
|
|
|
|
def on_select_sources_response(response, results):
|
|
|
|
if response != 0:
|
|
|
|
print("Failed to select sources: %d"%response)
|
|
|
|
terminate()
|
|
|
|
return
|
|
|
|
|
|
|
|
print("sources selected")
|
|
|
|
global session
|
|
|
|
screen_cast_call(portal.Start, on_start_response,
|
|
|
|
session, ''')
|
|
|
|
|
|
|
|
def on_create_session_response(response, results):
|
|
|
|
if response != 0:
|
|
|
|
print("Failed to create session: %d"%response)
|
|
|
|
terminate()
|
|
|
|
return
|
|
|
|
|
|
|
|
global session
|
|
|
|
session = results['session_handle']
|
|
|
|
print("session %s created"%session)
|
|
|
|
|
|
|
|
screen_cast_call(portal.SelectSources, on_select_sources_response,
|
|
|
|
session,
|
|
|
|
options={ 'multiple': False,
|
|
|
|
'types': dbus.UInt32(1|2) })
|
|
|
|
|
|
|
|
portal = bus.get_object('org.freedesktop.portal.Desktop',
|
|
|
|
'/org/freedesktop/portal/desktop')
|
|
|
|
|
|
|
|
(session_path, session_token) = new_session_path()
|
|
|
|
screen_cast_call(portal.CreateSession, on_create_session_response,
|
|
|
|
options={ 'session_handle_token': session_token })
|
|
|
|
|
|
|
|
try:
|
|
|
|
loop.run()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
terminate()
|
|
|
|
'';
|
|
|
|
executable = true;
|
|
|
|
};
|
|
|
|
".local/bin/playerctl.sh" = {
|
|
|
|
source = ./bin/playerctl.sh;
|
|
|
|
executable = true;
|
|
|
|
};
|
2022-09-02 18:01:13 +02:00
|
|
|
};
|
2022-12-03 20:59:14 +01:00
|
|
|
|
2023-07-10 05:09:43 +02:00
|
|
|
xdg = (import ./nix/modules/xdg.nix) {inherit pkgs config hostName;};
|
2022-08-29 00:30:29 +02:00
|
|
|
}
|