vee/bin/vee

920 lines
34 KiB
Plaintext
Raw Permalink Normal View History

2020-07-10 22:47:12 -04:00
#!/bin/sh
VERSION=2.0-rc1
if [ ! "$EDITOR" ]; then
EDITOR=vi
fi
MARGIN=67
FORMAT=html
INDEX=vee.html
DIR=.vee
DRAFT="$DIR/.vee.tmp.$$"
USE_EDITOR=1
LISTENSTDIN=0
_CUSTOM_UMASK= # use -U to force to 0022 or -u to set something during post
PUBLISHED=$(date "+%m/%d/%Y") # date formated for index page entry
SORT_NEWEST="sort -t. -nr" # sorts all new to old
SORT_OLDEST="sort -t. -n" # sorts all old to new
RAWEXT=raw # default .raw (non-HTML) files, can change to .txt or something else in .veerc
# also used for updating $GOPHERMAP when $GOPHERMODE is 1 (-g) or 2 (-G)
DATE=$(date)
YEAR=$(date "+%Y")
TIME=$(date "+%Y-%m-%dT%H:%M:%S")
SEC=$(date "+%s")
TITLE=
DEFAULT_TITLE="Entry #$SEC (pid: $$)";
HEADERTXT= # text or $(cat some.header.txt)
FOOTERTXT="Powered by vee<br/>Copyright &copy; 2006-$YEAR"
TOP_TPL=./vee-top.tpl # if file exists, used to generate top of HTML post by OUTPUT_TOP func
BOT_TPL=./vee-bottom.tpl # if file exists, used to generate bottom of HTML post by OUTPUT_BOT func
OUTPUT_TOP=output_top # default template processor, uses TOP_TPL
OUTPUT_BOT=output_bottom # default template processor, use s BOT_TPL
# PRE/POST Format Hooks; used in both HTML and Gopher modes; to differentiate, $1 is always
# going to be 'html' or 'gopher'
PREFORMAT_HOOK=./vee-pre # the hook is assumed to be executable, else it is ignored
POSTFORMAT_HOOK=./vee-post # the hook is assumed to be executable, esle it is ignored
# Gopher defaults
GOPHERMODE=0 # -g set it to 1, -G sets it to 2; set in .veerc to skip always typing -g or -G
GOPHER_FORMAT=txt # extension for files linked in gophermap
GOPHERMAP=gophermap # pretty standard, so low chance of this needing to be changed
OUTPUT_TOP_GOPHER= # may define a top "template" function for gopher posts
OUTPUT_BOT_GOPHER= # may define a bottom "template" function for gopher posts
# gophermap header text and footer text - sorry didn't separate them out like was done
# for the HTML support (but these can be customized in a .veerc!)
GOPHERMAP_HEADER="Welcome to my Gophertunnel!"
GOPHERMAP_FOOTER="Carl Spackler: [preparing to dynamite the gopher tunnel] In the immortal words of Jean Paul Sartre, Au revoir, gopher."
guess_arch()
{ case $(uname) in
Linux) ARCH='linux'
;;
FreeBSD) ARCH='freebsd'
;;
NetBSD) ARCH='netbsd'
;;
Darwin) ARCH='macosx'
;;
*) ARCH='unknown'
;;
esac
}
ARCH='unknown'
guess_arch
# define custom formatting define custom functions file; see example in # vee/sample-custom-format/vee-custom.sh
FORMAT_FUNC=format_with_groff
FORMAT_DISPATCHER=default_set_format_func
FORMAT_CUSTOM_DISPATCHER=custom_set_format_func
FORMAT_CUSTOM_DEFS=./vee-custom.sh # path is relative to -d DIR, where .veerc resides
UPDATE_INDEX=default_update_index
CUSTOM_SETUP=default_setup
#
# vee is a zero configuration, commandline blog tool that
# requires NO installation other than dropping the vee
# script into your ~/bin, or someother directory in your PATH
#
# vee accepts input when in batch mode (-b), so it is well
# suited for use in batch situations, such as in a cronjob
#
# System utilities required via PATH:
# cat, cd, date, env, find, fmt, fold, grep, groff,
# head, ls, pwd, sort, tail, which
#
# vee provided utilities that must also be in PATH:
# vee (duh!), veels, veecat
#
disclaimer()
{ echo "Copyright (c) 2007-infinity /me"
echo "Permission is hereby granted, free of charge, to any person"
echo "obtaining a copy of this software and associated documentation"
echo "files (the \"Software\"), to deal in the Software without"
echo "restriction, including without limitation the rights to use,"
echo "copy, modify, merge, publish, distribute, sublicense, and/or"
echo "sell copies of the Software, and to permit persons to whom the"
echo "Software is furnished to do so, subject to the following"
echo "conditions:"
echo "The above copyright notice and this permission notice shall be"
echo "included in all copies or substantial portions of the Software."
echo "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY"
echo "KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE"
echo "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE"
echo "AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT"
echo "HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,"
echo "WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING"
echo "FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR"
echo "OTHER DEALINGS IN THE SOFTWARE."
}
#
# vee - the minimal, zero configuration command line blog thingy
#
# Contact (bugs, patches, suggestions)
# https://git.sdf.org/pifty/phlea/issues
#
# Instructions:
# 1. put in directory accessible via PATH
# 2. go to a web visible directory and type 'vee'
# 3. put in your title and write your post in vi
# 4. tell your mom to visit: http://..../yourdir/vee.html
# 5. tell your gen Z nephew to visit your gopherhole :E
#
# Tips:
#
# 1 You can force the index to be index.html using "-I", or
# you can specify the index with "-i somefile.html". But,
# if you do this, you'll have to specify this for all other
# commands, otherwise vee defaults to vee.html
#
# 2 vee respects your EDITOR environmental variable
#
# 3 What you do with vee.html or the formatting is up to you :)
#
# 4 Gopher support (-g|-G) may be lacking some parity with http/s
# support, but with feedback this can be fixed and go well beyond
#
# CREDITS
# Francois Saint-Jacques (fsaintjacques@networkdump.com) supplied 2nd patch ever :)
# efbeha (efbeha@gmail.com) - supplied first patch ever :)
# Oliver @ forums.bsdnexus.com
# arun @ chat.taucher.net #bsd
# J65nko @ bsdforums.com
default_set_format_func()
{ case $1 in
default) FORMAT_FUNC=format_with_groff
;;
groff) FORMAT_FUNC=format_with_groff
;;
fold) FORMAT_FUNC=format_with_fold
;;
fmt) FORMAT_FUNC=format_with_fmt
;;
none) FORMAT_FUNC=with_no_formatting
;;
# if not a supplied format, see if it is in the custom format file, if it exists
*) if [ -e "$FORMAT_CUSTOM_DEFS" ]; then
# call dispatch function that is defined in
# the custom format file, pass on format nickname
$FORMAT_CUSTOM_DISPATCHER "$1"
else
echo "bad format type"
die_cleanly
fi
esac
}
usage()
{ echo " "
echo " "
echo " .----------------. .----------------. .----------------. "
echo " | .--------------. || .--------------. || .--------------. | "
echo " | | ____ ____ | || | _________ | || | _________ | | "
echo " | ||_ _| |_ _| | || | |_ ___ | | || | |_ ___ | | | "
echo " | | \ \ / / | || | | |_ \_| | || | | |_ \_| | | "
echo " | | \ \ / / | || | | _| _ | || | | _| _ | | "
echo " | | \ ' / | || | _| |___/ | | || | _| |___/ | | | "
echo " | | \_/ | || | |_________| | || | |_________| | | "
echo " | | | || | | || | | | "
echo " | '--------------' || '--------------' || '--------------' | "
echo " '----------------' '----------------' '----------------' "
echo " the Zero-conf, commandline blog tool thingy "
echo " .... now with GopherMode! ("gopherlog" support) "
echo " (see -g|-G) "
echo " "
echo "Version: $VERSION "
echo " "
echo "Options: "
echo " -b Batch mode; used when piping in msg via stdin "
echo " -B file Define bottom template; default is ./vee-bottom.tpl "
echo " -c [1-9\d*] Specify the number of characters 'fold' allows per line "
echo " this only applies when 'fold' (-f) is used "
echo " -d 'publis_dir' Specify the directory .vee is in - defaults to PWD "
echo " -D Debug mode with, set -x "
echo " -f 'format' Option for setting formatinstead of the default, groff; "
echo " 'groff', 'fmt', 'fold', and 'none' are all supported "
echo " -g Update the gophermap file with the INDEX "
echo " -G Exclusively update the gophermap file rather than INDEX "
echo " Note: for -g|-G, the gophermap is merely appended to, there"
echo " is no maintaining of the order from newest first to last; "
echo " -g|-G will create the gophermap if it isn't found. "
echo " -h Prints this blurb "
echo " -i 'custom.html' Specify a custom index file over the default "
echo " -I force index file to be \"index.html\" "
echo " -l edit latest post's *.raw; used with '-r' publishes changes;"
echo " calls reformat automatically; "
echo " -L [1-9\d*] edit the Nth latest, relative to last post; lp starts at 1"
echo " -m 'message ...' Epecify entry message at commandline and avoid vi "
echo " -n Lists all entries, newest first, then quits "
echo " -o Lists all entries, oldest first, then quits "
echo " -p See what *raw files don't have an entry in the INDEX "
echo " -P Forever deletes all *raw and formatted files associated with"
echo " posts that are listed with -p; "
echo " -r [1-9\d*] Reformats the Nth latest post "
echo " -R reformats _all_ .vee/*.raw files; -c applies as well "
echo " -s 'summary' Placed below title in INDEX "
echo " -t 'title' Specify title at commandline and avoid annoying default prompt"
echo " -T file Define top template; default is ./vee-top.tpl "
echo " -u <octal> Temporarily set umask to <octal> "
echo " -U Temporarily set umask to 0022 "
echo " -v Version and exit "
echo " -x hook Defines hook if not using default "./vee-pre"; hook "
echo " must be executable, i.e., chmod 755 vee-pre "
echo " "
echo "Examples: "
echo " "
echo "%vee "
echo " "
echo " user will be prompted for title and presented with vi "
echo " "
echo " if no default dir/files are found, they will be created "
echo " "
echo "%vee -t \"this is the title\" "
echo " "
echo " user will just be presented with a vi session; "
echo " "
echo "%cat text.txt | vee -b -t \"my title\" -m \"text to go before stdin\" "
echo " "
echo " This publishes contents of text.txt with provided title; -m's msg will be "
echo " shown above the cat'd text. This means of publishing content is well suited "
echo " for use with cronjobs or batch processes. It also works when GopherMode! is "
echo " invoked (-g|-G). "
echo " "
echo "%vee -l # edit and reformat the latest post "
echo "%vee -L 5 # allows one to edit and reformats the fifth latest post "
echo "%vee -r 8 # reformats the 8th latest post "
echo "%vee -n # see which post is the 8th latest post "
echo "%vee -R # reformats ALL posts that have *.raw files "
echo " "
echo "To delete a post forever: "
echo " "
echo "1) delete the entry in the INDEX "
echo " "
echo "2) purge the entry: "
echo " %vee -p # make sure it is the one you want to purge "
echo " %vee -P # purge it! "
echo " "
echo " brings up the latest entry as a vi sessions; when changes are save, "
echo " all messages are reformatted "
echo " "
echo " :E We Need to Talk About Gopher Support :E "
echo " "
echo "vee supports the creation of content in the gophersphere by formatting text-only"
echo "posts using the provided formatters (meant for text-only anyway). vee also goes"
echo "a step further and generates the gophermap (index listing) for you. "
echo " "
echo "All of the vee commands immediately above *should* work when GopherMode! is on"
echo "which is as simple as adding the -g xor -G flags. -g invokes the Gopher bits "
echo "*and* the default www support. -G only invokes the Gopher bits. Not using -g "
echo " or -G only involes the traditional www support. "
echo " "
echo "Usage examples from above, with GopherMode! enabled: "
echo " "
echo "%vee -l -G # edit and reformat the latest post "
echo "%vee -L 5 -g # allows one to edit and reformats the fifth latest post "
echo "%vee -r 8 -G # reformats the 8th latest post "
echo "%vee -n # see which post is the 8th latest post "
echo "%vee -R -g # reformats ALL posts that have *.raw files "
echo " "
echo "Notes: "
echo " "
echo "0. Reminder - vee requires zero configurations to start, but *can* be coed "
echo " by creating a .veerc file. This is also the case when in GopherGeb!Mode "
echo " "
echo "1. Batch mode looks for piped input via STDIN; if none after a short time, "
echo " message creation fails UNLESS something was passed in via '-m' as well. "
echo " If nothing was passed in via '-t' for the title, some default is used; "
echo " This is set at the top of the script as 'DEFAULT_TITLE'. "
echo " "
echo "2. Interactive mode (default) prompts for a title if no '-t' is provided. "
echo " Such is the case even if '-m' is used. If '-m' is not used in this "
echo " "
echo "3. Gopher support (-g|-G) is limited and users may discover weird issues with "
echo " updating posts or the batch reformatting options. It's a best effort. Also "
echo " the gophermap is fully regenerated whenever a new post is added; for a large"
echo " number of posts this may take a few seconds. "
echo " "
echo "4. Patches are welcome; the goal is not more feature bloat, but a nicer "
echo " way of dealing with STDIN, etc and reports/fixes for any weird gopher phlog"
echo " bugs or UX would be greatly welcomed. vee development laid dormant for years,"
echo " being used as a niche static site generator. But the rediscovery of Gopher "
echo " by the masses has made adding Gopher support a high priority. "
echo " "
disclaimer
exit 1
}
default_update_html_index()
{ echo "<!-- ;$SEC; -->$PUBLISHED:<a href=\"$1\"> $3</a>" >> $INDEX
if [ -n "$SUMMARY" ]; then
SEC=$(expr "$SEC" - 1)
echo "<!-- ;$SEC; -->$SUMMARY" >> "$INDEX"
fi
}
default_update_gophermap()
{ # rebuild the entire $GOPHERMAP
# toggle IFS if in -b mode
if [ 1 -eq $LISTENSTDIN ]; then
_OLDIFS=$IFS
IFS=$OLDIFS
fi
if [ -e $GOPHERMAP ]; then
echo Found existing $GOPHERMAP, renaming to $GOPHERMAP.bkp
mv $GOPHERMAP $GOPHERMAP.bkp #(be nice, just move to the side)
fi
default_setup_gophermap # initialize gophermap
for f in $(veels -d "$DIR" -e "$GOPHER_FORMAT"); do
_RAW=$(echo $f | sed 's/$GOPHER_FORMAT/$RAWEXT/')
_TITLE=$(echo $_RAW | veecat -t)
_DATE=$(echo $_RAW | veecat -d | awk '{print $3 " " $2 " " $6}') #e.g., Fri May 29 09:02:12 UTC 2020
# creating a symlink to $DIR because the default $DIR
# starts with a '.' and the gopher server seems to not
# want to serve files in such a directory
fileLink=$(echo $f | sed "s/$DIR/phlogsrc/")
# seems relative paths can't be directories that start
# with a dot (e.g., ".vee")
ln -s $DIR phlogsrc > /dev/null 2>&1 # rather than check if link exists, just try it and hide error
printf "0[$_DATE] $_TITLE\t$fileLink\n" >> $GOPHERMAP
done
echo >> $GOPHERMAP
echo >> $GOPHERMAP
echo $GOPHERMAP_FOOTER | fmt -w 67 >> $GOPHERMAP
echo >> $GOPHERMAP
echo >> $GOPHERMAP
echo Generated with vee. >> $GOPHERMAP
# toggle IFS back if temporarily set to interactive IFS above
if [ 1 -eq $LISTENSTDIN ]; then
IFS=$_OLDIFS
fi
}
#"$FINAL" "$gFINAL" "$RAW" "$gRAW" "$TITLE"
default_update_index()
{
if [ 2 != $GOPHERMODE ]; then
default_update_html_index "$1" "$3" "$5"
fi
if [ 0 != $GOPHERMODE ]; then
default_update_gophermap "$2" "$4" "$5"
fi
}
output_top()
{ echo "$HEADERTXT" > "$FINAL"
if [ -e "$TOP_TPL" ]; then
cat "$TOP_TPL" >> "$FINAL"
else
echo "<!-- <?xml version=\"1.0\" encoding=\"UTF-8\" ?> --><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\">" >> "$FINAL"
echo "<meta http-equiv=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">" >> "$FINAL"
echo " <head><title>$TITLE - $DATE</title></head>" >> "$FINAL"
echo " <body>" >> "$FINAL"
echo " <pre>" >> "$FINAL"
echo "<a href=\"../$INDEX\">[index]</a><a href=\"./$RAWNAME\">[raw]</a><a href=\"../\">[main]</a>" >> "$FINAL"
fi
echo >> "$FINAL"
}
output_bottom()
{ echo >> "$FINAL"
echo -- >> "$FINAL"
echo "$FOOTERTXT" >> "$FINAL"
if [ -e "$BOT_TPL" ]; then
cat "$BOT_TPL" >> "$FINAL"
else
echo " </pre>" >> "$FINAL"
echo " </body>" >> "$FINAL"
echo "</html>" >> "$FINAL"
fi
}
# begin formatting funcs
format_with_groff()
{ #sed 1liner from http://sed.sourceforge.net/sed1line.txt
if [ "html" = "$_OUTPUT_TYPE" ]; then
groff -man -Tascii "$RAW" > $$.tmp.$RAWEXT
sed '/^$/N;/\n$/D' < $$.tmp.$RAWEXT > $$.tmp.final
cat $$.tmp.final >> "$FINAL"
fi
if [ "gopher" = "$_OUTPUT_TYPE" ]; then
groff -man -Tascii "$gRAW" > $$.tmp.$RAWEXT
sed '/^$/N;/\n$/D' < $$.tmp.$RAWEXT > $$.tmp.final
cat $$.tmp.final > "$gFINAL"
fi
rm $$.tmp.$RAWEXT $$.tmp.final
}
format_with_fmt()
{ if [ 0 -lt $MARGIN ]; then
if [ "html" = $_OUTPUT_TYPE ]; then
fmt -w $MARGIN "$RAW" > $$.tmp.$RAWEXT
cat $$.tmp.$RAWEXT >> "$FINAL"
fi
if [ "gopher" = $_OUTPUT_TYPE ]; then
fmt -w $MARGIN "$gRAW" > $$.tmp.$RAWEXT
cat $$.tmp.$RAWEXT > "$gFINAL"
fi
rm $$.tmp.$RAWEXT
else
with_no_formatting
fi
}
format_with_fold()
{ if [ 0 -lt $MARGIN ]; then
if [ "html" = $_OUTPUT_TYPE ]; then
fold -s -w $MARGIN "$RAW" > $$.tmp.$RAWEXT
cat $$.tmp.$RAWEXT >> "$FINAL"
fi
if [ "gopher" = $_OUTPUT_TYPE ]; then
fold -s -w $MARGIN "$gRAW" > $$.tmp.$RAWEXT
cat $$.tmp.$RAWEXT > "$gFINAL"
fi
rm $$.tmp.$RAWEXT
else
with_no_formatting
fi
}
with_no_formatting()
{ if [ "html" = $_OUTPUT_TYPE ]; then
cat "$RAW" >> "$FINAL"
fi
if [ "gopher" = $_OUTPUT_TYPE ]; then
cat "$gRAW" > "$gFINAL"
fi
}
#
# preformat hook has been changed to NOT be a filter;
#
# $1 is 'html' or 'gopher'
#
preformat()
{ if [ -x "$PREFORMAT_HOOK" ]; then
"$PREFORMAT_HOOK" "$1"
fi
}
#
# this hook is for any things to do after the post; a good example for use
# would be to integrate git or another SCM; another is a notification script
#
# $1 is 'html' or 'gopher'
#
postformat()
{ if [ -x "$POSTFORMAT_HOOK" ]; then
"$POSTFORMAT_HOOK" "$1"
fi
}
# dispatches formatting based on $GOPHERMODE; sets $_OUTPUT_TYPE
# for called functions to know for what $_OUTPUT_TYPE they're doing stuff
format_main_html()
{ FINAL=$DIR/$1
FINALNAME=$1
RAW=$DIR/$2
RAWNAME=$2
preformat $_OUTPUT_TYPE # expecting 'html'
if [ ! -e "$RAW" ]; then
echo "$DATE" > "$RAW" # in RAW, line 1 is date
echo >> "$RAW"
echo "$TITLE" >> "$RAW" # in RAW, line 2 is title
echo >> "$RAW"
echo "--" >> "$RAW"
echo >> "$RAW" # this blank line is important
cat "$DRAFT" >> "$RAW"
fi
$OUTPUT_TOP
$FORMAT_FUNC
$OUTPUT_BOT
postformat $_OUTPUT_TYPE # expecting 'html'
}
format_main_gopher()
{ gFINAL=$DIR/$1
gFINALNAME=$1
gRAW=$DIR/$2
gRAWNAME=$2
preformat $_OUTPUT_TYPE # expecting 'gopher'
if [ ! -e "$gRAW" ]; then
echo "$DATE" > "$gRAW" # in gRAW, line 1 is date
echo >> "$gRAW"
echo "$TITLE" >> "$gRAW" # in gRAW, line 2 is title
echo >> "$gRAW"
echo "--" >> "$gRAW"
echo >> "$gRAW" # this blank line is important
cat "$DRAFT" >> "$gRAW"
fi
$OUTPUT_TOP_GOPHER # NOTE: not set by default
$FORMAT_FUNC
$OUTPUT_BOT_GOPHER # NOTE not set by default
postformat $_OUTPUT_TYPE # expecting 'gopher'
}
format_main()
{ if [ 2 != $GOPHERMODE ]; then
_OUTPUT_TYPE=html # tracks formatting type
format_main_html "$1" "$3"
fi
if [ 0 != $GOPHERMODE ]; then
_OUTPUT_TYPE=gopher # tracks formatting type
format_main_gopher "$2" "$3"
fi
_OUTPUT_TYPE=none
}
reformat_singleton()
{ if [ -e "$DIR/$1.$RAWEXT" ]; then
cat "$DIR/$1.$RAWEXT" > "$DRAFT"
format_main "$1.$FORMAT" "$1.$GOPHER_FORMAT" "$1.$RAWEXT"
fi
}
reformat_all()
{
for f in $(veels -d "$DIR" -r); do
# From: Randall R Schulz <rrschulz at cris dot com>
FULLNAME="$f"
DIR=${FULLNAME%/*}
FILE=${FULLNAME##*/}
MAXBASE=${FILE%.*}
MINBASE=${FILE%%.*}
MAXSUF=${FILE#*.}
MINSUF=${FILE##*.}
_TITLE=$(echo $f | veecat -t)
echo "..reformatting '$_TITLE'"
reformat_singleton "$MAXBASE"
done
}
list_newest_first()
{ COUNT=1
for _RAW in $(veels -d "$DIR"); do
_TITLE=$(echo $_RAW | veecat -t)
_DATE=$(echo $_RAW | veecat -d)
printf "%4d) " "$COUNT"
echo $_DATE - $_TITLE
COUNT=$(expr $COUNT + 1)
done
}
list_oldest_first()
{ COUNT=1
for _RAW in $(veels -d "$DIR" -r); do
_TITLE=$(echo $_RAW | veecat -t)
_DATE=$(echo $_RAW | veecat -d)
printf "%4d) " "$COUNT"
echo $_DATE - $_TITLE
COUNT=$(expr $COUNT + 1)
done
}
get_path2post()
{
GOAL=$1
COUNT=1
for FILE in $(veels -d "$DIR"); do
FULLNAME=$FILE
DIR=${FULLNAME%/*}
FILE=${FULLNAME##*/}
MAXBASE=${FILE%.*}
if [ "$COUNT" -eq "$GOAL" ]; then
echo "$MAXBASE"
break
fi
COUNT=$(expr "$COUNT" + 1)
done
}
purge_entries()
{ LEVEL=$1
COUNT=0
if [ ! -e "$INDEX" ]; then
echo "Can't find index, \"$INDEX\""
die_cleanly
fi
for FILE in $(veels -d "$DIR"); do
FULLNAME=$FILE
DIR=${FULLNAME%/*}
FILE=${FULLNAME##*/}
MAXBASE=${FILE%.*}
ENTRY=$(grep "$MAXBASE" "$INDEX")
if [ -z "$ENTRY" ]; then
COUNT=$(expr "$COUNT" + 1)
if [ "$LEVEL" -eq 1 ]; then
echo "$DIR/$FILE (not really purged, use -P for realz)"
elif [ "$LEVEL" -eq 2 ]; then
echo "$DIR/$MAXBASE[.$RAWEXT,$FORMAT] (delebed)"
rm -f "$DIR/$MAXBASE"*
fi
fi
done
if [ "$LEVEL" -eq 1 ]; then
echo "use -P to remove all $COUNT entrie(s)"
elif [ "$LEVEL" -eq 2 ]; then
echo "removed $COUNT entrie(s)..."
fi
}
die_cleanly()
{ if [ -e "$DRAFT" ]; then
rm -f "$DRAFT"
fi
exit 0
}
_POST2REFORMAT=0
_REFORMATALL=0
_PURGELEVEL=0
_POST2EDIT=0
SUMMARY=
MESSAGE=
SET_DEFAULT_FORMAT_FUNC=
# get opts ! stdin append to anything passed in by -m
while getopts 'DgGf:m:t:T:c:d:i:IbB:hRr:lL:novx:X:Pps:u:U' option; do
case $option in
u) _CUSTOM_UMASK=$OPTARG
;;
U) _CUSTOM_UMASK=0022
;;
D) set -x
echo Setting debug mode with, set -x
;;
g) # Gopher mode 1: output .txt and update $GOPHERMAP along side of HTML
GOPHERMODE=1
;;
G) # Gopher mode 2: treat as gopher phlog only (skip HTML stuff)
GOPHERMODE=2
;;
i) INDEX=$OPTARG # specify INDEX to $OPTARG
;;
I) INDEX="index.html" # force INDEX to index.html
;;
d) if [ -d "$OPTARG" ]; then
cd "$OPTARG"
else
echo "$OPTARG" is not a directory!
die_cleanly
fi
;;
r) _POST2REFORMAT=$OPTARG
;;
R) _REFORMATALL=1
;;
b) LISTENSTDIN=1
USE_EDITOR=0
;;
B) BOT_TPL=$OPTARG
;;
f) SET_DEFAULT_FORMAT_FUNC=$OPTARG
;;
c) MARGIN=$OPTARG
;;
l) _POST2EDIT=1
;;
L) _POST2EDIT=$OPTARG
;;
m) MESSAGE=$OPTARG
USE_EDITOR=0
;;
n) list_newest_first
die_cleanly
;;
o) list_oldest_first
die_cleanly
;;
s) SUMMARY=$OPTARG
;;
t) TITLE=$OPTARG
;;
T) TOP_TPL=$OPTARG
;;
v) echo $VERSION
die_cleanly
;;
p) _PURGELEVEL=1
;;
P) _PURGELEVEL=2
;;
h) usage | less
die_cleanly
;;
x) PREFORMAT_HOOK=$OPTARG
;;
?) #usage | less
die_cleanly
;;
esac
done
post_opts()
{
if [ -n "$_CUSTOM_UMASK" ]; then
umask "$_CUSTOM_UMASK"
fi
if [ $LISTENSTDIN -ne 1 ]; then
# brute check for umask 0022 if not using -b ($LISTENSTDIN -eq 1)
if [ $(umask) != "0022" ]; then
_default=yes
read -p "Would you like to temporarily set umask to 0022, to create files that are world readable [$_default]?" tmp_set_umask
if [ -z "$tmp_set_umask" ]; then
tmp_set_umask=$_default
fi
if [ "$tmp_set_umask" = "yes" ]; then
echo
umask 0022 && \
echo OK. To avoid this message in the future use -U, set umask in your login environment, or set the _CUSTOM_UMASK variable in your ./.veerc.
fi
fi
else
echo Warning: umask should be set to 0022. Your files may not be visible to others.
fi
if [ -e "$FORMAT_CUSTOM_DEFS" ]; then
. "$FORMAT_CUSTOM_DEFS"
fi
if [ -n "$SET_DEFAULT_FORMAT_FUNC" ]; then
"$FORMAT_DISPATCHER" "$SET_DEFAULT_FORMAT_FUNC" # default is set_format_func
fi
if [ "$_PURGELEVEL" -ge 1 ]; then
purge_entries "$_PURGELEVEL"
die_cleanly
fi
if [ "$_POST2EDIT" -ge 1 ]; then
LATEST=$(get_path2post "$_POST2EDIT")
$EDITOR "$DIR/$LATEST.$RAWEXT"
_POST2REFORMAT=$_POST2EDIT
fi
if [ "$_POST2REFORMAT" -ge 1 ]; then
LATEST=$(get_path2post "$_POST2REFORMAT")
reformat_singleton "$LATEST"
if [ 0 != $GOPHERMODE ]; then
default_update_gophermap
fi
die_cleanly
fi
# if "-R", or reformat all, is set
if [ "$_REFORMATALL" -eq 1 ]; then
# future may yield seperate "rebuild reindex" functionality
reformat_all
if [ 0 != $GOPHERMODE ]; then
default_update_gophermap
fi
die_cleanly
fi
# blocks vee -l (without the -r) from going on
if [ "$_POST2EDIT" -ge 1 ]; then
die_cleanly
fi
# Batch message creation: -m and stdin
# handles -m
if [ -n "$MESSAGE" ]; then
echo "$MESSAGE" >> "$DRAFT"
fi
if [ $LISTENSTDIN -eq 1 ]; then
OLDIFS=$IFS
IFS="" # ensures that leading spaces are retained
while read -r IN <&0 ; do # break after 1 sec of no stdin
echo "$IN" # echo's stdin back out so user can see
echo "$IN" >> "$DRAFT"
LISTENSTDIN=1
USE_EDITOR=0
done
fi
}
# generates INDEX file if none exists
default_setup_html()
{ if [ ! -e "$INDEX" ]; then
echo
echo "...creating $INDEX"
echo "<!-- ;10000000000000000000000000; open pre tag --><!-- <?xml version=\"1.0\" encoding=\"UTF-8\" ?> --><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>my vee index</title><meta http-equiv=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\"></head><body><pre>" >> "$INDEX"
# header stuff
echo "<!-- ;100000000000000000000000; fixed content -->" >> "$INDEX"
echo "<!-- ;10000000000000000000000; fixed content -->" >> "$INDEX"
echo "<!-- ;1000000000000000000000; fixed content -->" >> "$INDEX"
# footer stuff
echo "<!-- ;3; fixed content -->" >> "$INDEX"
echo "<!-- ;2; fixed content -->" >> "$INDEX"
echo "<!-- ;1; fixed content -->Powered by vee" >> "$INDEX"
echo "<!-- ;0; closing pre tag --></pre></body></html>" >> "$INDEX"
echo
fi
}
default_setup_gophermap()
{ if [ ! -e "$GOPHERMAP" ]; then
echo
echo "...generating updated $GOPHERMAP"
echo $GOPHERMAP_HEADER > $GOPHERMAP
echo >> $GOPHERMAP
echo >> $GOPHERMAP
fi
}
default_setup()
{
if [ 2 != $GOPHERMODE ]; then
default_setup_html
fi
if [ 0 != $GOPHERMODE ]; then
default_setup_gophermap
fi
}
use_editor()
{ if [ $USE_EDITOR -eq 1 ]; then
OK=0
$EDITOR "$DRAFT" && OK=1
if [ "$OK" -ne 1 ]; then
echo there has been a problem with your editor session
exit
fi
#else
#echo ...vi mode off
fi
}
# ask for title if not set with -t and not in batch mode
# if in batch mode with no -t set, use default title below
get_title()
{ if [ -z "$TITLE" ]; then
TITLE=$DEFAULT_TITLE
fi
}
read_config()
{ if [ -e ./.veerc ]; then
. ./.veerc
fi
}
# this case statement may be overkill if "sort -t';' -nr -k2,2" works across platforms
sort_index()
{ if [ -e "$INDEX" ]; then
case $ARCH in
linux) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted"
;;
freebsd) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted"
;;
netbsd) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted"
;;
macosx) # -k2,2 sorts by second field as delimted by -t';' - this may actually work
# for all platforms
sort -t';' -nr -k2,2 "$INDEX" > ".$INDEX.$$.sorted"
;;
*) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted"
;;
esac
mv ".$INDEX.$$.sorted" "$INDEX" # "rebuild $INDEX
fi
}
#-- main program body
mkdir -p "$DIR" || echo "found $DIR ..."
read_config # done after all options are read in, could look in -d before
# opts are processed though so opts could override defaults
# and config file .. yeah do that
post_opts # process options
"$CUSTOM_SETUP" # initialized indexes, can be defined in .veerc
get_title
use_editor
main()
{ if [ -e "$DRAFT" ]; then
RAWFILE="$SEC.$$.$TIME.$RAWEXT" # uses process id, $$, assuming there will
# not be duplicate process ids within 1 sec of each other
format_main "$SEC.$$.$TIME.$FORMAT" "$SEC.$$.$TIME.$GOPHER_FORMAT" "$RAWFILE"
"$UPDATE_INDEX" "$FINAL" "$gFINAL" "$RAW" "$gRAW" "$TITLE"
sort_index
die_cleanly
else
echo Error! "$DRAFT" not found
fi
}
main