mirror of https://git.envs.net/envs/burrow.git
445 lines
10 KiB
Bash
Executable File
445 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
version="v1.2.4"
|
|
|
|
shopt -s extglob
|
|
configfiles="$HOME/.config/burrow/config $HOME/.config/burrow $HOME/.burrow"
|
|
editor=${EDITOR:-vi}
|
|
|
|
# vars from config
|
|
config_dir_gopher="$HOME/gopher/"
|
|
config_dir_recipebox="recipebox"
|
|
config_dir_phlog="phlog"
|
|
config_dir_topics="topics"
|
|
config_gopher_server="sdf.org"
|
|
config_gopher_port="70"
|
|
config_gopher_root="/users/username/"
|
|
config_phlog_gophermap=true
|
|
config_phlog_usedate=true
|
|
config_recipebox_gophermap=false
|
|
config_recipebox_usedate=false
|
|
config_topics_gophermap=true
|
|
config_topics_usedate=false
|
|
config_git_commit=false
|
|
config_git_push=false
|
|
config_autoindent=true
|
|
config_autofold=false
|
|
config_foldwidth=66
|
|
|
|
# vars from flags
|
|
flag_debug=0
|
|
flag_version=0
|
|
flag_help=0
|
|
flag_noautoindent=0
|
|
|
|
# vars from args
|
|
arg_options="hvd"
|
|
arg_longoptions="help,version,debug,noautoindent"
|
|
arg_shortlist=0
|
|
arg_recipe=0
|
|
arg_phlog=0
|
|
arg_topic=0
|
|
arg_create_config=0
|
|
arg_update_git=0
|
|
|
|
# silence directory movements
|
|
pushd () {
|
|
command pushd "$@" 2>/dev/null 1>&2
|
|
}
|
|
|
|
popd () {
|
|
command popd 2>/dev/null 1>&2
|
|
}
|
|
|
|
function show_help {
|
|
cat > /dev/stdout << END
|
|
burrow [options] [commands]
|
|
|
|
COMMANDS:
|
|
phlog Create new phlog entry
|
|
recipe Add new recipe to box
|
|
topic Add or update a topic
|
|
create-config Create a default configuration file
|
|
update-git Silently pulls gopher git repo if it exists
|
|
|
|
OPTIONAL FLAGS:
|
|
-h, --help Show this help
|
|
-v, --version Show current version info
|
|
-d, --debug Debug mode
|
|
|
|
END
|
|
}
|
|
|
|
function parse_input {
|
|
getopt -T > /dev/null
|
|
if [ $? -eq 4 ]; then
|
|
# GNU enhanced getopt is available
|
|
parsed=$(getopt \
|
|
--options=$arg_options \
|
|
--longoptions=$arg_longoptions \
|
|
--name "$0" \
|
|
-- "$@")
|
|
else
|
|
# Original getopt is available
|
|
parsed=$(getopt $arg_options "$@")
|
|
fi
|
|
|
|
if [[ $? -ne 0 ]]; then
|
|
die "Invalid input" 2
|
|
fi
|
|
|
|
eval set -- "$parsed"
|
|
|
|
while true; do
|
|
case "$1" in
|
|
-h|--help)
|
|
flag_help=1
|
|
shift
|
|
;;
|
|
-v|--version)
|
|
flag_version=1
|
|
shift
|
|
;;
|
|
-d|--debug)
|
|
flag_debug=1
|
|
shift
|
|
;;
|
|
--noautoindent)
|
|
flag_noautoindent=1
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
*)
|
|
die "Internal error: $1" 3
|
|
;;
|
|
esac
|
|
done
|
|
|
|
for arg in "$@"; do
|
|
argc=${arg,,}
|
|
case $argc in
|
|
"shortlist") arg_shortlist=1 ;;
|
|
"phlog") arg_phlog=1 ;;
|
|
"recipe") arg_recipe=1 ;;
|
|
"topic") arg_topic=1 ;;
|
|
"create-config") arg_create_config=1 ;;
|
|
"update-git") arg_update_git=1 ;;
|
|
*) echo "Unknown command: $arg";;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function day_suffix {
|
|
case $(date +%d) in
|
|
01|1|21|31) echo "st";;
|
|
02|2|22) echo "nd";;
|
|
03|3|23) echo "rd";;
|
|
*) echo "th";;
|
|
esac
|
|
}
|
|
|
|
function update_gopher_date {
|
|
newdate=$(date +"%B %d$(day_suffix), %Y")
|
|
sed -i "s/.*Last\ Updated:.*/ ==== Last Updated: $newdate ====/" \
|
|
"${config_dir_gopher}/gophermap"
|
|
}
|
|
|
|
function check_directory {
|
|
if [[ ! -d "$1" ]]; then
|
|
die "Missing directory: $1 aborting." 1
|
|
fi
|
|
}
|
|
|
|
function die {
|
|
msg="$1"
|
|
code="$2"
|
|
|
|
# exit code defaults to 1
|
|
if [[ "$code" =~ /^[0-9]+$/ ]] ; then
|
|
code=1
|
|
fi
|
|
|
|
# output message to stdout or stderr based on code
|
|
if [[ ! -z "$msg" ]]; then
|
|
if [[ "$code" == 0 ]]; then
|
|
echo "$msg"
|
|
else
|
|
echo "$msg" >&2
|
|
fi
|
|
fi
|
|
exit "$code"
|
|
}
|
|
|
|
function finish {
|
|
if [[ -f "$temp_gophermap" ]]; then
|
|
rm "$temp_gophermap"
|
|
fi
|
|
if [[ -f "$temp_links" ]]; then
|
|
rm "$temp_links"
|
|
fi
|
|
if [[ -f "$temp_fold" ]]; then
|
|
rm "$temp_fold"
|
|
fi
|
|
}
|
|
trap finish EXIT
|
|
|
|
function autofold {
|
|
file="$1"
|
|
if $config_autofold; then
|
|
temp_fold=$(mktemp -t "$(basename "$0").fold.XXXXXXX") || \
|
|
die "Failed to create temporary file" 1
|
|
fold -s -w "$config_foldwidth" "$file" > "$temp_fold"
|
|
cat "$temp_fold" > "$file"
|
|
rm "$temp_fold"
|
|
fi
|
|
}
|
|
|
|
function make_post {
|
|
query="$1"
|
|
type="$2"
|
|
use_gophermap="$3"
|
|
use_date="$4"
|
|
update_root="$5"
|
|
|
|
check_directory "$config_dir_gopher"
|
|
check_directory "${config_dir_gopher}${type}"
|
|
|
|
read -r -e -p "$query" title
|
|
if [[ $title == "" ]]; then
|
|
die "Cancelled." 0
|
|
fi
|
|
|
|
type_gophermap="${config_dir_gopher}${type}/gophermap"
|
|
|
|
if $use_gophermap; then
|
|
title_slug=$(echo "${title}" | \
|
|
sed -E -e 's/[^[:alnum:]]/-/g' -e 's/^-+|-+$//g' | \
|
|
tr -s '-' | \
|
|
tr '[:upper:]' '[:lower:]')
|
|
if $use_date; then
|
|
post_dir="${config_dir_gopher}${type}/$(date +%Y%m%d)-$title_slug"
|
|
post_path="${config_gopher_root}${type}/$(date +%Y%m%d)-$title_slug"
|
|
else
|
|
post_dir="${config_dir_gopher}${type}/$title_slug"
|
|
post_path="${config_gopher_root}${type}/$title_slug"
|
|
fi
|
|
post_file="${post_dir}/gophermap"
|
|
post_file_path="${post_path}"
|
|
else
|
|
post_dir="${config_dir_gopher}${type}"
|
|
post_path="${config_gopher_root}${type}"
|
|
title_slug=$(echo "${title}" | \
|
|
sed -E -e 's/[^[:alnum:]]/-/g' -e 's/^-+|-+$//g' | \
|
|
tr -s '-' | \
|
|
tr '[:upper:]' '[:lower:]')
|
|
if $use_date; then
|
|
title_slug="$(date +%Y%m%d)-${title_slug}"
|
|
fi
|
|
post_file="${post_dir}/${title_slug}.txt"
|
|
post_file_path="${post_path}/${title_slug}.txt"
|
|
fi
|
|
|
|
if [[ -f $post_file ]]; then
|
|
$editor "$post_file"
|
|
else
|
|
mkdir -p "${post_dir}"
|
|
if [[ -f "${post_dir}/.template" ]]; then
|
|
cat "${post_dir}/.template" > "$post_file"
|
|
else
|
|
{
|
|
echo "----------------------------------------"
|
|
echo "$title"
|
|
if $use_date; then
|
|
date +"%B %d$(day_suffix), %Y"
|
|
fi
|
|
echo "----------------------------------------"
|
|
echo ""
|
|
echo ""
|
|
if $use_gophermap; then
|
|
echo "Links:"
|
|
echo ""
|
|
fi
|
|
} >> "$post_file"
|
|
fi
|
|
|
|
$editor "$post_file"
|
|
|
|
if $use_gophermap; then
|
|
if [[ $config_autoindent ]] && [[ $flag_noautoindent == 0 ]]; then
|
|
temp_links=$(mktemp -t "$(basename "$0").links.XXXXXXX") || \
|
|
die "Failed to create temporary file" 1
|
|
sed -n '/^Links:$/,$p' "$post_file" | tail -n +2 > "$temp_links"
|
|
sed -i '/^Links:$/,$d' "$post_file"
|
|
autofold "$post_file"
|
|
sed -i 's/^/ /' "$post_file"
|
|
cat "$temp_links" >> "$post_file"
|
|
rm "$temp_links"
|
|
fi
|
|
else
|
|
autofold "$post_file"
|
|
fi
|
|
|
|
temp_gophermap=$(mktemp -t "$(basename "$0").gophermap.XXXXXXX") || \
|
|
die "Failed to create temporary file" 1
|
|
|
|
if $use_gophermap; then
|
|
if $use_date; then
|
|
# if using gophermap and date
|
|
echo -e "1$(date +%Y-%m-%d) - $title\t${post_file_path}\t"\
|
|
"${config_gopher_server}\t${config_gopher_port}" > "$temp_gophermap"
|
|
else
|
|
# if using gophermap but not date
|
|
echo -e "1$title\t${post_file_path}\t"\
|
|
"${config_gopher_server}\t${config_gopher_port}" > "$temp_gophermap"
|
|
fi
|
|
else
|
|
if $use_date; then
|
|
# if not using gophermap but using date
|
|
echo -e "0$(date +%Y-%m-%d) - $title\t${post_file_path}\t"\
|
|
"${config_gopher_server}\t${config_gopher_port}" > "$temp_gophermap"
|
|
else
|
|
# if not using gophermap or date
|
|
echo -e "0$title\t${post_file_path}\t"\
|
|
"${config_gopher_server}\t${config_gopher_port}" > "$temp_gophermap"
|
|
fi
|
|
fi
|
|
|
|
cat "$type_gophermap" >> "$temp_gophermap"
|
|
cat "$temp_gophermap" > "$type_gophermap"
|
|
rm "$temp_gophermap"
|
|
|
|
# sort gophermap if not using date
|
|
if ! $use_date; then
|
|
sort -fo "${post_dir}/gophermap" "${post_dir}/gophermap"
|
|
fi
|
|
|
|
if $update_root; then
|
|
update_gopher_date
|
|
fi
|
|
|
|
if [[ $config_git_commit != false ]]; then
|
|
pushd "$config_dir_gopher"
|
|
git add "${post_dir}/gophermap" "${post_file}" "$type_gophermap"
|
|
if $update_root; then
|
|
git add "${config_dir_gopher}/gophermap"
|
|
fi
|
|
git commit -m "$type: $title"
|
|
if [[ $config_git_push != false ]]; then
|
|
git pull
|
|
git push
|
|
fi
|
|
popd
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function create_config {
|
|
if [[ ! -f "$HOME/.config/burrow/config" ]] && \
|
|
[[ ! -f "$HOME/.config/burrow" ]] && \
|
|
[[ ! -f "$HOME/.burrow" ]]; then
|
|
|
|
config="$HOME/.config/burrow/config"
|
|
mkdir -p "$(dirname "$config")"
|
|
{
|
|
echo "config_dir_gopher=\"$HOME/gopher/\""
|
|
echo ""
|
|
echo "config_gopher_server=\"sdf.org\""
|
|
echo "config_gopher_port=\"70\""
|
|
echo "config_gopher_root=\"/users/username/\""
|
|
echo ""
|
|
echo "config_dir_phlog=\"phlog\""
|
|
echo "config_phlog_gophermap=true"
|
|
echo "config_phlog_usedate=true"
|
|
echo ""
|
|
echo "config_dir_recipebox=\"recipebox\""
|
|
echo "config_recipebox_gophermap=false"
|
|
echo "config_recipebox_usedate=false"
|
|
echo ""
|
|
echo "config_dir_topics=\"topics\""
|
|
echo "config_topics_gophermap=true"
|
|
echo "config_topics_usedate=false"
|
|
echo ""
|
|
echo "config_git_commit=false"
|
|
echo "config_git_push=false"
|
|
echo ""
|
|
echo "config_autofold=false"
|
|
echo "config_foldwidth=66"
|
|
echo "config_autoindent=true"
|
|
} >> "$config"
|
|
else
|
|
echo "Configuration already exists."
|
|
fi
|
|
}
|
|
|
|
function update_git {
|
|
pushd "$config_dir_gopher"
|
|
if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) ]]; then
|
|
git pull -q
|
|
fi
|
|
popd
|
|
}
|
|
|
|
function main {
|
|
parse_input "$@"
|
|
|
|
if [[ $arg_shortlist -gt 0 ]]; then
|
|
die "phlog topic recipe create-config update-git -v -h -d --version \
|
|
--help --debug --noautoindent" 0
|
|
fi
|
|
|
|
if [[ $flag_version -gt 0 ]]; then
|
|
echo "$version"
|
|
fi
|
|
|
|
if [[ $flag_help -gt 0 ]]; then
|
|
show_help
|
|
fi
|
|
|
|
if [[ $flag_debug -gt 0 ]]; then
|
|
set -x
|
|
fi
|
|
|
|
if [[ $arg_create_config -gt 0 ]]; then
|
|
create_config
|
|
fi
|
|
|
|
for configfile in $configfiles; do
|
|
if [[ -f $configfile ]]; then
|
|
source "$configfile"
|
|
fi
|
|
done
|
|
|
|
if [[ ${arg_update_git} -gt 0 ]]; then
|
|
update_git
|
|
fi
|
|
|
|
if [[ ${arg_recipe} -gt 0 ]]; then
|
|
make_post "What is the name of your recipe? " \
|
|
"$config_dir_recipebox" \
|
|
"$config_recipebox_gophermap" \
|
|
"$config_recipebox_usedate" \
|
|
true
|
|
fi
|
|
|
|
if [[ ${arg_topic} -gt 0 ]]; then
|
|
make_post "What is the name of your topic? " \
|
|
"$config_dir_topics" \
|
|
"$config_topics_gophermap" \
|
|
"$config_topics_usedate" \
|
|
true
|
|
fi
|
|
|
|
if [[ ${arg_phlog} -gt 0 ]]; then
|
|
make_post "Enter a title for your post: " \
|
|
"$config_dir_phlog" \
|
|
"$config_phlog_gophermap" \
|
|
"$config_phlog_usedate" \
|
|
true
|
|
fi
|
|
}
|
|
|
|
main "$@"
|