--- /dev/null
+#!/bin/bash
+#
+# Support script for restoring individual directories and files
+#
+
+CONFIG=/etc/duplicity-daily.conf
+eval $(grep ^TARGET= $CONFIG)
+eval $(grep ^OPTIONS= $CONFIG)
+: ${RESTORE:=/restore}
+
+SRCS=( $(grep ^/ $CONFIG) )
+if [ -z "$SRCS" ] ; then
+ cat <<EOF
+** There are no backup sources.
+** Check /etc/duplicity-daily.conf
+EOF
+ exit 1
+fi
+echo "= Select backup set ==="
+select SRC in ${SRCS[@]} ; do [ -n "$SRC" ] && break ; done
+
+BASE="${SRC%=*}"
+if [ "$BASE" = "$SRC" ] ; then
+ URI="$TARGET$SRC"
+else
+ URI="${SRC#*=}"
+fi
+REMOTE="${URI%%/*}"
+STORE="${URI#*/}"
+
+## Check for existing backups
+TIMES=( $(ssh $REMOTE ls $STORE |grep sigtar |awk -F. '{ print $(NF-2); }') )
+if [ -z "$TIMES" ] ; then
+ cat <<EOF
+** No backups found for $SRC
+EOF
+ exit 0
+fi
+echo "= Select backup timestamp ==="
+select TIME in ${TIMES[@]} ; do [ -n "$TIME" ] && break ; done
+
+LIST=/tmp/restore-$$
+cleanup() {
+ rm -f $LIST
+}
+
+duplicity list-current-files $OPTIONS --time $TIME pexpect+scp://$URI |\
+ sed '1d;2d;3d;s/.\{25\}//' > $LIST
+
+echo
+
+# Restore pathname $1
+restore() {
+ local X
+ cat <<EOF
+Pathname = $1
+Restore at = $RESTORE/$TIME$BASE/$1
+Souce = $URI
+Options = $OPTIONS
+EOF
+ read -p "Go ahead [Yn]?" X
+ [ "$X" = n ] && return 0
+ duplicity restore $OPTIONS --file-to-restore "$1" --time "$TIME" \
+ "pexpect+scp://$URI" "$RESTORE/$TIME$BASE/$1"
+}
+
+# $1 root
+browse() {
+ local X Y
+ while true ; do
+ X="$(grep -oE "^$1[^/]*/?" < $LIST | uniq | iselect -fa)"
+ [ -z "$X" ] && break
+ if [ -z "${X##*/}" ] ; then
+ browse "$X"
+ else
+ restore "$X"
+ fi
+ done
+}
+
+browse
+cleanup