#!/bin/bash
# net/webdav - WebDAV support
set -e
lib_load 'net/tool/rsync'
######
# Settings
net_webdav_client_packages=( cadaver )
######
# Library Configuration
net_webdav_config_init() {
lib_setting_vars webdav_host
lib_setting_vars --null webdav_port
lib_setting_vars --null webdav_root
webdav_host=localhost
# WebDAV property namespace
lib_setting_vars --null webdav_namespace
lib_setting_vars -ro webdav_netrc
lib_setting_vars -ro webdav_stagedir
lib_setting_vars -ro webdav_exportdir
webdav_exportdir='.'
}
net_webdav_config_check() {
webdav_netrc="${webdav_netrc:-${HOME}/.netrc}"
webdav_stagedir="${webdav_stagedir:-$script_tempdir/stage}"
}
######
# Internal Functions
run_cadaver() {
run_pushd "$webdav_stagedir"
run cadaver "$@"
run_popd
}
pipe_to_cadaver() {
local tmp
tmp=$(cmd_tempfile)
"$@" >"$tmp"
debug "running cadaver script:"$'\n'"$(<"$tmp")"
run_cadaver <"$tmp"
}
webdav_filename() {
echo "$1" \
| ( iconv -f utf-8 -t ascii//translit \
|| error "$1: unable to encode name" ) \
| sed -e 's, - ,-,g' -e 's, ,-,g' -e 's,\?,-,g'
}
######
# WebDAV CLI
# webdav_dispatch() - Runs a webdav command
webdav_dispatch() { lib_cmd_dispatch webdav "$@"; }
webdav_usage() {
cat <<USAGE
<cmd> ...
WebDAV Commands:
host ... Host credential commands
stage ... Staging directory commands
remote ... WebDAV remote/server commands
USAGE
}
######
# .netrc Management
webdav_host() { cmd_dispatch "$@"; }
webdav_host_usage() {
cat <<USAGE
WebDAV Host Commands:
init Creates empty host credential file
add <host> <user> <passwd> Adds credentials for a host
delete <host> Removes credentials for a host
USAGE
}
webdav_host_init() {
touch "$webdav_netrc"
chmod 600 "$webdav_netrc"
}
webdav_host_add() {
has_args "3" "$@"
local name=$1
local user=$2
local pass=$3
echo "machine $name login $user password $pass" >> "$webdav_netrc"
}
webdav_host_delete() {
has_args "1" "$@"
local name=$1
local tmp
tmp=$(cmd_tempfile)
grep -v "^machine $name " "$webdav_netrc" >"$tmp"
run mv "$tmp" "$webdav_netrc"
}
######
# Script generation
webdav_script_open() {
echo "lcd '$webdav_stagedir'"
local url="$webdav_host"
[ -z "$webdav_port" ] || url="$url:$webdav_port"
echo "open '$url'"
[ -z "$webdav_namespace" ] || echo "set namespace '$webdav_namespace'"
}
webdav_script_close() {
echo close
}
webdav_script_import_dir() {
echo "echo '$1: creating collection...'"
echo "mkcol '$1'"
}
webdav_script_import_file() {
echo "echo '$2: importing...'"
echo "put '$1' '$2'"
}
webdav_script_import_symlink() {
debug "$2: skipping symlink ($3)"
}
webdav_script_import_default() {
error "$2: unknown item type"
}
webdav_script_import_item() {
local src=$1
local dst="$webdav_root${src#$webdav_stagedir}"
if [ -d "$src" ]; then
webdav_script_import_dir "$dst"
elif [ -f "$src" ]; then
webdav_script_import_file "$src" "$dst"
elif [ -L "$src" ]; then
local tgt
tgt=$(readlink "$src")
webdav_script_import_symlink "$src" "$dst" "$tgt"
else
webdav_script_import_default "$src" "$dst"
fi
}
webdav_script_import() {
info "searching for files to stage..."
local -a files
webdav_stage_find files "$@"
echo 'echo "webdav import: connecting to server..."'
webdav_script_open
for_each webdav_script_import_item "${files[@]}"
echo 'echo "webdav import: cleaning up..."'
webdav_script_close
echo 'echo "webdav import: ... done."'
info "webdav import: ... found ${#files[@]} items!"
}
webdav_script_export() {
webdav_script_open
# TODO
webdav_script_close
}
######
# WebDAV Server Interface
webdav_remote() { cmd_dispatch "$@"; }
webdav_remote_usage() {
cat <<USAGE
...
WebDAV Remote Commands:
import [<path>+] Imports from staging to WebDAV server
export [<path>+] Exports from WebDAV server to staging
USAGE
}
webdav_remote_import() { pipe_to_cadaver webdav_script_import "$@"; }
webdav_remote_export() { pipe_to_cadaver webdav_script_export "$@"; }
######
# WebDAV Staging interface
webdav_stage_filename() { echo "$webdav_stagedir/$(webdav_filename "$1")"; }
webdav_stage_relname() { echo "${1#$webdav_stagedir}"; }
webdav_stage() { cmd_dispatch "$@"; }
webdav_stage_usage() {
cat <<USAGE
<cmd> ...
WebDAV Staging Commands:
list [<path>+] Lists files in stanging directory
import <path>+ Imports files to staging directory
export [<path>+] Exports files to \$webdav_exportdir'
(default: $webdav_exportdir)
shell [<path>] Starts shell in "\$stagedir\$path"
WebDAV Staging Synchronization:
push [<path>+] Uploads files from staging to server
fetch [<path>+] Downloads files from server to staging
USAGE
}
webdav_stage_find() {
min_args 1 "$@"
local var=$1
shift
local -a wsf_files=( "$@" )
[ "$*" ] || wsf_files=( "" )
list_map webdav_stage_filename wsf_files
file_find wsf_files "${wsf_files[@]}"
eval "$var=( \"\${wsf_files[@]}\" )"
}
webdav_stage_findrel() {
local var=$1
webdav_stage_find "$@"
list_map webdav_stage_relname $var
}
webdav_stage_shell() {
local path=$1
run_pushd "$(webdav_stage_filename "$path")"
$SHELL
run_popd
}
webdav_stage_list() {
local -a file_find_opts=( -type f )
local -a files
webdav_stage_findrel files "$@"
local IFS=$'\n'
echo "${files[*]}"
}
webdav_stage_import() {
min_args 1 "$@"
local -a files
file_find files "$@"
run_mkdir "$webdav_stagedir"
for_each webdav_stage_import_file "${files[@]}"
}
webdav_stage_import_file() {
local src=$1
local dst
dst="$(webdav_stage_filename "$src")"
run_mkdir "$(dirname "$dst")"
rsync_run --archive "$src" "$dst"
}
webdav_stage_export() {
: # TODO
}
webdav_stage_push() {
local ssh_host="$webdav_host"
run_ssh mkdir -p "$webdav_stagedir"
if [ "$*" ]; then
for_each webdav_stage_push_part "$@"
else
webdav_stage_push_part "/"
fi
}
webdav_stage_push_part() {
has_args 1 "$@"
local part=$1
[ "${part#/}" != "$part" ] || part="/$part"
local src="$webdav_stagedir$part"
local dst="$webdav_host:$webdav_stagedir$part"
local -a opts=( --archive --checksum --progress --stats --links )
rsync_run "${opts[@]}" "$src" "$dst"
}
webdav_stage_fetch() {
: # TODO
}
Generated on Wed Jun 28 07:40:14 PDT 2017 by mcsh d14 v0.20.0.