summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2020-10-22 11:47:42 -0400
committerKjetil Orbekk <kj@orbekk.com>2020-10-22 11:47:42 -0400
commit4276ddd26a6841809199fd915cda0b0089173451 (patch)
tree786ea3897253464a200fc0bce2d7387c1ba18db9 /common
parent68908463d7676c35540fcea20ae70d177f49b053 (diff)
add zoxide
Diffstat (limited to 'common')
-rwxr-xr-xcommon/bin/P24
-rwxr-xr-xcommon/bin/askpass.sh2
-rwxr-xr-xcommon/bin/brightness.sh22
-rwxr-xr-xcommon/bin/dmenu_run.sh3
-rwxr-xr-xcommon/bin/kj-publish.sh3
-rwxr-xr-xcommon/bin/kj-setup.sh125
-rwxr-xr-xcommon/bin/kj-sync-keys.sh55
-rwxr-xr-xcommon/bin/media-filename-to-title.sh5
-rwxr-xr-xcommon/bin/pb2
-rwxr-xr-xcommon/bin/play-kj2
-rwxr-xr-xcommon/bin/play-yt6
-rwxr-xr-xcommon/bin/pod.sh251
-rwxr-xr-xcommon/bin/split-media-files.sh15
-rwxr-xr-xcommon/bin/tag2
-rwxr-xr-xcommon/bin/zoxidebin0 -> 2339944 bytes
15 files changed, 517 insertions, 0 deletions
diff --git a/common/bin/P b/common/bin/P
new file mode 100755
index 0000000..492d3d8
--- /dev/null
+++ b/common/bin/P
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+shopt -s nullglob globstar
+
+typeit=0
+if [[ $1 == "--type" ]]; then
+ typeit=1
+ shift
+fi
+
+prefix=${PASSWORD_STORE_DIR-~/.password-store}
+password_files=( "$prefix"/**/*.gpg )
+password_files=( "${password_files[@]#"$prefix"/}" )
+password_files=( "${password_files[@]%.gpg}" )
+
+password=$(printf '%s\n' "${password_files[@]}" | dmenu -fn "-*-*-*-*-*-*-20-*-*-*-*-*-*-*" "$@")
+
+[[ -n $password ]] || exit
+
+if [[ $typeit -eq 0 ]]; then
+ pass show -c "$password" 2>/dev/null
+else
+ xdotool - <<<"type --clearmodifiers -- $(pass show "$password" | head -n 1)"
+fi
diff --git a/common/bin/askpass.sh b/common/bin/askpass.sh
new file mode 100755
index 0000000..a6727b1
--- /dev/null
+++ b/common/bin/askpass.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+pass show machine/$(hostname)
diff --git a/common/bin/brightness.sh b/common/bin/brightness.sh
new file mode 100755
index 0000000..5cedc62
--- /dev/null
+++ b/common/bin/brightness.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+readonly XBACKLIGHT=xbacklight
+
+current_level=$($XBACKLIGHT)
+current_level=$((${current_level%.*}))
+
+if (( "$current_level" < 8 )); then
+ diff=1
+elif (( "$current_level" < 24 )); then
+ diff=6
+else
+ diff=10
+fi
+
+if [[ $1 == "+" ]]; then
+ $XBACKLIGHT -inc $diff
+elif [[ $1 == "-" ]]; then
+ $XBACKLIGHT -dec $diff
+else
+ echo "Usage: $0 +|-"
+ exit 1
+fi
diff --git a/common/bin/dmenu_run.sh b/common/bin/dmenu_run.sh
new file mode 100755
index 0000000..affa2af
--- /dev/null
+++ b/common/bin/dmenu_run.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+PATH=$HOME/dotfiles/bin:$HOME/bin:$PATH dmenu_run -fn -*-*-*-*-*-*-20-*-*-*-*-*-*-* "$@"
+
diff --git a/common/bin/kj-publish.sh b/common/bin/kj-publish.sh
new file mode 100755
index 0000000..e65716d
--- /dev/null
+++ b/common/bin/kj-publish.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+ssh orbekk@sabaki.orbekk.com ./build/org-publisher/publish.sh
diff --git a/common/bin/kj-setup.sh b/common/bin/kj-setup.sh
new file mode 100755
index 0000000..a7368be
--- /dev/null
+++ b/common/bin/kj-setup.sh
@@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+
+red='\e[0;31m'
+orange='\e[0;33m'
+green='\e[0;32m'
+none='\e[0m'
+
+cd
+# Check that things are in their right places.
+if [[ ! -f dotfiles/bin/kj-setup.sh ]]; then
+ printf "${red}[FAIL]${none} expected to find myself\n"
+ exit 1
+fi
+
+required_commands=(git basename)
+for command in ${required_commands[@]}; do
+ if ! which "${command}" >/dev/null; then
+ printf "${red}[FAIL]${none} ${command} not installed\n"
+ exit 1
+ fi
+done
+
+# cd ~/dotfiles
+# git submodule update --init --recursive
+# git submodule foreach git pull origin master
+
+cd
+# Creates a symlink with target $1 at location $2.
+# Does nothing and prints an error message if $2 exists and is not a symlink.
+create_symlink() {
+ if [[ -e "$2" && ! -h "$2" ]]; then
+ printf "${orange}[SKIPPED]${none} '$2' exists and is not a symlink.\n"
+ return
+ else
+ if ln -sf "$1" "$2"; then
+ printf "${green}[OK]${none} '$2' → '$1'\n"
+ else
+ printf "${red}[WARNING]${none} could not create '$2'\n"
+ fi
+ fi
+ if ! diff "$2" "$(dirname $2)/$1"; then
+ printf "${red}[WARNING]${none} diffs in $2\n"
+ fi
+}
+
+mkdir -p .config
+
+create_symlink dotfiles/Xresources .Xresources
+create_symlink dotfiles/gitconfig .gitconfig
+create_symlink dotfiles/taskrc .taskrc
+create_symlink dotfiles/tmux.conf .tmux.conf
+create_symlink dotfiles/spacemacs .spacemacs
+create_symlink /dev/null .vimrc.local
+create_symlink dotfiles/livestreamerrc .livestreamerrc
+
+if which fc-cache; then
+ create_symlink dotfiles/fonts .fonts
+ fc-cache -f -v
+fi
+
+mkdir -p .doom.d
+for f in dotfiles/doom.d/*; do
+ f=$(basename "${f}")
+ create_symlink "../dotfiles/doom.d/${f}" ".doom.d/${f}"
+done
+touch .doom.d/{config,init,packages}.local.el
+
+mkdir -p bin
+for binary in dotfiles/bin/*; do
+ binary=$(basename "${binary}")
+ create_symlink "../dotfiles/bin/${binary}" "bin/${binary}"
+done
+
+# Don't use these on new machines.
+# mkdir -p .config/fish/functions
+# create_symlink ../../dotfiles/config/fish/config.fish .config/fish/config.fish
+# for f in dotfiles/config/fish/functions/*.fish; do
+# create_symlink ../../../$f .config/fish/functions/$(basename $f)
+# done
+
+# create_symlink dotfiles/zshrc .zshrc
+create_symlink dotfiles/zshenv .zshenv
+
+mkdir -p .ssh
+create_symlink ../dotfiles/ssh/config .ssh/config
+
+mkdir -p .xmonad
+create_symlink ../dotfiles/xmonad/xmonad.hs .xmonad/xmonad.hs
+create_symlink dotfiles/xmonad/xmobar.hs .xmobarrc
+#create_symlink dotfiles/xsession .xsession
+
+mkdir -p .i3
+create_symlink ../dotfiles/i3/config .i3/config
+create_symlink dotfiles/i3status.conf .i3status.conf
+create_symlink dotfiles/i3blocks.conf .i3blocks.conf
+
+mkdir -p .urxvt/ext
+create_symlink ../../dotfiles/urxvt/ext/resize-font .urxvt/ext/resize-font
+create_symlink ../../dotfiles/urxvt/ext/clipboard .urxvt/ext/clipboard
+
+# Don't use on new machines.
+# create_symlink dotfiles/vimrc .vimrc
+# if [[ -e .vim/bundle/Vundle.vim ]]; then
+# printf "${orange}[SKIPPED]${none} Vundle.vim already installed\n"
+# else
+# success=1
+# mkdir -p .vim/bundle
+# git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim \
+# || success=0
+# fi
+# vim +PluginInstall +qall || success=0
+# if [[ "$success" == "1" ]]; then
+# printf "${green}[OK]${none} installed vim plugins\n"
+# else
+# printf "${red}[WARNING]${none} failed to install vim plugins\n"
+# fi
+
+if which emacs >/dev/null && [[ ! -d .emacs.d ]]; then
+ git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d
+fi
+
+if which xfconf-query; then
+ echo "disable xfce ssh-agent"
+ xfconf-query -c xfce4-session -p /startup/ssh-agent/enabled -n -t bool -s false
+fi
diff --git a/common/bin/kj-sync-keys.sh b/common/bin/kj-sync-keys.sh
new file mode 100755
index 0000000..8c71bdd
--- /dev/null
+++ b/common/bin/kj-sync-keys.sh
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+#
+# This script syncs authorized keys (found in the $authorized_keys_file below)
+# to a list of remote hosts. It does not touch existing keys unless overwrite
+# is set to true, but creates a special section containing the keys.
+
+declare -r begin_marker="### BEGIN MANAGED_BY_KJ_SYNC_AUTHORIZED_KEYS.SH ###"
+declare -r end_marker="### END MANAGED_BY_KJ_SYNC_AUTHORIZED_KEYS.SH ###"
+# If overwrite=true, the entire authorized_keys file is overwritten.
+declare -r overwrite=false
+declare -r tmpdir=$(mktemp -d /tmp/kj_sync_authorized_keys.XXXXX)
+
+targets=(
+ shape
+ sabaki
+ semeai
+ dragon
+ root@orbekk.osl.trygveandre.net
+ #login.pvv.ntnu.no
+ gote.orbekk.com
+)
+authorized_keys_file=$HOME/dotfiles/authorized_keys
+if [[ ! -f "${authorized_keys_file}" ]]; then
+ echo "could not find authorized_keys_file: ${authorized_keys_file}"
+ exit 1
+fi
+
+add_keys_to_file() {
+ local filename="$1"
+ awk \
+ "/$begin_marker/"' { exit 0 } { print }' \
+ ${filename} > ${filename}.header
+ awk \
+ "/$end_marker/"' { should_output=1 } !'"/$end_marker/"' { if (should_output) { print } }' \
+ ${filename} > ${filename}.footer
+
+ cat "${filename}.header" > ${filename}
+ echo "${begin_marker}" >> ${filename}
+ echo "# WARNING: ANY CHANGES WILL BE OVERWRITTEN" >> ${filename}
+ cat "$authorized_keys_file" >> ${filename}
+ echo "${end_marker}" >> ${filename}
+ cat "${filename}.footer" >> ${filename}
+}
+
+for target in ${targets[@]}; do
+ echo "syncing $target"
+ tmp="${tmpdir}/${target}"
+ touch ${tmp}
+ if [[ $overwrite != true ]]; then
+ ssh ${target} 'bash -c "cat .ssh/authorized_keys || echo -n"' > ${tmp}
+ fi
+ add_keys_to_file "${tmp}"
+ ssh ${target} 'mkdir -p .ssh'
+ cat "${tmp}" | ssh ${target} ' bash -c "cat > .ssh/authorized_keys.tmp && mv .ssh/authorized_keys{.tmp,}"'
+done
diff --git a/common/bin/media-filename-to-title.sh b/common/bin/media-filename-to-title.sh
new file mode 100755
index 0000000..38dadd2
--- /dev/null
+++ b/common/bin/media-filename-to-title.sh
@@ -0,0 +1,5 @@
+for f in *; do
+ ffmpeg -i "$f" -metadata title="$(basename $f)" -c copy "new_$f"
+ mv "new_$f" "$f"
+done
+
diff --git a/common/bin/pb b/common/bin/pb
new file mode 100755
index 0000000..21b9021
--- /dev/null
+++ b/common/bin/pb
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+curl -F c=@- https://ptpb.pw/
diff --git a/common/bin/play-kj b/common/bin/play-kj
new file mode 100755
index 0000000..3d3e192
--- /dev/null
+++ b/common/bin/play-kj
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+livestreamer "$(xclip -selection clipboard -out)" best \ No newline at end of file
diff --git a/common/bin/play-yt b/common/bin/play-yt
new file mode 100755
index 0000000..2830354
--- /dev/null
+++ b/common/bin/play-yt
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+rm /tmp/youtube.*
+youtube-dl -o /tmp/youtube "$@" &
+sleep 5s && mpv /tmp/youtube.*
+rm /tmp/youtube.*
diff --git a/common/bin/pod.sh b/common/bin/pod.sh
new file mode 100755
index 0000000..5f0d282
--- /dev/null
+++ b/common/bin/pod.sh
@@ -0,0 +1,251 @@
+#!/usr/bin/env bash
+
+PATH=$PATH:$(nix-build '<nixpkgs>' -A wget)/bin
+PATH=$PATH:$(nix-build '<nixpkgs>' -A libxslt.bin)/bin
+
+# Copyright (C) 2010-2015 Christophe Delord
+# http://www.cdsoft.fr/pod
+#
+# pod.sh is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# pod.sh 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with pod.sh. If not, see <http://www.gnu.org/licenses/>.
+
+# Original idea: BashPodder (http://lincgeek.org/bashpodder/)
+
+# audio and video directories
+PODCASTS=~/Podcasts
+AUDIO=Audio
+VIDEO=Video
+
+# Default tempo factor for mp3 files
+TEMPO=1 # listen podcasts 1.5 x faster
+
+# Database containing the already downloaded URLs
+DB=~/.poddb
+
+# Temporary files
+PARTIAL=/tmp/.pod
+
+# Get on screen notifications
+NOTIFICATION=true
+
+# The configuration file defines the URL of the RSS feeds.
+CONF=$PARTIAL/pod.conf
+mkdir -p $(dirname $CONF)
+cat <<EOF >$CONF
+# podcast name tempo[^1] URL
+
+SkepticsGuide http://www.theskepticsguide.org/feed
+
+#[1]: if tempo is not defined, $TEMPO is used as the default tempo
+#01netTV http://feeds.feedburner.com/LaChaineTechno?format=xml
+#12_Min http://feeds.feedburner.com/12minutesdemp3
+#56Kast http://www.liberation.fr/podcast/40/
+#AppLoad http://feeds2.feedburner.com/appload
+##Apprendre_l_anglais http://www.anglaispod.com/apprendre.xml
+##Atelier_Numérique http://podcast.bfmradio.fr/channel9/BFMchannel9.xml
+#Bazingcast http://feeds.feedburner.com/bazingcast_mp3
+#Ciel_et_Espace http://www.cieletespaceradio.fr/podcast.php
+#CONTINENT_SCIENCES http://radiofrance-podcast.net/podcast09/rss_16256.xml
+##Deconnecast http://www.deconnecast.fr/feed/
+#De_quoi_je_me_mail http://podcast.rmc.fr/channel35/RMCInfochannel35.xml
+#Divergence_Numérique http://podcasts.divergence-fm.org/divergencenumerique.xml
+##En_Flux_Libre http://enfluxlibre.tuxfamily.org/?feed=rss2
+#En_quête_de_science http://www.europe1.fr/podcasts/en-quete-de-science.xml
+#FSPod http://rss.futura-sciences.com/fs/podcast
+#Indesciences http://feeds.soundcloud.com/users/soundcloud:users:59221717/sounds.rss
+#Info_sciences http://radiofrance-podcast.net/podcast09/rss_11074.xml
+#La_folle_histoire_de_l_Univers http://www.florenceporcel.com/podcast/lfhdu.xml
+#La_Grotte_Du_Barbu http://feeds.feedburner.com/lagrottedubarbu/bPUL
+#LA_MARCHE_DES_SCIENCES http://radiofrance-podcast.net/podcast09/rss_11193.xml
+#L_apéro_du_Captain http://feeds.feedburner.com/LaperoDuCaptain
+##La_revue_du_net http://www.europe1.fr/podcasts/c-est-pas-tres-net.xml
+#La_science_en_question http://radiofrance-podcast.net/podcast09/rss_10336.xml
+#La_tête_au_carré http://radiofrance-podcast.net/podcast09/rss_10212
+##La_voix_du_libre-capsule http://feeds.feedburner.com/capsulemp3vdl?format=xml
+##La_voix_du_libre-entrevue http://feeds.feedburner.com/entrevuesoggvdl?format=xml
+##La_voix_du_libre http://feeds.feedburner.com/podcastoggvdl?format=xml
+##Le_7-9 http://radiofrance-podcast.net/podcast09/rss_11992.xml
+##Le_bruit_du_net http://radiofrance-podcast.net/podcast09/rss_11064.xml
+#L_écho_des_Gnous http://www.chtinux.org/podcast/feed.xml
+#L_éclectique_show http://feeds.feedburner.com/eclectiqueshow
+#Le_rendez-vous_Tech http://feeds2.feedburner.com/lerendezvoustech
+##Libre_FM http://s.libre.fm/podcast.rss
+##L_innovation_du_jour http://cdn-new-europe1.ladmedia.fr/var/exports/podcasts/sound/Innovation.xml
+#NipDev http://feeds.feedburner.com/NipDev
+#NipLife http://feeds.feedburner.com/NiptechPodcastNiplife
+#NipSource http://feeds.feedburner.com/NipcastNipsource
+#NipTech http://feeds.feedburner.com/niptechpodcast/
+#Nouveau_monde http://radiofrance-podcast.net/podcast09/rss_18998.xml
+#nouvo http://nouvo.ch/feeds/videos
+##Oh_La_Radio http://feeds.feedburner.com/OhLaRadio
+#Parole_de_Tux http://www.captainposix.net/RSSPodcast/feeditunes.xml
+#Podcast_Science http://feeds.feedburner.com/PodcastScience
+##Random_Radio http://fz-corp.net/podcast/podcast.xml
+##Revue_de_presque http://www.europe1.fr/podcasts/revue-de-presque.xml
+#Sang_libre 1 http://libre.tuxakadjseb.net/?feed=rss2
+#SCIENCE_PUBLIQUE http://radiofrance-podcast.net/podcast09/rss_10192.xml
+##Symbiose http://www.dogmazic.net/radio/groupePod.php?f=mp3&usr=&groupe=Symbiose
+##Un_jour_sur_la_toile http://radiofrance-podcast.net/podcast09/rss_10274.xml
+#Vie_artificielle http://feeds.feedburner.com/vieartificielle
+EOF
+
+PARSE=$PARTIAL/parse_enclosure.xsl
+mkdir -p $(dirname $PARSE)
+cat <<EOF >$PARSE
+<?xml version="1.0"?>
+<stylesheet version="1.0"
+ xmlns="http://www.w3.org/1999/XSL/Transform">
+ <output method="text"/>
+ <template match="/">
+ <apply-templates select="/rss/channel/item/enclosure"/>
+ </template>
+ <template match="enclosure">
+ <value-of select="@url"/><text>&#10;</text>
+ </template>
+</stylesheet>
+EOF
+
+mkdir -p $AUDIO
+mkdir -p $VIDEO
+
+echo "*** $(basename $0) ***"
+
+LOCKFILE=$PARTIAL/lock
+if [ -e $LOCKFILE ]
+then
+ echo "$(basename $0) is already running..."
+ exit 1
+fi
+trap "rm -f $LOCKFILE; rm -rf $PARTIAL; exit" EXIT INT TERM
+echo $$ > $LOCKFILE
+
+mkdir -p $PODCASTS/$AUDIO
+mkdir -p $PODCASTS/$VIDEO
+cd $PODCASTS
+
+mkdir -p $PARTIAL
+
+# The database must exist. Create it empty otherwise.
+touch $DB
+
+# Wait for an internet connection
+while ! wget -q --tries=10 --timeout=20 --spider http://google.com
+do
+ sleep 60
+done
+
+# number of episodes downloaded
+n=0
+
+# Parse each line of the configuration file
+cat $CONF | while read nom tempo podcast
+do
+ case "$podcast" in
+ "") # 2 arguments => the tempo is not defined, let take the default tempo ($TEMPO)
+ podcast=$tempo; tempo=$TEMPO
+ ;;
+ *) # 3 arguments => the tempo is defined for this podcast
+ ;;
+ esac
+ case "$nom" in
+ "") # empty line => ignored
+ ;;
+ \#*) # comment line => ignored
+ ;;
+ *) # line with a podcast RSS feed => parse the RSS feed and download new episodes
+ echo "* parse $nom ($podcast)"
+ # get all episodes
+ file=$(xsltproc $PARSE $podcast 2> /dev/null || wget -T 60 -t 1 -q $podcast -O - | tr '\r' '\n' | tr \' \" | sed -n "s/></>\n</gp" | sed -n 's/.*url="\([^"]*\)".*/\1/p')
+ for url in $file
+ do
+ case "$url" in
+ (*.jpg|*.jpeg|*.png|*.JPG|*.JPEG|*.gif) # ignore images
+ ;;
+ (*) # not an image, it may be something to watch or listen to
+ if ! grep -q "$url" $DB
+ then
+ # not in the database => new episode to download
+ echo "* $(basename $url)"
+ #echo "url = $url"
+ OUT=$nom-$(echo "$url" | awk -F'/' {'print $NF'} | awk -F'=' {'print $NF'} | awk -F'?' {'print $1'})
+ if wget -t 10 -c -q -O $PARTIAL/$OUT "$url"
+ then
+ NEW=$OUT
+ DATE=$(stat -c %y $PARTIAL/$OUT | sed 's/^..\(..\)-\(..\)-\(..\) \(..\):\(..\).*/\1\2\3\4\5/')
+ # Normalize the extension
+ NEW=${NEW/.MP3/.mp3}
+ NEW=${NEW/.MP4/.mp4}
+ # Speedup with the current tempo
+ case $NEW in
+ (*.mp4) # video are not accelerated
+ mv $PARTIAL/$OUT $PARTIAL/$DATE-$NEW
+ ;;
+ (*.mp3) # audio is accelerated according to the selected tempo
+ case $tempo in
+ (1) # tempo = 1 => no acceleration
+ mv $PARTIAL/$OUT $PARTIAL/$DATE-$NEW
+ ;;
+ (*) # tempo != 1 => acceleration
+ if (ffmpeg -i "$PARTIAL/$OUT" -filter:a "atempo=$tempo" -c:a libmp3lame -q:a 4 "$PARTIAL/$DATE-$NEW" > /dev/null 2> /dev/null)
+ then
+ touch -r "$PARTIAL/$OUT" "$PARTIAL/$DATE-$NEW"
+ else
+ rm -f "$PARTIAL/$DATE-$NEW"
+ fi
+ rm "$PARTIAL/$OUT"
+ ;;
+ esac
+ ;;
+ (*) # other file types are not accelerated
+ mv $PARTIAL/$OUT $PARTIAL/$DATE-$NEW
+ ;;
+ esac
+ if [ -e $PARTIAL/$DATE-$NEW ]
+ then
+ # copy audio and video episodes in $AUDIO and $VIDEO
+ case $NEW in
+ (*.mp3|*.ogg) mv $PARTIAL/$DATE-$NEW $PODCASTS/$AUDIO/$DATE-$NEW ;;
+ (*) mv $PARTIAL/$DATE-$NEW $PODCASTS/$VIDEO/$DATE-$NEW ;;
+ esac
+ $NOTIFICATION && notify-send -c transfer.complete "$nom: new podcast" "$NEW"
+ echo $url >> $DB
+ n=$((n+1))
+ fi
+ fi
+ fi
+ ;;
+ esac
+ done
+ ;;
+ esac
+done
+
+# done => remove configuration files
+rm -f $CONF $PARSE
+
+if [ $n -gt 0 ]
+then
+ [ $n -gt 1 ] && s="s" || s=""
+ $NOTIFICATION && notify-send -c transfer "Podcasts" "$n new episode$s downloaded"
+fi
+
+# remove lock and partially downloaded files, sleep for 2 hours and try again
+rm -f $LOCKFILE
+rm -rf $PARTIAL
+echo "*** done ($(date)) ***"
+# for some unexplained (yet) reasons, the main loop may be exited after some
+# episodes are downloaded. As a workaround the script is restarted immediately
+# when $n > 0 in case some new episodes were not downloaded.
+# When every is done; we wait for 2 hours before restarting.
+[ $n -gt 0 ] || sleep $((2*3600))
+exec $0 $*
diff --git a/common/bin/split-media-files.sh b/common/bin/split-media-files.sh
new file mode 100755
index 0000000..c680629
--- /dev/null
+++ b/common/bin/split-media-files.sh
@@ -0,0 +1,15 @@
+max_duration=$((4*3600))
+
+if [[ $# -ne 1 ]]; then
+ echo 1>&2 "Usage: $0 <media-file>"
+ exit 1
+fi
+
+input_file="$1"
+
+base="$(basename $input_file | perl -pe 's/(.*)\.([^.]*)$/$1/')"
+
+ffmpeg -i "${input_file}" \
+ -f segment -segment_time $max_duration -segment_start_number 1 \
+ -segment_format mp3 -qscale:a 5 \
+ "${base}-%02d.mp3"
diff --git a/common/bin/tag b/common/bin/tag
new file mode 100755
index 0000000..a95d525
--- /dev/null
+++ b/common/bin/tag
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+awk '/TAG/ {tag++; sub("TAG", tag);} { print };'
diff --git a/common/bin/zoxide b/common/bin/zoxide
new file mode 100755
index 0000000..4976d1e
--- /dev/null
+++ b/common/bin/zoxide
Binary files differ