#!/bin/sh
#####################################################################
# tirph - Generate TIR gophermap from file system on SDF
#
# Copyright 2010 David Meyer. All rights reserved.  +JMJ
# 
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials
#    provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
#####################################################################

# Identification ####################################################

PROGRAM='tirph'
VERSION=1.0
COPYRIGHT='Copyright 2010 David Meyer'
DESCRIPTION='Generate TIR gophermap from file system on SDF'
USAGE="Usage: $PROGRAM [-CPVh] [-n NUM] [-o OUTFILE] [-p PHLOGDIR] [DIR]"
CONTACT='David Meyer <papa@freeshell.org>'

# Initialize environment ############################################

IFS=" 	
"
PATH=/bin:/usr/bin:/usr/pkg/bin

SERVER=sdf.org
PORT=70
NEXUSSEL=/users/$USER
NEXUSPATH=/ftp/pub/users/$USER

FORTUNE=/usr/games/fortune

# Arguments #########################################################

while getopts CPn:o:p:Vh option; do
    case $option in
	C ) NOCONTENTS=1 ;;
	P ) NOPHLOG=1 ;;
	n ) NUM=$OPTARG ;;
	o ) OUTFN=$OPTARG ;;
	p ) PHLOGDIR=$OPTARG ;;
	V ) echo "$PROGRAM $VERSION"
	    echo $COPYRIGHT
	    exit 0
	    ;;
	h ) cat << ENDHELP
$USAGE

$DESCRIPTION.

DIR ...

Options are as follows:
-p PHLOGDIR
-n NUM
-o OUTFN
-C	Suppress output of directory contents section.
-P	Suppress output of phlog section.
-V	Display version number
-h	Display this help message

Files:
DIR/.title
DIR/.descripton
DIR/.gophhead
DIR/.gophfoot
DIR/.exits

Report bugs to $CONTACT.
ENDHELP
		exit 0
		;;
	* )	echo $USAGE >&2
		exit 1
		;;
	esac
done

shift $(( $OPTIND-1 ))

DIR=${1:-""}
: ${NUM:=10}
: ${OUTFN:=gophermap}
: ${PHLOGDIR:=""}

# Functions #########################################################

# ftitle() - Return title for file or subdirectory
ftitle() {
    bn=$(basename $1)
    if [ -d $1 ]; then
	if [ -f $1/.title ]; then
	    ftitle=$(cat $1/.title)
	else
	    ftitle=$bn
	fi
    else
	fn=${bn%.*}
	fext=${bn##*.}
	case $fext in
	    txt | org | blink )
		ftitle=$(head -n 1 $1)
		;;
	    html | htm | shtml )
		ftitle=$(grep -i "\<h1\>" $1 | head -n 1 | sed -e "s;</*[hH]1>;;g")
		: ${ftitle:=$fn}
		;;
	    * )
		ftitle=$bn
		;;
	esac
    fi
    echo $ftitle
}

# gtype() - Return Gopher item type
gtype() {
    if [ -d $1 ]; then
	gtype=1
    else
	fext=${1##*.}
	case $fext in
	    txt | org )           gtype=0 ;;
	    html | htm | shtml | blink )  gtype=h ;;
	    jpg | jpeg | png )    gtype=I ;;
	    gif )                 gtype=g ;;
	    * )                   gtype=0 ;;
	esac
    fi
    echo $gtype
}

# blink_map() - Output gopher menu entry for blink file
blink_map() {
    bfile=$1
    btpre=${2:-""}
    btpost=${3:-""}
    btitle=""
    buri=""
    cat $bfile | while read bline; do
	if [ -z "$btitle" ]; then
	    btitle=$bline
	    if [ "$btpre" ]; then btitle="$btpre $btitle"; fi
	    if [ "$btpost" ]; then btitle="$btitle $btpost"; fi
	elif [ -z "$buri" ]; then
	    buri=$bline
	    echo "h$btitle	URL:$buri" >>$OUTFILE
	else
	    if [ "$buri" -a "$bline" ]; then
		echo $bline >>$OUTFILE
	    fi
	fi
    done
}

# Main driver #######################################################

if [ "$DIR" ]; then
    DIRPATH=$NEXUSPATH/$DIR
    DIRSEL=$NEXUSSEL/$DIR
else
    DIRPATH=$NEXUSPATH
    DIRSEL=$NEXUSSEL
fi

OUTFILE=$DIRPATH/$OUTFN

# Backup output file ...
if [ -f $OUTFILE ]; then
    mv $OUTFILE $OUTFILE~
    touch $OUTFILE
    chmod 750 $OUTFILE
fi

# Directory title ...
if [ -f $DIRPATH/.title ]; then
    cat $DIRPATH/.title >>$OUTFILE
    echo "" >>$OUTFILE
fi

# Directory description ...
if [ -f $DIRPATH/.description ]; then
    cat $DIRPATH/.description >>$OUTFILE
    echo "" >>$OUTFILE
fi

# Link to nexus directory (top)  ...
if [ "$DIR" ]; then
    echo "1(to nexus)	$NEXUSSEL	$SERVER	$PORT" >>$OUTFILE
    echo "" >>$OUTFILE
fi

# Gopher-specific header ...
if [ -f $DIRPATH/.gophhead ]; then
    cat $DIRPATH/.gophhead >>$OUTFILE
fi

# Phlog  ...
if [ -z "$NOPHLOG" ]; then
    if [ "$PHLOGDIR" ]; then
	PHLOGPATH=$NEXUSPATH/$PHLOGDIR
	PHLOGSEL=$NEXUSSEL/$PHLOGDIR
    else
	PHLOGPATH=$NEXUSPATH
	PHLOGSEL=$NEXUSSEL
    fi

    ls -lt $(find $PHLOGPATH -type f -name "[^\.]*") | grep -Ev "~$|#.*#$|gophermap$" | head -n $NUM | while read perm lc own gr sz t1 t2 t3 fn; do
	if [ -z "$phloginit" ]; then
	    echo "" >>$OUTFILE
	    echo "RECENT ACTIVITY:" >>$OUTFILE
	    phloginit=1
	fi
	ft=$(ftitle $fn)
	loc=$(basename $(dirname $fn))
	case $fn in
	    *.blink ) 
		blink_map $fn "$t1 $t2 $t3" "[$loc]" >>$OUTFILE 
		;;
	    * )
		echo "0$t1 $t2 $t3 $ft [$loc]	$PHLOGSEL${fn#$PHLOGPATH}"  >>$OUTFILE
		;;
	esac
    done
fi

# Directory contents  ...
if [ -z "$NOCONTENTS" ]; then
    ls $DIRPATH | grep -Ev "~$|^#.*#$|^gophermap$" | while read fn; do
	if [ -z "$continit" ]; then
	    echo "" >>$OUTFILE
	    echo "YOU SEE HERE:" >>$OUTFILE
	    continit=1
	fi
	case $fn in
	    *.blink ) 
		blink_map $DIRPATH/$fn 
		;;
	    * )
		type=$(gtype $DIRPATH/$fn)
		title=$(ftitle $DIRPATH/$fn)
		echo "$type$title	$DIRSEL/$fn	$SERVER	$PORT" >>$OUTFILE
		;;
	esac
    done
fi
    
# Exits  ...
if [ -f $DIRPATH/.exits ]; then
    cat $DIRPATH/.exits | while read exit tag; do
	if [ -z "$exitinit" ]; then
	    echo "" >>$OUTFILE
	    echo "OBVIOUS EXITS:" >>$OUTFILE
	    exitinit=1
	fi
	if [ "$exit" -a -d $NEXUSPATH/$exit ]; then
	    title=$(ftitle $NEXUSPATH/$exit)
	    if [ "$tag" ]; then
		title="($tag) "$title
	    fi
	    echo "1$title	$NEXUSSEL/$exit	$SERVER	$PORT" >>$OUTFILE
	fi
    done
fi

# Gopher-specific footer ...
if [ -f $DIRPATH/.gophfoot ]; then
    echo "" >>$OUTFILE
    cat $DIRPATH/.gophfoot >>$OUTFILE
fi

# Link to nexus directory (bottom)  ...
if [ "$DIR" ]; then
    echo "" >>$OUTFILE
    echo "1(to nexus)	$NEXUSSEL	$SERVER	$PORT" >>$OUTFILE
fi

# Fortune cookie  ...
if [ "$FORTUNE" ]; then
    echo "" >>$OUTFILE
    $FORTUNE >>$OUTFILE
fi

exit 0