summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2022-12-06 23:03:44 -0700
committerSean Whitton <spwhitton@spwhitton.name>2022-12-07 09:41:16 -0700
commit13f08e9d36de02c54283993d2bd035adf13f0411 (patch)
tree8270a1dfe4916b9e70e173f4b2957d86e56e9e12 /scripts
parente27b9fcc8e89e847a4c7f7f6a80cc15e991dd260 (diff)
downloaddotfiles-13f08e9d36de02c54283993d2bd035adf13f0411.tar.gz
bin/: some straightforward tidying up
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/debian/test-package-plan10
-rwxr-xr-xscripts/desktop/i3-startup-always119
-rwxr-xr-xscripts/desktop/xuserrun58
-rwxr-xr-xscripts/docs/make-poster-pdf89
-rwxr-xr-xscripts/docs/pdfbg.py34
-rwxr-xr-xscripts/flashdrive/usbpubkeys24
-rwxr-xr-xscripts/media/burndir57
-rwxr-xr-xscripts/media/copydvd55
-rwxr-xr-xscripts/media/encode.sh184
-rwxr-xr-xscripts/media/flac2mp3134
-rwxr-xr-xscripts/pgp/get-wkd-key5
-rwxr-xr-xscripts/pgp/offcaff17
-rwxr-xr-xscripts/pgp/preoffcaff17
-rwxr-xr-xscripts/root/ps_mem.py168
14 files changed, 971 insertions, 0 deletions
diff --git a/scripts/debian/test-package-plan b/scripts/debian/test-package-plan
new file mode 100755
index 00000000..47d6b232
--- /dev/null
+++ b/scripts/debian/test-package-plan
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+find $HOME/.cabal/packages/hackage.haskell.org/01-index.tar \
+ -newermt '4 hours ago' \
+ | xargs test -z && cabal --no-require-sandbox update
+
+schroot -c haskell -d $HOME -- /bin/sh -c \
+ "cd src/package-plan && perl test-packages.pl"
diff --git a/scripts/desktop/i3-startup-always b/scripts/desktop/i3-startup-always
new file mode 100755
index 00000000..b2a02e25
--- /dev/null
+++ b/scripts/desktop/i3-startup-always
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+# idempotent X settings
+
+xrdb -merge "$HOME/.Xresources"
+
+# ---- don't let other local users spawn windows on my main X session
+
+xhost -local:
+
+# ---- no bell please
+
+xset b off
+
+# ---- keyboard settings
+
+xset r rate 380 25
+
+# enable numlock if using USB keyboard, with an exception
+if ! lsusb | grep -q "SiGma Micro Keyboard TRACER Gamma Ivory"; then
+ . /etc/X11/Xsession.d/55numlockx
+fi
+
+# disable caps lock if I accidently hit it before running this script
+if xset -q | grep "Caps Lock: *on" >/dev/null; then
+ xdotool key Caps_Lock
+fi
+
+# ---- wallpaper rotation
+
+# if [ -e "$HOME/local/wallpaper.png" ] \
+# && ! systemctl --user --quiet is-enabled i3-rotate-wallpaper.timer; then
+# # Persistent=true only works if the timer has been triggered at
+# # least once, but my computer is generally suspended at midnight.
+# # So pretend that the job just fired
+# mkdir -p "$HOME/.local/share/systemd/timers"
+# touch "$HOME/.local/share/systemd/timers/stamp-i3-rotate-wallpaper.timer"
+
+# systemctl --user --now enable i3-rotate-wallpaper.timer
+# fi
+
+# ---- monitor settings
+
+# if this machine is always plugged into the same monitor, may
+# `convert ~/lib/annex/doc/img/wallpaper/foo -resize 1366x768\!
+# ~/local/wallpaper.png` or add a cronjob to call i3-rotate-wallpaper.
+# Otherwise, stick to a solid colour, because doing otherwise requires
+# resizing the image file, setting the root window and restarting
+# i3lock every time an external monitor is plugged or unplugged
+#
+# For images that look bad stretched, to get black borders: convert foo.jpg -resize 1920x1080 -background black -gravity center -extent 1920x1080 ~/local/wallpaper.png
+
+# xsetroot -solid \#2c2c2e
+# xsetroot -solid \#111111
+# xsetroot -solid \#E5E5E5
+# xsetroot -solid \#FFFFF6
+
+# machine-specific display settings
+if [ "$(hostname -f)" = "iris.silentflame.com" ]; then
+ # set-half-brightness
+ if xrandr | grep "VGA-1 connected"; then
+ xrandr \
+ --output VGA-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal \
+ --output LVDS-1 --mode 1366x768 --pos 1920x312 --rotate normal
+ else
+ xrandr \
+ --output VGA-1 --off \
+ --output LVDS-1 --primary --mode 1366x768 --pos 0x0 --rotate normal
+ fi
+elif [ "$(hostname -f)" = "melete.silentflame.com" ]; then
+ # set-half-brightness
+ # need this to set --primary, to ensure that i3 tray icons appear on
+ # laptop monitor
+ xrandr --output eDP-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal
+fi
+
+# # use wallpaper.png if it's the right size
+# if i3-wallpaper --check-have; then
+# feh --bg-scale --no-xinerama $HOME/local/wallpaper.png
+
+# # restart i3lock, in case the wallpaper changed
+# i3-startup-i3lock
+# else
+ # feh --bg-tile ~/src/dotfiles/lib-src/img/diagmonds_2X.png
+# fi
+
+feh --bg-tile ~/src/dotfiles/lib-src/img/green_gobbler.png
+
+# Set how long before automatic lock. We have the DPMS time and the
+# automatic lock time set to the same value.
+#
+# I used to have have (e.g.) `xset s 150 180; xset dpms 1200 1200 0`
+# with a --notifier option passed to xss-lock which used i3-nagbar to
+# warn of an impending lock. This warning was necessary because
+# xtrlock's visual feedback is low. However, when i3-nagbar (or,
+# indeed, notify-send) is launched by xss-lock, they break the
+# display of various windows until the mouse is moved around. This
+# problem does not occur if I launch i3-nagbar from a terminal window.
+# In that case, everything gets redrawn as it should be.
+#
+# So instead, we wait to lock the screen until the point at which we
+# are blanking it for power saving. The screen going blank is
+# sufficient visual feedback.
+#
+# If my screen actually needs locking, I always just do that manually,
+# so this is only a fallback, in any case.
+#
+# Changes to these values should be kept in sync with comproc.org
+# notes for configuring xfce4-power-manager
+xset s default
+if [ "$(hostname)" = develacc ]; then
+ xset s 0
+ xset dpms 0 0 0
+ xset -dpms
+else
+ xset s 1200
+ xset dpms 1200 1200 1200
+ xset +dpms
+fi
diff --git a/scripts/desktop/xuserrun b/scripts/desktop/xuserrun
new file mode 100755
index 00000000..6ec24350
--- /dev/null
+++ b/scripts/desktop/xuserrun
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+#
+# Run a command as the currently active X11 user
+#
+
+# source: https://github.com/rephorm/xuserrun
+
+seat="seat0"
+
+# determine location of loginctl
+LOGINCTL=$(command -v loginctl || command -v systemd-loginctl)
+if [[ -e LOGINCTL ]]; then
+ echo "Error: Unable to find loginctl executable"
+ exit 1
+fi
+
+get_session_info() {
+ local session="$1"
+ local varname="$2"
+ local IFS=$'\n'
+ eval declare -Ag $varname
+ for row in $(loginctl show-session "$session"); do
+ key="$(echo "${row}"|cut -d= -f1)"
+ val="$(echo "${row}"|cut -d= -f2-)"
+ eval ${varname}[\"${key}\"]=\"${val}\"
+ done
+}
+
+escape() {
+ for arg in "$@" ; do
+ printf "%q " "$arg";
+ done;
+}
+
+active_session="$(loginctl show-seat ${seat}|grep ActiveSession|cut -d= -f2)"
+if [[ $? -ne 0 || -z $active_session ]]; then
+ echo "Error: Unable to determine active session"
+ exit 1
+fi
+
+get_session_info $active_session session_info
+
+if [[ ${session_info[Type]} != "x11" ]]; then
+ echo "Error: Active session is not x11"
+ exit 2
+fi
+
+current_user="$(id -u -n)"
+
+if [[ ${current_user} == ${session_info[Name]} ]]; then
+ # already correct user, no need to su
+ DISPLAY="${session_info[Display]}" "$@"
+else
+ # run command as user
+ DISPLAY="${session_info[Display]}" su -c - "${session_info[Name]}" "$(escape "$@")"
+fi
+
diff --git a/scripts/docs/make-poster-pdf b/scripts/docs/make-poster-pdf
new file mode 100755
index 00000000..f8ac917b
--- /dev/null
+++ b/scripts/docs/make-poster-pdf
@@ -0,0 +1,89 @@
+#!/bin/bash
+
+# Resizes files to A4 (or other size - change PaperWdthMetr and PaperHghtMetr below) and merges into a PDF
+
+# by Mikher and user173283 on StackExchange
+# https://unix.stackexchange.com/questions/20026/convert-images-to-pdf-how-to-make-pdf-pages-same-size
+
+export LOCALE=C
+
+[[ "${2}x" == "x" ]] && \
+ { echo "Usage: $( basename $0 ) output.pdf extension"
+ echo " merges all files (*.extension) into a single PDF"
+ echo "If files z_merged.pdf, z_temp.pdf or $1 exist, they will be overwritten"
+ exit 1
+ } || \
+ OutName="$1"
+ ext="$2"
+
+# Set basic variables
+unset Debug #; Debug="yes" # print extra messages
+IMBackground="white" # what colour for paper
+IMQuality="91" # JPEG compression level
+PaperHghtMetr="279.4" # milimeters, 297 for ISO A4
+PaperWdthMetr="215.9" # milimeters, 210 for ISO A4
+PaperDens="300" # maximum (wanted) dpi for a page
+PaperHInch=$( echo scale=5\; $PaperHghtMetr / 2.54 / 10 | bc -l ) # Inch
+PaperWInch=$( echo scale=5\; $PaperWdthMetr / 2.54 / 10 | bc -l ) # Inch
+PaperRtio=$( echo scale=5\; $PaperWdthMetr / $PaperHghtMetr | bc -l )
+
+# Remove temporary files from prior run
+rm -rf z_merged.pdf z_temp.pdf 2>/dev/null
+
+# Process any $ext file in the current directory
+find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r FName
+do
+ echo "Converting $FName"
+ ImgIdentify=$( identify -format "%w %h" "$FName" )
+ ImgWdthOrig=$( echo $ImgIdentify | cut -d" " -f1 )
+ ImgHghtOrig=$( echo $ImgIdentify | cut -d" " -f2 )
+ ImgRtio=$( echo "scale=5; $ImgWdthOrig / $ImgHghtOrig" | bc -l )
+
+
+# Match output page layout - Landscape or Portrait - to input file
+ if (( $(echo "$ImgRtio > 1 && $PaperRtio > 1 || $ImgRtio < 1 && $PaperRtio < 1" |bc -l) )); then
+ echo "Portrait"
+ PaperHghtInch=$PaperHInch
+ PaperWdthInch=$PaperWInch
+ else
+ echo "Landscape"
+ PaperHghtInch=$PaperWInch
+ PaperWdthInch=$PaperHInch
+ fi
+
+
+ [[ $( echo $ImgRtio'>'$PaperRtio | bc -l ) == 1 ]] \
+ && ImgDens=$( echo scale=0\; $ImgWdthOrig / $PaperWdthInch | bc -l ) \
+ || ImgDens=$( echo scale=0\; $ImgHghtOrig / $PaperHghtInch | bc -l )
+ [[ $Debug ]] && echo "ImgDens1: $ImgDens"
+ [[ $( echo $ImgDens'>'$PaperDens | bc -l ) == 1 ]] \
+ && ImgDens=$PaperDens
+ [[ $Debug ]] && echo "ImgDens2: $ImgDens"
+
+ ImgWdth=$( echo $PaperWdthInch \* $ImgDens | bc -l ) # pixels
+ ImgHght=$( echo $PaperHghtInch \* $ImgDens | bc -l ) # pixels
+
+ [[ $Debug ]] && echo "ImgWdth: $ImgWdth".
+ [[ $Debug ]] && echo "ImgHght: $ImgHght".
+
+ convert "${FName}" \
+ -resize ${ImgWdth}x${ImgHght} \
+ -background $IMBackground -gravity center \
+ -extent ${ImgWdth}x${ImgHght} \
+ -units PixelsPerInch -set density $ImgDens \
+ -repage ${ImgWdth}x${ImgHght}+0+0 \
+ -compress JPEG \
+ -quality $IMQuality \
+ "${FName%.$ext}.pdf"
+
+ # Merge new PDF page with prior pages
+ [[ -f z_merged.pdf ]] && \
+ { pdftk z_merged.pdf "${FName%.$ext}.pdf" cat output z_temp.pdf
+ mv z_temp.pdf z_merged.pdf
+ } || \
+ cp "${FName%.$ext}.pdf" z_merged.pdf
+ [[ $Debug ]] || rm -rf "${FName%.$ext}.pdf"
+done
+
+[[ -f z_merged.pdf ]] && mv z_merged.pdf "$OutName"
+echo "Done."
diff --git a/scripts/docs/pdfbg.py b/scripts/docs/pdfbg.py
new file mode 100755
index 00000000..af1b28cd
--- /dev/null
+++ b/scripts/docs/pdfbg.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+import tempfile
+import subprocess
+import shutil
+import os
+import sys
+
+def main ():
+ workdir = tempfile.mkdtemp()
+ bgfiles = {'wotc': os.path.expanduser("~") + r'/lib/annex/rt/complete/Dungeons and Dragons/3.5 Core Rulebooks/Blank WoTC Stationary/D&D Blank Pages.pdf'}
+
+ if not(len(sys.argv) == 3):
+ print "wrong number of arguments"
+ return 1
+ # sys.argv[1] is the bgfiles key, sys.argv[2] is the file to be processed
+ if sys.argv[2][-3:] == "tex":
+ thepdf = sys.argv[2][:-3] + 'pdf'
+ else:
+ thepdf = sys.argv[2]
+
+ subprocess.call(['pdftk', bgfiles[sys.argv[1]], 'cat', '1', 'output', workdir + '/odd_bg.pdf'])
+ subprocess.call(['pdftk', bgfiles[sys.argv[1]], 'cat', '2', 'output', workdir + '/even_bg.pdf'])
+ subprocess.call(['pdftk', thepdf, 'cat', '1-endodd', 'output', workdir + '/odd.pdf'])
+ subprocess.call(['pdftk', thepdf, 'cat', '1-endeven', 'output', workdir + '/even.pdf'])
+ subprocess.call(['pdftk', workdir + '/odd.pdf', 'background', workdir + '/odd_bg.pdf', 'output', workdir + '/odd_bged.pdf'])
+ subprocess.call(['pdftk', workdir + '/even.pdf', 'background', workdir + '/even_bg.pdf', 'output', workdir + '/even_bged.pdf'])
+ subprocess.call(['pdftk', 'A=' + workdir + '/odd_bged.pdf', 'B=' + workdir + '/even_bged.pdf', 'shuffle', 'A', 'B', 'output', thepdf])
+
+ shutil.rmtree(workdir)
+
+if __name__ == "__main__":
+ main()
+
diff --git a/scripts/flashdrive/usbpubkeys b/scripts/flashdrive/usbpubkeys
new file mode 100755
index 00000000..20330b99
--- /dev/null
+++ b/scripts/flashdrive/usbpubkeys
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# update cache of ssh and https host keys for USB drives
+
+OUTPUT=$HOME/lib/annex/big/skel/usb/lib/host_keys.txt
+OUTPUT_OPENSSH=$HOME/lib/annex/big/skel/usb/lib/known_hosts
+
+(
+ echo -n "Generated by ~/bin/usbpubkeys "
+ date
+ echo
+ echo -n "athena.silentflame.com's SSH key fingerprint: "
+ # assume that we've already got it in known_hosts locally
+ ssh -o ControlMaster=no -o ControlPath=/dev/null -v athena /bin/true 2>&1 \
+ | grep "Server host key:" | cut -d' ' -f 5-6
+ # don't assume our connection is safe; ssh to ma first
+ # echo -n "ma.sdf.org's web SSL key SHA1 fingerprint: "
+ # echo -n | ssh ma openssl s_client -connect ma:443 2>/dev/null | \
+ # openssl x509 -noout -fingerprint | cut -f2 -d'='
+
+) > $OUTPUT
+unix2dos $OUTPUT
+
+ssh-keyscan -t rsa athena.silentflame.com > $OUTPUT_OPENSSH
diff --git a/scripts/media/burndir b/scripts/media/burndir
new file mode 100755
index 00000000..786845ac
--- /dev/null
+++ b/scripts/media/burndir
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+#Usage: burndir <dir> <device>
+
+# http://www.linuxquestions.org/questions/linux-software-2/burning-dvd-and-verifying-no-iso-689438/#post3458795
+
+#Make sure we are running as root (otherwise we can't burn later)
+if [ `whoami` != "root" ]
+then
+echo "This script must be run as root."
+exit 1
+fi
+
+DIRPATH="$1"
+DEVICE="$2"
+
+TMPDIR=`mktemp -d` || exit 1
+ISOPIPE="$TMPDIR/pipe.iso"
+MKISOERR="$TMPDIR/mkisoerr"
+
+mkfifo "$ISOPIPE"
+
+echo "Burning directory..."
+
+growisofs -dvd-compat -Z "$DEVICE"="$ISOPIPE" &
+BURNER=$!
+MD5=`mkisofs -r -J -l "$DIRPATH" 2>"$MKISOERR" | tee "$ISOPIPE" | md5sum | egrep -o -i -e "^[0-9a-f]{32}"`
+
+EXTENTS=`egrep -e "^[0-9]+ extents written " "$MKISOERR" | egrep -o -e "^[0-9]+"`
+
+wait "$BURNER"
+
+echo "Wrote $EXTENTS extents with a MD5 hash of $MD5."
+echo "Cycling drive tray..."
+
+eject "$DEVICE"
+eject -t "$DEVICE"
+
+# Arch Linux seems to have problems without a wait
+# here; gives dd: opening `/dev/sr1': No medium found otherwise
+sleep 15
+
+echo "Verifying..."
+
+DISCMD5=`dd if="$DEVICE" bs=2048 count="$EXTENTS" | md5sum | egrep -o -i -e "^[0-9a-f]{32}"`
+
+echo "Disc has an MD5 hash of $DISCMD5."
+
+if [ "$MD5" == "$DISCMD5" ]
+then
+echo "Disc appears to have burned successfully!"
+else
+echo "Disc appears to have burned with errors."
+fi
+
+rm -r "$TMPDIR"
+
diff --git a/scripts/media/copydvd b/scripts/media/copydvd
new file mode 100755
index 00000000..6b939c68
--- /dev/null
+++ b/scripts/media/copydvd
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#Usage: copydvd <read> <write>
+
+#Make sure we are running as root (otherwise we can't burn later)
+if [ `whoami` != "root" ]
+then
+echo "This script must be run as root."
+exit 1
+fi
+
+DEVICE1="$1"
+DEVICE2="$2"
+
+TMPDIR=`mktemp -d` || exit 1
+ISOPIPE="$TMPDIR/pipe.iso"
+READERR="$TMPDIR/mkisoerr"
+
+mkfifo "$ISOPIPE"
+
+echo "Burning directory..."
+
+growisofs -dvd-compat -Z "$DEVICE2"="$ISOPIPE" &
+BURNER=$!
+MD5=`dd if="$DEVICE1" 2>"$READERR" | tee "$ISOPIPE" | md5sum | egrep -o -i -e "^[0-9a-f]{32}"`
+
+EXTENTS=`egrep -e "^[0-9]+ extents written " "$READERR" | egrep -o -e "^[0-9]+"`
+
+wait "$BURNER"
+
+echo "Wrote $EXTENTS extents with a MD5 hash of $MD5."
+echo "Cycling drive tray..."
+
+eject "$DEVICE2"
+eject -t "$DEVICE2"
+
+# Arch Linux seems to have problems without a wait
+# here; gives dd: opening `/dev/sr1': No medium found otherwise
+sleep 15
+
+echo "Verifying..."
+
+DISCMD5=`dd if="$DEVICE2" bs=2048 count="$EXTENTS" | md5sum | egrep -o -i -e "^[0-9a-f]{32}"`
+
+echo "Disc has an MD5 hash of $DISCMD5."
+
+if [ "$MD5" == "$DISCMD5" ]
+then
+echo "Disc appears to have burned successfully!"
+else
+echo "Disc appears to have burned with errors."
+fi
+
+rm -r "$TMPDIR"
+
diff --git a/scripts/media/encode.sh b/scripts/media/encode.sh
new file mode 100755
index 00000000..4c72eff5
--- /dev/null
+++ b/scripts/media/encode.sh
@@ -0,0 +1,184 @@
+#!/bin/bash
+
+# encode.sh
+#
+# Copyright (c) 2013 Don Melton
+#
+# This version published on June 7, 2013.
+#
+# Re-encode video files in a format suitable for playback on Apple TV, Roku 3,
+# iOS, OS X, etc.
+#
+# Input is assumed to be a single file readable by HandBrakeCLI and mediainfo,
+# e.g. just about any .mkv, .avi, .mpg, etc. file.
+#
+# The script automatically calculates output video bitrate based on input. For
+# Blu-ray Disc-quality input that's always 5000 Kbps. For DVD-quality input
+# that's always 1800 Kbps. For other files that will vary.
+#
+# The script also automatically calculates video frame rates and audio channel
+# configuration.
+#
+# If the input contains a VobSub (DVD-style) or PGS (Blu-ray Disc-style)
+# subtitle, then it is burned into the video.
+#
+# Optional frame rate overrides and soft subtitles in .srt format are read
+# from separate fixed locations in the `$frame_rates_location` and
+# `$subtitles_location` variables defined below. Edit this script to redefine
+# them.
+#
+# If your input file is named "foobar.mkv" then the optional frame rate file
+# should be named "foobar.txt". And all it should contain is the frame rate
+# number, e.g. "25" followed by a carriage return.
+#
+# If your input file is named "foobar.mkv" then the optional soft subtitle
+# file should be named "foobar.srt".
+#
+# Output is an MP4 container with H.264 video, AAC audio and possibly AC-3
+# audio if the input has more than two channels.
+#
+# No scaling or cropping is performed on the output. This is a good thing.
+#
+# The output .mp4 file and a companion .log file are written to the current
+# directory.
+#
+# This script depends on two separate command line tools:
+#
+# HandBrakeCLI http://handbrake.fr/
+# mediainfo http://mediainfo.sourceforge.net/
+#
+# Make sure both are in your `$PATH` or redefine the variables below.
+#
+# Usage:
+#
+# ./encode.sh [input file]
+#
+
+die() {
+ echo "$program: $1" >&2
+ exit ${2:-1}
+}
+
+escape_string() {
+ echo "$1" | sed "s/'/'\\\''/g;/ /s/^\(.*\)$/'\1'/"
+}
+
+readonly program="$(basename "$0")"
+
+readonly input="$1"
+
+if [ ! "$input" ]; then
+ die 'too few arguments'
+fi
+
+handbrake="HandBrakeCLI"
+mediainfo="mediainfo"
+
+frame_rates_location="/path/to/Frame Rates"
+subtitles_location="/path/to/Subtitles"
+
+# My advice is: do NOT change these HandBrake options. I've encoded over 300
+# Blu-ray Discs, 30 DVDs and numerous other files with these settings and
+# they've never let me down.
+
+handbrake_options="--markers --large-file --encoder x264 --encopts vbv-maxrate=25000:vbv-bufsize=31250:ratetol=inf --crop 0:0:0:0 --strict-anamorphic"
+
+width="$(mediainfo --Inform='Video;%Width%' "$input")"
+height="$(mediainfo --Inform='Video;%Height%' "$input")"
+
+if (($width > 1280)) || (($height > 720)); then
+ max_bitrate="5000"
+elif (($width > 720)) || (($height > 576)); then
+ max_bitrate="4000"
+else
+ max_bitrate="1800"
+fi
+
+min_bitrate="$((max_bitrate / 2))"
+
+bitrate="$(mediainfo --Inform='Video;%BitRate%' "$input")"
+
+if [ ! "$bitrate" ]; then
+ bitrate="$(mediainfo --Inform='General;%OverallBitRate%' "$input")"
+ bitrate="$(((bitrate / 10) * 9))"
+fi
+
+if [ "$bitrate" ]; then
+ bitrate="$(((bitrate / 5) * 4))"
+ bitrate="$((bitrate / 1000))"
+ bitrate="$(((bitrate / 100) * 100))"
+
+ if (($bitrate > $max_bitrate)); then
+ bitrate="$max_bitrate"
+ elif (($bitrate < $min_bitrate)); then
+ bitrate="$min_bitrate"
+ fi
+else
+ bitrate="$min_bitrate"
+fi
+
+handbrake_options="$handbrake_options --vb $bitrate"
+
+frame_rate="$(mediainfo --Inform='Video;%FrameRate_Original%' "$input")"
+
+if [ ! "$frame_rate" ]; then
+ frame_rate="$(mediainfo --Inform='Video;%FrameRate%' "$input")"
+fi
+
+frame_rate_file="$(basename "$input")"
+frame_rate_file="$frame_rates_location/${frame_rate_file%\.[^.]*}.txt"
+
+if [ -f "$frame_rate_file" ]; then
+ handbrake_options="$handbrake_options --rate $(cat "$frame_rate_file")"
+elif [ "$frame_rate" == '29.970' ]; then
+ handbrake_options="$handbrake_options --rate 23.976"
+else
+ handbrake_options="$handbrake_options --rate 30 --pfr"
+fi
+
+channels="$(mediainfo --Inform='Audio;%Channels%' "$input" | sed 's/[^0-9].*$//')"
+
+if (($channels > 2)); then
+ handbrake_options="$handbrake_options --aencoder ca_aac,copy:ac3"
+elif [ "$(mediainfo --Inform='General;%Audio_Format_List%' "$input" | sed 's| /.*||')" == 'AAC' ]; then
+ handbrake_options="$handbrake_options --aencoder copy:aac"
+fi
+
+if [ "$frame_rate" == '29.970' ]; then
+ handbrake_options="$handbrake_options --detelecine"
+fi
+
+srt_file="$(basename "$input")"
+srt_file="$subtitles_location/${srt_file%\.[^.]*}.srt"
+
+if [ -f "$srt_file" ]; then
+ subtitle_format="$(mediainfo --Inform='Text;%Format%' "$input" | sed q)"
+
+ if [ "$subtitle_format" == 'VobSub' ] || [ "$subtitle_format" == 'PGS' ]; then
+ handbrake_options="$handbrake_options --subtitle 1 --subtitle-burned"
+ else
+ tmp=""
+
+ trap '[ "$tmp" ] && rm -rf "$tmp"' 0
+ trap '[ "$tmp" ] && rm -rf "$tmp"; exit 1' SIGHUP SIGINT SIGQUIT SIGTERM
+
+ tmp="/tmp/${program}.$$"
+ mkdir -m 700 "$tmp" || exit 1
+
+ temporary_srt_file="$tmp/subtitle.srt"
+ cp "$srt_file" "$temporary_srt_file" || exit 1
+
+ handbrake_options="$handbrake_options --srt-file $(escape_string "$temporary_srt_file") --srt-codeset UTF-8 --srt-lang eng --srt-default 1"
+ fi
+fi
+
+output="$(basename "$input")"
+output="${output%\.[^.]*}.mp4"
+
+echo "Encoding: $input" >&2
+
+time "$handbrake" \
+ $handbrake_options \
+ --input "$input" \
+ --output "$output" \
+ 2>&1 | tee -a "${output}.log"
diff --git a/scripts/media/flac2mp3 b/scripts/media/flac2mp3
new file mode 100755
index 00000000..23d5a170
--- /dev/null
+++ b/scripts/media/flac2mp3
@@ -0,0 +1,134 @@
+#!/usr/bin/perl -w
+use strict;
+
+#########################################################
+# Flac to Mp3 Perl Converter
+# Created by: Somnorific
+# Based on: Scripts by Falkano and Nick Sklaventitis
+# Date: June 26, 2008
+#
+# Requires: perl, zenity, flac, lame, and rsync
+# Tested on: Ubuntu (Hardy)
+#########################################################
+
+# List of default encoding options, add to this list if you want more
+my %lameOptions = (
+"320" => ["-b 320 --ignore-tag-errors", ''],
+"V0" => ["-V 0 --vbr-new --ignore-tag-errors", ''],
+"V2" => ["-V 2 --vbr-new --ignore-tag-errors", '']
+);
+my $move_other = 0;
+
+# Ask for the directory containing the FLAC files
+my $dialog_flac = "zenity --file-selection --title 'FLAC directory' --directory";
+my $flac_dir = '';
+if (!($flac_dir = `$dialog_flac`)) {
+exit 0;
+}
+chomp($flac_dir);
+
+# Ask how the files should be encoded
+my $dialog_lame = "zenity --list --text 'LAME Options' --width 400 --height 300 --radiolist --column 'Choose' --column 'Option' TRUE";
+for my $lameOption ( keys %lameOptions ) {
+$dialog_lame .= " '" . $lameOption . "' FALSE";
+}
+$dialog_lame .= " 'All' FALSE 'Other'";
+my $lame_choice = '';
+if (!($lame_choice = `$dialog_lame`)) {
+exit 0;
+}
+chomp($lame_choice);
+if ($lame_choice eq 'Other') { # If other, present user with a text box to manually type in encoding options
+my $dialog_other = "zenity --entry --title 'LAME Options' --width 200 --text 'Please enter custom LAME encoder options'";
+if (!($lame_choice = `$dialog_other`)) {
+exit 0;
+}
+chomp($lame_choice);
+%lameOptions = ();
+%lameOptions = ( 'Custom' => [$lame_choice, ''] );
+} elsif ($lame_choice ne 'All') { # If a specific default encoding type is chosen, save it and remove the others
+my @temp = @{$lameOptions{$lame_choice}};
+%lameOptions = ();
+%lameOptions = ( $lame_choice => [$temp[0], ''] );
+}
+# If neither of the above, the array remains the same as all of the encoding types will be used
+
+# Ask if you would like to use default folder naming
+# Default folder naming places the files in a folder with this structure: "flac_dir (encoding_type)"
+my $dialog_type = "zenity --question --title 'MP3 Folder Naming' --text 'Use default folder naming?'";
+`$dialog_type`;
+if ($?) { # If not using default, ask the user which directory should be used for whichever encoding they chose
+foreach my $lame_option (keys %lameOptions) {
+my $dialog_mp3 = "zenity --file-selection --title 'MP3 directory for " . $lame_option . "' --directory";
+my $mp3_dir = '';
+if (!($mp3_dir = `$dialog_mp3`)) {
+exit 0;
+}
+chomp($mp3_dir);
+$lameOptions{ $lame_option }[1] = $mp3_dir;
+}
+} else { # If using default, make the directories using the default naming scheme
+foreach my $lame_option (keys %lameOptions) {
+my $mp3_dir = $flac_dir . " ($lame_option)";
+`mkdir "$mp3_dir"`;
+$lameOptions{ $lame_option }[1] = $mp3_dir;
+}
+}
+
+# Ask to move other files (playlists, image art, etc)
+my $dialog_move = "zenity --question --title 'Other Files' --text 'Move other non-FLAC files?'";
+`$dialog_move`;
+if (!$?) {
+$move_other = 1;
+}
+
+# Gather all of the flac files
+opendir(DIR, $flac_dir);
+my @files = grep(/\.flac$/,readdir(DIR));
+closedir(DIR);
+
+# Loop through each of the encodings chosen
+for my $lame_option ( keys %lameOptions ) {
+print "\nEncoding with $lame_option started...\n";
+
+# Pull out the directories and flags from the array
+my @mp3_arry = @{$lameOptions{$lame_option}};
+my $mp3_dir = $mp3_arry[1];
+my $lame_flags = $mp3_arry[0];
+
+# Loop through each of the FLAC files
+foreach my $file (@files) {
+# Create the destination mp3 filename
+my $mp3_filename = `basename "$file" .flac`;
+chomp($mp3_filename);
+$mp3_filename = $mp3_dir."/".$mp3_filename.".mp3";
+
+# Grab the tag info from the FLAC
+my %flac_tags = ('TITLE','','ALBUM','','ARTIST','','TRACKNUMBER','','GENRE','','COMMENT','','DATE','');
+for my $tag ( keys %flac_tags ) {
+$flac_tags{ $tag } = `metaflac --show-tag=$tag "$flac_dir/$file" | awk -F = '{ printf(\$2) }'`;
+}
+
+# Build the conversion script and do the actual conversion
+my $flac_command = "flac -dc \"$flac_dir/$file\" | lame $lame_flags " .
+"--tt \"" . $flac_tags{'TITLE'} . "\" " .
+"--tl \"" . $flac_tags{'ALBUM'} . "\" " .
+"--ta \"" . $flac_tags{'ARTIST'} . "\" " .
+"--tn \"" . $flac_tags{'TRACKNUMBER'} . "\" " .
+"--tg \"" . $flac_tags{'GENRE'} . "\" " .
+"--ty \"" . $flac_tags{'DATE'} . "\" " .
+"--add-id3v2 - \"$mp3_filename\" 2>&1";
+`$flac_command`;
+}
+
+print "\nEncoding with $lame_option finished...\n";
+
+# Move over any other files using rsync
+if ($move_other) {
+my $rsync_comm = "rsync -a --exclude \"*.flac\" \"$flac_dir/\" \"$mp3_dir/\"";
+`$rsync_comm`;
+}
+}
+
+print "\nAll encodings finished, bye...\n";
+
diff --git a/scripts/pgp/get-wkd-key b/scripts/pgp/get-wkd-key
new file mode 100755
index 00000000..98ee6165
--- /dev/null
+++ b/scripts/pgp/get-wkd-key
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# works for all DDs: `get-wkd-key foo@debian.org`
+
+gpg -v --auto-key-locate clear,wkd,nodefault --locate-key "$@"
diff --git a/scripts/pgp/offcaff b/scripts/pgp/offcaff
new file mode 100755
index 00000000..ef71398d
--- /dev/null
+++ b/scripts/pgp/offcaff
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# credits: David Bremner -- https://www.cs.unb.ca/~bremner/blog/posts/offcaff/
+
+infile=$1
+
+keys=$(gpg --with-colons $infile | sed -n 's/^pub//p' | cut -f5 -d: )
+
+gpg --homedir $HOME/.caff/gnupghome --import $infile
+
+caff -R -m no "${keys[*]}"
+
+today=$(date +"%Y-%m-%d")
+output="$(pwd)/keys-$today.tar"
+for key in ${keys[*]}; do
+ (cd $HOME/.caff/keys/; tar rvf "$output" $today/$key.mail*)
+done
diff --git a/scripts/pgp/preoffcaff b/scripts/pgp/preoffcaff
new file mode 100755
index 00000000..6913e1ce
--- /dev/null
+++ b/scripts/pgp/preoffcaff
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+set -e
+
+while read -r line; do
+ gpg --trust-model always --no-default-keyring \
+ --primary-keyring ~/tmp/offcaff.kbx \
+ --recv-key $line
+done
+
+gpg --trust-model always --no-default-keyring \
+ --primary-keyring ~/tmp/offcaff.kbx \
+ --output ~/tmp/offcaff.gpg \
+ --export
+
+rm ~/tmp/offcaff.kbx ~/tmp/offcaff.kbx~
+echo "file for sneakernet: ~/tmp/offcaff.gpg"
diff --git a/scripts/root/ps_mem.py b/scripts/root/ps_mem.py
new file mode 100755
index 00000000..a6bd1c58
--- /dev/null
+++ b/scripts/root/ps_mem.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+
+
+# Try to determine how much RAM is currently being used per program.
+# Note the per program, not per process. So for example this script
+# will report mem used by all httpd process together. In detail it reports:
+# sum(all RSS for process instances) + max(shared mem for any process instance)
+#
+# The shared calculation below will factor out shared text and
+# libs etc. within a program, but not between programs. So there
+# will always be some overestimation. This will be the same for
+# all processes that just use libc for e.g. but more for others
+# that use larger shared libs like gnome, kde etc.
+
+
+# Author: P@draigBrady.com
+
+# V1.0 06 Jul 2005 Initial release
+# V1.1 11 Aug 2006 root permission required for accuracy
+# V1.2 08 Nov 2006 Add total to output
+# Use KiB,MiB,... for units rather than K,M,...
+# V1.3 22 Nov 2006 Ignore shared col from /proc/$pid/statm for
+# 2.6 kernels up to and including 2.6.9.
+# There it represented the total file backed extent
+# V1.4 23 Nov 2006 Remove total from output as it's meaningless
+# (the shared values overlap with other programs).
+# Display the shared column. This extra info is
+# useful, especially as it overlaps between programs.
+# V1.5 26 Mar 2007 Remove redundant recursion from human()
+# V1.6 05 Jun 2007 Also report number of processes with a given name.
+# Patch from riccardo.murri@gmail.com
+
+# Notes:
+#
+# All interpreted programs where the interpreter is started
+# by the shell or with env, will be merged to the interpreter
+# (as that's what's given to exec). For e.g. all python programs
+# starting with "#!/usr/bin/env python" will be grouped under python.
+# You can change this by changing comm= to args= below but that will
+# have the undesirable affect of splitting up programs started with
+# differing parameters (for e.g. mingetty tty[1-6]).
+#
+# For 2.6 kernels up to and including 2.6.13 and later 2.4 redhat kernels
+# (rmap vm without smaps) it can not be accurately determined how many pages
+# are shared between processes in general or within a program in our case:
+# http://lkml.org/lkml/2005/7/6/250
+# A warning is printed if overestimation is possible.
+# In addition for 2.6 kernels up to 2.6.9 inclusive, the shared
+# value in /proc/$pid/statm is the total file-backed extent of a process.
+# We ignore that, introducing more overestimation, again printing a warning.
+#
+# I don't take account of memory allocated for a program
+# by other programs. For e.g. memory used in the X server for
+# a program could be determined, but is not.
+#
+# This script assumes threads are already merged by ps
+
+# TODO:
+#
+# use ps just to enumerate the pids and names
+# so as to remove the race between reading rss and shared values
+
+import sys, os, string
+
+if os.geteuid() != 0:
+ sys.stderr.write("Sorry, root permission required.\n");
+ sys.exit(1)
+
+PAGESIZE=os.sysconf("SC_PAGE_SIZE")/1024 #KiB
+our_pid=os.getpid()
+
+#(major,minor,release)
+def kernel_ver():
+ kv=open("/proc/sys/kernel/osrelease").readline().split(".")[:3]
+ for char in "-_":
+ kv[2]=kv[2].split(char)[0]
+ return (int(kv[0]), int(kv[1]), int(kv[2]))
+
+kv=kernel_ver()
+
+def getShared(pid):
+ if os.path.exists("/proc/"+str(pid)+"/smaps"):
+ shared_lines=[line
+ for line in open("/proc/"+str(pid)+"/smaps").readlines()
+ if line.find("Shared")!=-1]
+ return sum([int(line.split()[1]) for line in shared_lines])
+ elif (2,6,1) <= kv <= (2,6,9):
+ return 0 #lots of overestimation, but what can we do?
+ else:
+ return int(open("/proc/"+str(pid)+"/statm").readline().split()[2])*PAGESIZE
+
+cmds={}
+shareds={}
+count={}
+for line in os.popen("ps -e -o rss=,pid=,comm=").readlines():
+ size, pid, cmd = map(string.strip,line.strip().split(None,2))
+ if int(pid) == our_pid:
+ continue #no point counting this process
+ try:
+ shared=getShared(pid)
+ except:
+ continue #ps gone away
+ if shareds.get(cmd):
+ if shareds[cmd] < shared:
+ shareds[cmd]=shared
+ else:
+ shareds[cmd]=shared
+ #Note shared is always a subset of rss (trs is not always)
+ cmds[cmd]=cmds.setdefault(cmd,0)+int(size)-shared
+ if count.has_key(cmd):
+ count[cmd] += 1
+ else:
+ count[cmd] = 1
+
+#Add max shared mem for each program
+for cmd in cmds.keys():
+ cmds[cmd]=cmds[cmd]+shareds[cmd]
+
+sort_list = cmds.items()
+sort_list.sort(lambda x,y:cmp(x[1],y[1]))
+sort_list=filter(lambda x:x[1],sort_list) #get rid of zero sized processes (kernel threads)
+
+#The following matches "du -h" output
+#see also human.py
+def human(num, power="Ki"):
+ powers=["Ki","Mi","Gi","Ti"]
+ while num >= 1000: #4 digits
+ num /= 1024.0
+ power=powers[powers.index(power)+1]
+ return "%.1f %s" % (num,power)
+
+def cmd_with_count(cmd, count):
+ if count>1:
+ return "%s (%u)" % (cmd, count)
+ else:
+ return cmd
+print " Private + Shared = RAM used\tProgram \n"
+for cmd in sort_list:
+ print "%8sB + %8sB = %8sB\t%s" % (human(cmd[1]-shareds[cmd[0]]), human(shareds[cmd[0]]), human(cmd[1]),
+ cmd_with_count(cmd[0], count[cmd[0]]))
+print "\n Private + Shared = RAM used\tProgram \n"
+
+#Warn of possible inaccuracies
+#1 = accurate
+#0 = some shared mem not reported
+#-1= all shared mem not reported
+def shared_val_accurate():
+ """http://wiki.apache.org/spamassassin/TopSharedMemoryBug"""
+ if kv[:2] == (2,4):
+ if open("/proc/meminfo").read().find("Inact_") == -1:
+ return 1
+ return 0
+ elif kv[:2] == (2,6):
+ if os.path.exists("/proc/"+str(os.getpid())+"/smaps"):
+ return 1
+ if (2,6,1) <= kv <= (2,6,9):
+ return -1
+ return 0
+ else:
+ return 1
+
+vm_accuracy = shared_val_accurate()
+if vm_accuracy == -1:
+ sys.stderr.write("Warning: Shared memory is not reported by this system.\n")
+ sys.stderr.write("Values reported will be too large.\n")
+elif vm_accuracy == 0:
+ sys.stderr.write("Warning: Shared memory is not reported accurately by this system.\n")
+ sys.stderr.write("Values reported could be too large.\n")