254 lines
8.3 KiB
Nix
254 lines
8.3 KiB
Nix
|
{...}: {
|
||
|
home.file = {
|
||
|
".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"
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
# 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;
|
||
|
};
|
||
|
|
||
|
".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;
|
||
|
};
|
||
|
|
||
|
".local/bin/workqb" = {
|
||
|
text = ''
|
||
|
#!/bin/zsh
|
||
|
|
||
|
qutebrowser \
|
||
|
--restore work \
|
||
|
--config ~/.config/qutebrowser/config.py \
|
||
|
--basedir ~/.config/qutebrowser-work \
|
||
|
&
|
||
|
disown
|
||
|
'';
|
||
|
executable = true;
|
||
|
};
|
||
|
};
|
||
|
}
|