aboutsummaryrefslogtreecommitdiff
path: root/.local/bin
diff options
context:
space:
mode:
Diffstat (limited to '.local/bin')
l---------.local/bin/awesome1
-rwxr-xr-x.local/bin/bl28
-rwxr-xr-x.local/bin/count44
-rwxr-xr-x.local/bin/dmenu22
-rwxr-xr-x.local/bin/downloadgemist42
l---------[-rwxr-xr-x].local/bin/firefox48
-rwxr-xr-x.local/bin/get-focussed-monitor43
-rwxr-xr-x.local/bin/gittab87
l---------.local/bin/herbstluftwm1
-rwxr-xr-x.local/bin/hyprland-switch-tag161
-rwxr-xr-x.local/bin/import-pape19
-rwxr-xr-x.local/bin/ipass48
l---------.local/bin/irc1
l---------.local/bin/jellyfin1
-rwxr-xr-x.local/bin/krokify30
-rwxr-xr-x.local/bin/kubectl-rageclean-pod17
-rwxr-xr-x.local/bin/kubectl-secret76
-rwxr-xr-x.local/bin/kubectl-shell57
-rwxr-xr-x.local/bin/kubectx (renamed from .local/bin/kubecontext)0
-rwxr-xr-x.local/bin/localmail4
-rwxr-xr-x.local/bin/media-import53
l---------.local/bin/mpv1
-rwxr-xr-x.local/bin/mscrot2
-rwxr-xr-x.local/bin/open26
l---------.local/bin/signal2
-rwxr-xr-x.local/bin/sscrot2
-rwxr-xr-x.local/bin/ssln26
-rwxr-xr-x.local/bin/ta17
-rwxr-xr-x.local/bin/todo (renamed from .local/bin/notify-send)43
-rwxr-xr-x.local/bin/updot63
-rwxr-xr-x.local/bin/vol35
-rwxr-xr-x.local/bin/wscrot2
-rwxr-xr-x.local/bin/x14
l---------.local/bin/xdg-open1
34 files changed, 752 insertions, 265 deletions
diff --git a/.local/bin/awesome b/.local/bin/awesome
new file mode 120000
index 0000000..3da827c
--- /dev/null
+++ b/.local/bin/awesome
@@ -0,0 +1 @@
+../share/wrapper.sh \ No newline at end of file
diff --git a/.local/bin/bl b/.local/bin/bl
index da1980e..ee71504 100755
--- a/.local/bin/bl
+++ b/.local/bin/bl
@@ -29,13 +29,25 @@ main()
case "$1" in
inc)
- xbacklight -inc ${2:-5}
+ brightnessctl set +${2:-5}%
notify="Brightness increased to $(brightness_level)%"
;;
dec)
- xbacklight -dec ${2:-5}
+ if [ $(brightness_level) -lt $(( ${2:-5} + 1 )) ]
+ then
+ brightnessctl set 1
+ else
+ brightnessctl set ${2:-5}%-
+ fi
+
notify="Brightness lowered to $(brightness_level)%"
;;
+ set)
+ [ -z "$2" ] && usage && exit 1
+
+ brightnessctl set $2%
+ notify="Brightness set to $(brightness_level)%"
+ ;;
esac
notify-send -n 57492 -s -t 2 -i "$(brightness_icon)" "Backlight" "$notify"
@@ -43,7 +55,7 @@ main()
brightness_level()
{
- xbacklight -get
+ awk "BEGIN { printf(\"%d\", ($(brightnessctl get) / $(brightnessctl max)) * 100) }"
}
brightness_icon()
@@ -61,8 +73,16 @@ usage()
cat <<EOF
Usage:
${0##*/} -h
+ ${0##*/} inc [level]
+ ${0##*/} dec [level]
+ ${0##*/} set <level>
+
+Alter the backlight intensity.
-Nondescript
+Subcommands:
+ inc Increase the volume by level, defaults to 5.
+ dec Decrease the volume by level, defaults to 5.
+ set Set the volume to level.
Options:
-h Show this help text and exit.
diff --git a/.local/bin/count b/.local/bin/count
new file mode 100755
index 0000000..cc02a71
--- /dev/null
+++ b/.local/bin/count
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+
+main()
+{
+ # Handle opts
+ while getopts ":h" opt
+ do
+ case "$opt" in
+ h) usage && exit 0 ;;
+ *)
+ printf "Invalid option passed: %s\n" "$OPTARG" >&2
+ ;;
+ esac
+ done
+
+ shift $(( OPTIND - 1 ))
+
+ cat - | sort | uniq -c | sort -h
+}
+
+usage()
+{
+ cat <<EOF
+Usage:
+ ${0##*/} -h
+
+Count occurrences of unique lines.
+
+Options:
+ -h Show this help text and exit.
+EOF
+}
+
+main "$@"
diff --git a/.local/bin/dmenu b/.local/bin/dmenu
index 78cdf52..6c1494b 100755
--- a/.local/bin/dmenu
+++ b/.local/bin/dmenu
@@ -1,8 +1,20 @@
#!/usr/bin/env sh
-if ! command -v rofi > /dev/null
-then
- exec /usr/bin/dmenu "$@"
-fi
+main() {
+ if [ -n "$WAYLAND_DISPLAY" ]
+ then
+ exec fuzzel --dmenu "$@"
+ fi
-exec rofi -dmenu "$@"
+ if [ -n "$DISPLAY" ]
+ then
+ if command -v rofi > /dev/null
+ then
+ exec rofi -dmenu "$@"
+ fi
+
+ exec /usr/bin/dmenu "$@"
+ fi
+}
+
+main "$@"
diff --git a/.local/bin/downloadgemist b/.local/bin/downloadgemist
new file mode 100755
index 0000000..d690ba8
--- /dev/null
+++ b/.local/bin/downloadgemist
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+
+import argparse
+import requests
+import sys
+
+# Handle arguments
+argparser = argparse.ArgumentParser(
+ description = "Command line utility to interact with downloadgemist.nl",
+)
+argparser.add_argument("url")
+
+args = argparser.parse_args()
+
+# Make the actual HTTP request
+form = requests.post(
+ "https://www.downloadgemist.nl/core/hyperbridge.php",
+ data={
+ "mode": "initiate",
+ "link": args.url,
+ "options": '{"size":"large","download_tt888":true}',
+ },
+)
+
+# Make sure the response is json
+if form.headers.get("Content-Type").lower() != "application/json":
+ print("oh no")
+ sys.exit(1)
+
+json = form.json()
+
+print(form.json())
+
+# Handle any errors
+if json["status"] == 1:
+ print(form.json()["error"])
+ sys.exit(form.json()["status"])
+
+# Write the downloaded file
+video = requests.get(json["file"])
+
+open(json["filename"], "wb").write(video.content)
diff --git a/.local/bin/firefox b/.local/bin/firefox
index dde1929..3da827c 100755..120000
--- a/.local/bin/firefox
+++ b/.local/bin/firefox
@@ -1,47 +1 @@
-#!/bin/sh
-
-# This program is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Affero General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-# details.
-
-readonly BINS="
- /usr/bin/firefox
- /usr/bin/firefox-bin
-"
-
-main()
-{
- require_exe "firejail"
-
- for bin in $BINS
- do
- [ -x "$bin" ] || continue
-
- exec firejail --profile="$HOME/.local/etc/firejail/firefox.profile" -- \
- "$bin" --profile "$HOME/.config/firefox" "$@"
- done
-
- printf "No underlying executable found for %s:\n" "${0##*/}" >&2
-
- for bin in $BINS
- do
- printf "\t%s\n" "$bin" >&2
- done
-}
-
-require_exe()
-{
- if ! command -v "$1" > /dev/null 2>&1
- then
- printf "Missing required executable %s\n" "$1"
- exit 3
- fi
-}
-
-main "$@"
+../share/wrapper.sh \ No newline at end of file
diff --git a/.local/bin/get-focussed-monitor b/.local/bin/get-focussed-monitor
deleted file mode 100755
index 4d7bbd4..0000000
--- a/.local/bin/get-focussed-monitor
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env raku
-
-use v6.d;
-
-sub MAIN (
- #Bool:D :$shell = False,
- Bool:D :$coords = False,
-) {
- my @xrandr = shell('xrandr | grep -w connected', :out).out.slurp.lines;
- my %monitors;
-
- my $mouse = shell('xdotool getmouselocation', :out).out.slurp.trim ~~ m/
- 'x:' $<x> = [ \d+ ]
- \s*
- 'y:' $<y> = [ \d+ ]
- /;
-
- for @xrandr -> $monitor {
- my $match = $monitor ~~ m/
- $<width> = [ \d+ ]
- 'x'
- $<height> = [ \d+ ]
- '+'
- $<x> = [ \d+ ]
- '+'
- $<y> = [ \d+ ]
- /;
-
- next unless $match<x> ≤ $mouse<x> ≤ ($match<x> + $match<width>);
- next unless $match<y> ≤ $mouse<y> ≤ ($match<y> + $match<height>);
-
- say qq[MONITOR="{$monitor.words.first}"];
-
- if ($coords) {
- say qq[W="{$match<width>}"];
- say qq[H="{$match<height>}"];
- say qq[X="{$match<x>}"];
- say qq[Y="{$match<y>}"];
- }
-
- last;
- }
-}
diff --git a/.local/bin/gittab b/.local/bin/gittab
deleted file mode 100755
index 5ffd5f9..0000000
--- a/.local/bin/gittab
+++ /dev/null
@@ -1,87 +0,0 @@
-#! /usr/bin/env perl6
-
-use v6.d;
-
-constant TABDIR = $*HOME.add('.local/etc/gittab/tabs');
-constant TABCONF = $*HOME.add('.local/etc/gittab/basedirs');
-
-#| Update managed git repositories
-multi sub MAIN (
- #| A list of targets to update.
- *@targets,
-) {
- @targets = TABDIR.dir.map(*.basename) unless @targets;
-
- for @targets -> $target {
- my $tab = find-tab($target);
-
- note "No gittab for target '$target'" unless $tab;
-
- my $basedir = get-basedir($target);
-
- mkdir($basedir) unless $basedir.d;
-
- for $tab.lines.grep(!*.starts-with("#")) {
- my ($name, $repo, $branch) = $_.words;
-
- if (!$basedir.add($name).d) {
- chdir $basedir;
- run « git clone --single-branch --branch "$branch" --depth 1 "$repo" "$name" »;
- }
-
- chdir $basedir.add($name);
- run « git checkout "$branch" »;
- run « git pull "$repo" "$branch" »;
- }
- }
-}
-
-#| List managed git repositories
-multi sub MAIN (
- Bool:D :$list!,
-) {
- my @tabs = TABDIR.dir.map(*.basename).sort;
- my $longest = @tabs.map(*.chars).sort.tail;
-
- for @tabs {
- "%-{$longest}s %s\n".printf($_, get-basedir($_));
- }
-}
-
-sub find-tab (
- Str:D $name,
-) {
- my @attempts =
- $name,
- $name ~ 'tab',
- ;
-
- for @attempts {
- my $fh = TABDIR.add($_);
-
- return $fh if $fh.f;
- }
-
- Nil;
-}
-
-sub get-basedir (
- Str:D $tab,
-) {
- state %basedirs;
-
- if (!%basedirs && TABCONF.e) {
- TABCONF
- .lines
- .grep(!*.starts-with('#'))
- .map({
- my ($tab, $basedir) = $_.words;
-
- %basedirs{$tab} = $basedir.IO;
- })
- }
-
- return $*HOME unless %basedirs{$tab}:exists;
-
- $*HOME.add(%basedirs{$tab});
-}
diff --git a/.local/bin/herbstluftwm b/.local/bin/herbstluftwm
new file mode 120000
index 0000000..3da827c
--- /dev/null
+++ b/.local/bin/herbstluftwm
@@ -0,0 +1 @@
+../share/wrapper.sh \ No newline at end of file
diff --git a/.local/bin/hyprland-switch-tag b/.local/bin/hyprland-switch-tag
new file mode 100755
index 0000000..06840c9
--- /dev/null
+++ b/.local/bin/hyprland-switch-tag
@@ -0,0 +1,161 @@
+#!/usr/bin/env bash
+
+# Pascal Jaeger <pascal.jaeger@leimstift.de>
+
+# utils
+green="\033[0;32m"
+red="\033[0;31m"
+blue="\033[0;34m"
+nocolor="\033[0m"
+
+#util functions
+check() {
+ command -v "$1" 1>/dev/null
+}
+
+ok() {
+ echo -e "[$green  $nocolor] $*"
+}
+
+err() {
+ echo -e "[$red  $nocolor] $*"
+}
+optional() {
+ echo -e "[$blue  $nocolor] $*"
+}
+
+notify() {
+ # shellcheck disable=SC2015
+ check notify-send && {
+ notify-send "$@"
+ } || {
+ echo "$@"
+ }
+}
+
+checkUtils() {
+ # shellcheck disable=SC2015
+ check grep && ok "grep" || err "grep"
+ # shellcheck disable=SC2015
+ check grep && ok "cut" || err "cut"
+ # shellcheck disable=SC2015
+ check notify-send && ok "notify-send (Optional)" || optional "notify-send (Optional)"
+ exit
+}
+
+basicChecks() {
+ check hyprctl || {
+ notify "Seriously mate!!" "Start Hyprland before this script"
+ exit 1
+ }
+ pgrep -x Hyprland &>/dev/null || {
+ notify "Make Sure Hyprland Session is running."
+ exit 1
+ }
+}
+
+help() {
+ cat <<EOF
+ This is a bash script to move arbitrary workspace to arbritrary monitor and to swap workspaces between
+ monitors if the desired workspace is already active on a monitor for Hyprland using hyprctl.
+
+ flags:
+ -h: Displays This help menu
+ -c: Checks for all dependencies
+
+ Usage: try_swap_workspace [WORKSPACE]
+ bind = ALT,1,exec, /path/to/try_swap_workspace/binary 1
+ (where the last 1 is the workspace that should be shown on the currently active monitor)
+
+EOF
+}
+
+getArgs() {
+ while [ "$#" -gt 0 ]; do
+ case "$1" in
+ -h | --help)
+ help
+ exit 0
+ ;;
+ -c)
+ checkUtils
+ ;;
+ (*[!0-9]*)
+ # contains non-numbers
+ help
+ echo ""
+ echo "Wrong argument given"
+ exit 1
+ ;;
+ *)
+ # only nubers left, so good
+ switch_or_swap "$1"
+ ;;
+ esac
+ shift
+ done
+}
+
+
+#variables
+mon_wrkspcs=()
+
+get_active_mon() {
+ echo $(($(hyprctl monitors | grep 'focused' | grep -n 'yes' | cut -c1)-1))
+}
+
+get_workspaces_array() {
+ local workspaces
+ workspaces=$(hyprctl monitors | grep 'active workspace' | cut -f3 -d' ')
+ SAVEIFS=$IFS
+ IFS=$'\n'
+ mon_wrkspcs=($workspaces)
+ IFS=$SAVEIFS
+}
+
+# first argument: workspace to switch to
+# second argument: monitor to switch workspace on
+switch_workspace() {
+ local target_wrkspc=$1
+ local target_mon=$2
+ hyprctl dispatch moveworkspacetomonitor "$target_wrkspc" "$target_mon"
+ hyprctl dispatch workspace "$target_wrkspc"
+}
+# first argument: monitor the workspace should go to
+# second argument: monitor the workspace is currently displayed on
+swap_workspace() {
+ local target_mon=$1
+ local source_mon=$2
+ hyprctl dispatch swapactiveworkspaces "$target_mon" "$source_mon"
+}
+
+# first argument: workspace to switch to active monitor
+switch_or_swap() {
+ target_mon=$(get_active_mon)
+ target_wrkspc=$1
+ get_workspaces_array
+ # check if the workspace is currently displayed on another monitor
+ local currently_active_on_mon=-1
+ for (( i=0; i<${#mon_wrkspcs[@]}; i++ ))
+ do
+ if [[ "$target_wrkspc" == "${mon_wrkspcs[$i]}" ]]; then
+ currently_active_on_mon=$i
+ fi
+ done
+ if [[ $currently_active_on_mon -lt 0 ]]; then
+ # workspace is not active on any monitor, do a normal switch
+ ok "switching workspace $target_wrkspc to monitor $target_mon"
+ switch_workspace "$target_wrkspc" "$target_mon"
+ else
+ # workspace is already active on other monitor, swap workspaces between monitor
+ ok "swapping workspaces between $target_mon to monitor $currently_active_on_mon"
+ swap_workspace "$target_mon" "$currently_active_on_mon"
+ fi
+}
+
+main() {
+ basicChecks
+ getArgs "$@"
+}
+
+main "$@"
diff --git a/.local/bin/import-pape b/.local/bin/import-pape
new file mode 100755
index 0000000..b72c169
--- /dev/null
+++ b/.local/bin/import-pape
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+readonly PAPEDIR="$HOME/pictures/wallpapers"
+
+main() {
+ for s in "$@"
+ do
+ local format="$(identify -format "%m" "$s" | awk '{ print(tolower($0)) }')"
+ local resolution="$(identify -format "%wx%h" "$s")"
+ local hash="$(sha1sum "$s" | awk '{ print $1 }')"
+ local destination="$PAPEDIR/$resolution/$hash.$format"
+
+ mkdir -pv -- "$PAPEDIR/$resolution"
+ printf "Importing %s to %s\n" "$s" "$destination"
+ mv -- "$s" "$destination"
+ done
+}
+
+main "$@"
diff --git a/.local/bin/ipass b/.local/bin/ipass
index deef05f..4f555e4 100755
--- a/.local/bin/ipass
+++ b/.local/bin/ipass
@@ -1,19 +1,51 @@
#! /usr/bin/env sh
-main()
-{
+main() {
cd -- "$HOME/.password-store" || exit 1
- file=$(find ./* -type f | sed 's-^\./--' | sed 's-\.gpg$--' | dmenu)
- dmenu_exit=$?
+ if [ -n "$WAYLAND_DISPLAY" ]
+ then
+ file="$(pass_list | fuzzel -d)"
+ pass_get "$file" | wl-copy
+
+ notify "Copied $file to clipboard!"
+ exit 0
+ fi
- if [ "$dmenu_exit" -ne 0 ]
+ if [ -n "$DISPLAY" ]
then
- exit 2
+ file="$(pass_list | dmenu)"
+ pass_get "$file" | xdotool type --file -
+ dmenu_exit=$?
+
+ if [ "$dmenu_exit" -ne 0 ]
+ then
+ notify "Error typing $file"
+ exit 2
+ fi
+
+ notify "Typing $file"
+
+ exit 0
fi
- pass show "$file" | head -n 1 | perl -pe 'chomp' | xdotool type --file -
- notify-send -i "dialog-password" "ipass" "$file"
+ notify "No graphical environment detected"
+}
+
+pass_list() {
+ find ./* -type f \
+ | sed 's-^\./--' \
+ | sed 's-\.gpg$--'
+}
+
+pass_get() {
+ pass show "$1" \
+ | head -n 1 \
+ | perl -pe 'chomp'
+}
+
+notify() {
+ notify-send -i "dialog-password" "ipass" "$*"
}
main "$@"
diff --git a/.local/bin/irc b/.local/bin/irc
new file mode 120000
index 0000000..3da827c
--- /dev/null
+++ b/.local/bin/irc
@@ -0,0 +1 @@
+../share/wrapper.sh \ No newline at end of file
diff --git a/.local/bin/jellyfin b/.local/bin/jellyfin
new file mode 120000
index 0000000..3da827c
--- /dev/null
+++ b/.local/bin/jellyfin
@@ -0,0 +1 @@
+../share/wrapper.sh \ No newline at end of file
diff --git a/.local/bin/krokify b/.local/bin/krokify
new file mode 100755
index 0000000..a01c1f6
--- /dev/null
+++ b/.local/bin/krokify
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+import argparse
+import base64
+import sys
+import zlib
+
+def main():
+ arg_parser = argparse.ArgumentParser(
+ prog='krokify',
+ description='Turn a given file into a kroki link',
+ )
+ arg_parser.add_argument("file", default="-", help="Path to the file to krokify, or - to read from stdin")
+ arg_parser.add_argument("-f", "--format", default="svg", help="Which output format to use")
+ arg_parser.add_argument("-s", "--service", required=True, help="Which back-end service to use")
+ arg_parser.add_argument("-u", "--base-url", default="https://kroki.tyil.nl", help="The base URL of the Kroki server")
+
+ args = arg_parser.parse_args()
+
+ if args.file == "-":
+ stream = sys.stdin
+ else:
+ stream = open(args.file, "r")
+
+ url = base64.urlsafe_b64encode(zlib.compress(stream.read().encode('utf-8'), 9)).decode('ascii')
+
+ print(f"{args.base_url}/{args.service}/{args.format}/{url}")
+
+if __name__ == "__main__":
+ main()
diff --git a/.local/bin/kubectl-rageclean-pod b/.local/bin/kubectl-rageclean-pod
new file mode 100755
index 0000000..bbd3ba7
--- /dev/null
+++ b/.local/bin/kubectl-rageclean-pod
@@ -0,0 +1,17 @@
+#!/usr/bin/env sh
+
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+
+main() {
+ kubectl delete pod --force --grace-period=0 "$@"
+}
+
+main "$@"
diff --git a/.local/bin/kubectl-secret b/.local/bin/kubectl-secret
new file mode 100755
index 0000000..ab2e924
--- /dev/null
+++ b/.local/bin/kubectl-secret
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+
+import argparse
+import base64
+import sys
+
+import ruamel.yaml
+import ruamel.yaml.scalarstring
+
+def main():
+ argparser = argparse.ArgumentParser(description="Encode or decode Kubernetes Secrets.")
+ argparser.add_argument("mode", help="Mode of operation, either encode or decode.", choices=["encode", "decode"])
+ argparser.add_argument("path", help="Path to the file to operate on. If set to -, STDIN will be used instead.", default="-", nargs="?")
+
+ args = argparser.parse_args()
+ yaml = ruamel.yaml.YAML()
+
+ # Deduce whether to read from STDIN or open a file handle to a given path
+ if args.path == "-":
+ buffer = sys.stdin
+ else:
+ buffer = open(args.path)
+
+ # Load the manifest
+ manifest = yaml.load(buffer.read())
+
+ # Handle any known potential issues
+ if not "kind" in manifest:
+ print("No kind in manifest", file=sys.stderr)
+ return 3
+
+ if manifest["kind"] != "Secret":
+ print("Not a secret", file=sys.stderr)
+ return 4
+
+ if not "data" in manifest:
+ manifest["data"] = {}
+
+ # Call appropriate function with the manifest
+ manifest = globals()["secret_" + args.mode](manifest)
+
+ # Write the processed manifest back as yaml
+ yaml.dump(manifest, sys.stdout)
+
+ return 0
+
+def secret_decode(manifest):
+ for key in manifest["data"].keys():
+ # Decode the data
+ manifest["data"][key] = base64.b64decode(manifest["data"][key]).decode("utf-8")
+
+ # Turn this element into a block quoted string if there are newlines
+ if "\n" in manifest["data"][key]:
+ manifest["data"][key] = ruamel.yaml.scalarstring.LiteralScalarString(manifest["data"][key])
+
+ return manifest
+
+def secret_encode(manifest):
+ for key in manifest["data"].keys():
+ # Encode the data
+ manifest["data"][key] = base64.b64encode(str(manifest["data"][key]).encode("utf-8")).decode("utf-8")
+
+ return manifest
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/.local/bin/kubectl-shell b/.local/bin/kubectl-shell
new file mode 100755
index 0000000..781edfa
--- /dev/null
+++ b/.local/bin/kubectl-shell
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+
+main()
+{
+ # Handle opts
+ while getopts ":hi:t:" opt
+ do
+ case "$opt" in
+ h) usage && exit 0 ;;
+ i) DOCKER_IMAGE="$OPTARG" ;;
+ t) DOCKER_TAG="$OPTARG" ;;
+ *)
+ printf "Invalid option passed: %s\n" "$OPTARG" >&2
+ ;;
+ esac
+ done
+
+ shift $(( OPTIND - 1 ))
+
+ [ -z "$DOCKER_IMAGE" ] && DOCKER_IMAGE="alpine"
+ [ -z "$DOCKER_TAG" ] && DOCKER_TAG="latest"
+
+ kubectl run "shell-$(uuidgen)" \
+ --image "$DOCKER_IMAGE:$DOCKER_TAG" \
+ --restart=Never \
+ --rm \
+ --stdin \
+ --tty \
+ "$@" \
+ -- /bin/sh
+}
+
+usage()
+{
+ cat <<EOF
+Usage:
+ ${0##*/} -h
+
+Shorthand to spawn a single pod with an interactive shell into your Kubernetes
+cluster.
+
+Options:
+ -h Show this help text and exit.
+EOF
+}
+
+main "$@"
diff --git a/.local/bin/kubecontext b/.local/bin/kubectx
index ac99869..ac99869 100755
--- a/.local/bin/kubecontext
+++ b/.local/bin/kubectx
diff --git a/.local/bin/localmail b/.local/bin/localmail
index ef6833e..fcf3284 100755
--- a/.local/bin/localmail
+++ b/.local/bin/localmail
@@ -22,7 +22,7 @@ use App::Localmail;
# I've been at this crossroads before. This is the cpan command to run when
# Perl updates...
#
-# cpan -f -i Data::UUID Sys::Hostname::FQDN YAML::XS
+# cpan -f -i Data::UUID Sys::Hostname::FQDN YAML::XS MIME::Base64 Authen::SASL
sub main (@args) {
my $action = shift @args;
@@ -159,7 +159,7 @@ sub send ($config, @args) {
$current->{server},
Port => $port,
SSL => $current->{ssl} // 0,
- Timeout => $current->{timeout} // 5,
+ Timeout => $current->{timeout} // 30,
Hello => Sys::Hostname::FQDN::fqdn(),
Debug => 1,
);
diff --git a/.local/bin/media-import b/.local/bin/media-import
new file mode 100755
index 0000000..a1a99b2
--- /dev/null
+++ b/.local/bin/media-import
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+main() {
+ # Show help
+ if (( $# < 2 ))
+ then
+ echo "You need help"
+ return 2
+ fi
+
+ # Set the paths
+ local basedir="${MEDIA_BASEDIR:-/var/media}"
+ local mediadir="$basedir/$1" ; shift
+
+ # Ask for confirmation through a keypress
+ printf "Going to import %d URIs to %s...\n" "$#" "$mediadir"
+ read -s -n1
+
+ # Loop over all given args
+ for uri in "$@"
+ do
+ case "$uri" in
+ http://*) import_http "$mediadir" "$uri" ;;
+ https://*) import_http "$mediadir" "$uri" ;;
+ *) import_local "$mediadir" "$uri" ;;
+ esac
+ done
+}
+
+import_http() {
+ local dest="$1" ; shift
+ local uri="$1" ; shift
+ local temp="$(mktemp)"
+
+ wget -c -O "$temp" "$uri"
+
+ local output="$(import_local "$dest" "$temp" | awk '{ print $NF }')"
+
+ printf "%s -> %s\n" "$uri" "$output"
+}
+
+import_local() {
+ local dest="$1" ; shift
+ local uri="$1" ; shift
+ local hash="$(sha1sum "$uri" | awk '{ print $1 }')"
+ local ext="$(identify "$uri" | awk '{ print tolower($2) }')"
+ local out="$dest/$hash.$ext"
+
+ mv -- "$uri" "$out"
+ printf "%s -> %s\n" "$uri" "$out"
+}
+
+main "$@"
diff --git a/.local/bin/mpv b/.local/bin/mpv
new file mode 120000
index 0000000..3da827c
--- /dev/null
+++ b/.local/bin/mpv
@@ -0,0 +1 @@
+../share/wrapper.sh \ No newline at end of file
diff --git a/.local/bin/mscrot b/.local/bin/mscrot
index 3848aaa..fedd0d9 100755
--- a/.local/bin/mscrot
+++ b/.local/bin/mscrot
@@ -3,4 +3,4 @@
p="~/pictures/scrot"
cmd="mv \$f ${p} && notify-send \"Screenshot\" \"Saved to ${p}/\$f\""
-scrot -mz multi-%Y%m%d%H%M%S.png -e "${cmd}"
+scrot -m multi-%Y%m%d%H%M%S.png -e "${cmd}"
diff --git a/.local/bin/open b/.local/bin/open
index 068af10..9877708 100755
--- a/.local/bin/open
+++ b/.local/bin/open
@@ -58,8 +58,10 @@ proto cmd ($ --> Str) { * }
# working purposes.
multi sub cmd (HttpUrl $t where { $_.hostname.ends-with('gitlab.com') && $_.path[0].?fc eq 'mintlab' }) { "chromium '$t'" }
+multi sub cmd (HttpUrl $t where { $_.hostname.ends-with('gitlab.com') && $_.path[0].?fc eq 'xxllnc' }) { "chromium '$t'" }
multi sub cmd (HttpUrl $t where *.hostname.ends-with('atlassian.net')) { "chromium '$t'" }
multi sub cmd (HttpUrl $t where *.hostname.ends-with('aws.amazon.com')) { "chromium '$t'" }
+multi sub cmd (HttpUrl $t where *.hostname.ends-with('awsapps.com')) { "chromium '$t'" }
multi sub cmd (HttpUrl $t where *.hostname.ends-with('google.com')) { "chromium '$t'" }
multi sub cmd (HttpUrl $t where *.hostname.ends-with('slack.com')) { "chromium '$t'" }
multi sub cmd (HttpUrl $t where *.hostname.ends-with('zaaksysteem.net')) { "chromium '$t'" }
@@ -68,22 +70,28 @@ multi sub cmd (HttpUrl $t where *.hostname.ends-with('zaaksysteem.nl')) { "chrom
# Rewrite bad site to good site
my @not-twitter = <
- nitter.42l.fr
- nitter.eu
- nitter.fdn.fr
- nitter.namazso.eu
- nitter.nixnet.services
- nitter.pussthecat.org
- nitter.tedomum.net
- nitter.unixfox.eu
+ nitter.mnus.de
+ twitter.alt.tyil.nl
twitter.lurkmore.com
>;
-multi sub cmd (HttpUrl $t is copy where *.hostname eq "twitter.com") { callwith(URL.new(|$t.Hash, hostname => @not-twitter.pick())) }
+my @not-reddit = <
+ reddit.alt.tyil.nl
+>;
+
+my @not-youtube = <
+ youtube.alt.tyil.nl
+>;
+
+multi sub cmd (HttpUrl $t is copy where *.hostname eq "twitter.com") { cmd(URL.new(|$t.Hash, hostname => @not-twitter.pick())) }
multi sub cmd (HttpUrl $t is copy where *.hostname eq "instagram.com") { callwith(URL.new(|$t.Hash, hostname => 'brap.top', path => $t.path.unshift('u'))) }
multi sub cmd (HttpUrl $t is copy where *.hostname eq "www.instagram.com") { callwith(URL.new(|$t.Hash, hostname => 'brap.top', path => $t.path.unshift('u'))) }
+multi sub cmd (HttpUrl $t is copy where *.hostname.ends-with("reddit.com")) { callwith(URL.new(|$t.Hash, hostname => @not-reddit.pick())) }
+
+multi sub cmd (HttpUrl $t is copy where *.hostname.ends-with("youtube.com")) { callwith(URL.new(|$t.Hash, hostname => @not-youtube.pick())) }
+
# All other URLs should be opened with the preferred browser.
multi sub cmd (HttpUrl $t) { "%*ENV<BROWSER> '$t'" }
diff --git a/.local/bin/signal b/.local/bin/signal
index 3dc73e2..3da827c 120000
--- a/.local/bin/signal
+++ b/.local/bin/signal
@@ -1 +1 @@
-../lib/cmd-wrapper/wrapper.sh \ No newline at end of file
+../share/wrapper.sh \ No newline at end of file
diff --git a/.local/bin/sscrot b/.local/bin/sscrot
index 2d4c049..3e218d5 100755
--- a/.local/bin/sscrot
+++ b/.local/bin/sscrot
@@ -5,4 +5,4 @@ cmd="mv \$f ${p} && notify-send \"Screenshot\" \"Saved to ${p}/\$f\""
eval "$(get-focussed-monitor --coords)"
-scrot -a $X,$Y,$W,$H -z screen-%Y%m%d%H%M%S.png -e "${cmd}"
+scrot -a $X,$Y,$W,$H screen-%Y%m%d%H%M%S.png -e "${cmd}"
diff --git a/.local/bin/ssln b/.local/bin/ssln
new file mode 100755
index 0000000..546107d
--- /dev/null
+++ b/.local/bin/ssln
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+
+use strict;
+use utf8;
+use warnings;
+
+my $cert = "";
+my $count = 0;
+
+# Loop over STDIN to get the nth certificate
+while (<STDIN>) {
+ # Append current line to potential cert
+ $cert .= $_;
+
+ # Check for end of certificate
+ if ($_ =~ /^\-+END(\s\w+)?\sCERTIFICATE\-+$/) {
+ # Print out the cert if this is the index we're looking for
+ if (grep(/^$count$/, @ARGV)) {
+ print $cert;
+ }
+
+ # Reset potential cert
+ $cert = "";
+ $count++;
+ }
+}
diff --git a/.local/bin/ta b/.local/bin/ta
index 3d364fa..200aeec 100755
--- a/.local/bin/ta
+++ b/.local/bin/ta
@@ -1,13 +1,16 @@
-#!/usr/bin/env sh
+#!/bin/sh
-t="tmux -2 -f ${HOME}/.config/tmux/conf -u"
+tmux="tmux -2 -f ${HOME}/.config/tmux/conf -u"
+session="$(hostname -s)"
-if [ -z "$1" ]
+if [ "$1" ]
then
- session=$(hostname -s)
-else
- session=$(hostname -s)/$1
+ session="$session/$1"
fi
-${t} attach -t "${session}" || ${t} new-session -s "${session}"
+if tmux has-session -t "$session" 2>/dev/null
+then
+ exec $tmux attach -t "$session"
+fi
+exec $tmux new-session -s "$session"
diff --git a/.local/bin/notify-send b/.local/bin/todo
index 8dc67a0..4d4df99 100755
--- a/.local/bin/notify-send
+++ b/.local/bin/todo
@@ -10,18 +10,15 @@
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
+readonly TODOTXT="$HOME/documents/todo.txt"
+
main()
{
# Handle opts
- while getopts ":a:hi:n:st:" opt
+ while getopts ":h" opt
do
case "$opt" in
- a) app=$OPTARG ;;
h) usage && exit 0 ;;
- i) icon=$OPTARG ;;
- n) id=$OPTARG ;;
- s) silent=1 ;;
- t) timeout=$OPTARG ;;
*)
printf "Invalid option passed: %s\n" "$OPTARG" >&2
;;
@@ -30,34 +27,22 @@ main()
shift $(( OPTIND - 1 ))
- [ $# -lt 1 ] && usage && exit 1
-
- if [ -z "$id" ]
+ if [ ! -f "$TODOTXT" ]
then
- id=$(awk -v min=10 -v max=10000 'BEGIN { srand(); print int(min+rand() * (max-min+1)) }')
+ printf "%s\n" "No todo.txt found at $TODOTXT" >&2
+ return 3
fi
- gdbus call \
- --session \
- --dest org.freedesktop.Notifications \
- --object-path /org/freedesktop/Notifications \
- --method org.freedesktop.Notifications.Notify \
- "$app" \
- "$id" \
- "$icon" \
- "$1" \
- "$2" \
- "[]" \
- "{}" \
- "$((${timeout:-10} * 1000))" \
- > /dev/null
-
- if [[ -z "$silent" ]]
+ if [ "$#" -lt 1 ]
then
- printf "%d\n" "$id"
+ cat "$TODOTXT"
+ return 0
fi
- exit 0
+ meta="$(date +%F)"
+
+ printf "%s %s gtd:inbox\n" "$meta" "$*"
+ printf "%s %s gtd:inbox\n" "$meta" "$*" >> "$TODOTXT"
}
usage()
@@ -66,7 +51,7 @@ usage()
Usage:
${0##*/} -h
-Nondescript
+Add an entry to the todo list.
Options:
-h Show this help text and exit.
diff --git a/.local/bin/updot b/.local/bin/updot
new file mode 100755
index 0000000..f0179ad
--- /dev/null
+++ b/.local/bin/updot
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+
+main()
+{
+ DOTFILES_REMOTE="origin"
+ DOTFILES_BRANCH="master"
+
+ # Handle opts
+ while getopts ":h" opt
+ do
+ case "$opt" in
+ b) DOTFILES_BRANCH="$OPTARG" ;;
+ h) usage && exit 0 ;;
+ u) DOTFILES_REMOTE="$OPTARG" ;;
+ *)
+ printf "Invalid option passed: %s\n" "$OPTARG" >&2
+ ;;
+ esac
+ done
+
+ shift $(( OPTIND - 1 ))
+
+ # Stash any pending changes
+ git -C "$HOME" stash
+
+ # Update the main repository
+ git -C "$HOME" fetch "$DOTFILES_REMOTE" "$DOTFILES_BRANCH"
+ git -C "$HOME" reset --hard "$DOTFILES_REMOTE/$DOTFILES_BRANCH"
+
+ # Pull updates for all submodules
+ git -C "$HOME" submodule update --init --recursive --remote
+
+ # Apply the stash
+ git -C "$HOME" stash apply
+}
+
+usage()
+{
+ cat <<EOF
+Usage:
+ ${0##*/} -h
+ ${0##*/} [-b <branch>] [-u <remote>]
+
+Utility application for dotfile maintenance.
+
+Options:
+ -b The name of the branch to use, defaults to "master"
+ -h Show this help text and exit.
+ -u The name of the remote to use, defaults to "origin"
+EOF
+}
+
+main "$@"
diff --git a/.local/bin/vol b/.local/bin/vol
index 4da6c18..84c913e 100755
--- a/.local/bin/vol
+++ b/.local/bin/vol
@@ -27,26 +27,31 @@ main()
[ $# -lt 1 ] && usage && exit 1
+ DEFAULT_SINK_NAME="$(pactl info | awk -F': ' '/Default Sink/ { print $NF }')"
+ DEFAULT_SINK_INDEX="$(pactl list short sinks | awk -v index_number="$DEFAULT_SINK_NAME" '$2==index_number {print $1}')"
+
case "$1" in
inc)
- amixer set Master ${2:-5}%+ > /dev/null
- notify="Level increased to $(volume_level)%"
+ pactl set-sink-volume @DEFAULT_SINK@ +${2:-5}% > /dev/null
+ notify="Increased '$DEFAULT_SINK_NAME' ($DEFAULT_SINK_INDEX) to $(volume_level)%"
;;
dec)
- amixer set Master ${2:-5}%- > /dev/null
- notify="Level decreased to $(volume_level)%"
+ pactl set-sink-volume @DEFAULT_SINK@ -${2:-5}% > /dev/null
+ notify="Decreased '$DEFAULT_SINK_NAME' ($DEFAULT_SINK_INDEX) to $(volume_level)%"
;;
set)
- amixer set Master $2% > /dev/null
- notify="Level set to $(volume_level)%"
+ [ -z "$2" ] && usage && exit 1
+
+ pactl set-sink-volume @DEFAULT_SINK@ $2% > /dev/null
+ notify="Set '$DEFAULT_SINK_NAME' ($DEFAULT_SINK_INDEX) to $(volume_level)%"
;;
on)
- amixer set Master on > /dev/null
- notify="Unmuted at $(volume_level)%"
+ pactl set-sink-mute @DEFAULT_SINK@ 0 > /dev/null
+ notify="Unmuted '$DEFAULT_SINK_NAME' ($DEFAULT_SINK_INDEX) at $(volume_level)%"
;;
off)
- amixer set Master off > /dev/null
- notify="Muted"
+ pactl set-sink-mute @DEFAULT_SINK@ 1 > /dev/null
+ notify="Muted '$DEFAULT_SINK_NAME' ($DEFAULT_SINK_INDEX)"
;;
toggle)
case "$(volume_state)" in
@@ -56,17 +61,23 @@ main()
;;
esac
+ printf "%s\n" "$notify"
notify-send -n 19269 -s -t 2 -i "$(volume_icon)" "Volume" "$notify"
}
volume_level()
{
- amixer get Master | awk '/Left:/ { print $5 }' | head -n 1 | tr -d '[]%'
+
+ pactl list sinks \
+ | perl -000ne 'if(/#'"$DEFAULT_SINK_INDEX"'/){/(Volume:.*)/; print "$1\n"}' \
+ | sed 's/.*\ \(.*\)%.*/\1/g'
}
volume_state()
{
- amixer get Master | awk '/Left:/ { print $6 }' | head -n 1 | tr -d '[]'
+ pactl list sinks \
+ | perl -000ne 'if(/#'"$DEFAULT_SINK_INDEX"'/){/(Mute:.*)/; print "$1\n"}' \
+ | awk '$NF == "no" { print "on" } $NF == "yes" { print "off" }'
}
volume_icon()
diff --git a/.local/bin/wscrot b/.local/bin/wscrot
index 2970713..979dbef 100755
--- a/.local/bin/wscrot
+++ b/.local/bin/wscrot
@@ -3,4 +3,4 @@
p="~/pictures/scrot"
cmd="mv \$f ${p} && notify-send \"Screenshot\" \"Saved to ${p}/\$f\""
-scrot -bsz window-%Y%m%d%H%M%S.png -e "${cmd}"
+scrot -bs window-%Y%m%d%H%M%S.png -e "${cmd}"
diff --git a/.local/bin/x b/.local/bin/x
index ed5e26f..a47b1bc 100755
--- a/.local/bin/x
+++ b/.local/bin/x
@@ -12,12 +12,10 @@ then
exit 1
fi
- # Remove the old config
- rm -f -- "$HOME/.xinitrc"
-
- # Add the base configuration
- cat -- "$HOME/.local/etc/x/xinitrc" "$HOME/.local/etc/x/xinit.d/$1.rc" \
- >> "$HOME/.xinitrc"
+ cat \
+ "$HOME/.local/etc/x/xinitrc" \
+ "$HOME/.local/etc/x/xinit.d/$1.rc" \
+ > "$HOME/.xinitrc"
fi
# Make sure the xinitrc exists, just in case
@@ -28,4 +26,6 @@ then
fi
# start the X session
-exec startx
+startx
+systemctl --user stop desktop-x11.target
+systemctl --user stop desktop.target
diff --git a/.local/bin/xdg-open b/.local/bin/xdg-open
deleted file mode 120000
index ce4a72b..0000000
--- a/.local/bin/xdg-open
+++ /dev/null
@@ -1 +0,0 @@
-open \ No newline at end of file