#!/bin/sh
# generate a Atom feed from a directory, recursively
# using POSIX sh
# AUTHOR: Case Duckworth <acdw@acdw.net>
# LICENSE: MIT

usage() {
    cat <<END
$0: generate an Atom feed from directories of files
INVOCATION:
	$0 [-h] [-c CONFIG] DIRECTORY...

OPTIONS:
	-h			show this help
	-c CONFIG	change the CONFIG file.
				Default: $PWD/gemshimfeed.conf.sh
END
}

# FEED VARIABLES
FEED_TITLE=example
FEED_SUBTITLE="an example"
FEED_URL="https://example.com/atom.xml"
SITE_URL="https://example.com"
FEED_ID="${SITE_URL#*//}"
FEED_AUTHOR="nobody"
FEED_COPYRIGHT="(c) 2020 CC-BY-SA $FEED_AUTHOR"
FEED_UPDATED=$(date -u +'%FT%TZ')

# FUNCTIONS

recent_files() { # recent_files DIRECTORY FIND_ARG...
    # list files, in order of recency
    # BOO: REQUIRES GNU FIND :( :( :( :(
    # possibly look into https://unix.stackexchange.com/questions/9247/
    # for more possibilities if you don't have GNU find.
    dir="$1"
    shift

    find "$dir" -maxdepth 1 \
        "$@" \
        -not -name '.*' \
        -printf '%T@\t%p\n' |
        sort -nr |
        cut -f2
}

# ENTRY FUNCTIONS

skip_entry() {
    return 1
}

entry_url() {
    basename="${1#$DIRECTORY}"
    echo "$FEED_URL/$basename"
}

entry_title() {
    awk '/^#+[ 	]\S/{
	for(i=2;i<=NF;i++) {
		printf $i;
		if (i!=NF) printf " ";
	}
	printf "\n";exit}' "$1"
}

entry_summary() {
    return 1
}

entry_author() {
    echo "$FEED_AUTHOR"
}

entry_content() {
    cat "$1"
}

entry_updated() {
    # requires stat(1).
    # probably another way.
    # possibly using ls(1).
    stat -c '%y' "$1" |
        awk '{
		sub(/\..*/,"",$2);
		sub(/[0-9][0-9]/,"&:",$3);
		print $1"T"$2$3;}'
}

# ATOM FUNCTIONS

atom_header() {
    cat <<END
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>$FEED_TITLE</title>
<subtitle>$FEED_SUBTITLE</subtitle>
<link href="$FEED_URL" rel="self" />
<link href="$SITE_URL" />
<id>$FEED_ID</id>
<generator uri="https://git.sr.ht/~acdw/gemshimfeed" version="infinite">GemShimFeed</generator>
<rights>$FEED_COPYRIGHT</rights>
<updated>$FEED_UPDATED</updated>
END
}

atom_footer() {
    cat <<END
</feed>
END
}

atom_entry() { # atom_entry FILE
    ENTRY_URL="$(entry_url "$1")"
    ENTRY_TITLE="$(entry_title "$1")"
    ENTRY_SUMMARY="$(entry_summary "$1")"
    ENTRY_AUTHOR="$(entry_author "$1")"
    ENTRY_CONTENT="$(entry_content "$1")"
    ENTRY_UPDATED="$(entry_updated "$1")"
    cat <<END
<entry>
<id>$ENTRY_URL</id>
<link rel="alternate" href="$ENTRY_URL" />
<title>$ENTRY_TITLE</title>
<summary>$ENTRY_SUMMARY</summary>
<updated>$ENTRY_UPDATED</updated>
<author><name>$ENTRY_AUTHOR</name></author>
<content type="text"><![CDATA[$ENTRY_CONTENT]]></content>
</entry>
END
}

main() {
    CONFIGFILE="$PWD/gemshimfeed.conf.sh"
    case "$1" in
        -h)
            usage
            exit 0
            ;;
        -c)
            CONFIGFILE="$2"
            shift 2
            ;;
    esac

    if [ -f "CONFIGFILE" ]; then
        . "$CONFIGFILE"
    fi

    atom_header
    for DIR; do
        for entry in $(recent_files "$DIR" -type f); do
            if skip_entry "$entry"; then continue; fi

            atom_entry "$entry"
        done
    done
    atom_footer
}

if [ $DEBUG ]; then set -x; fi

main "$@"