about summary refs log tree commit diff stats
path: root/gemshimfeed
diff options
context:
space:
mode:
Diffstat (limited to 'gemshimfeed')
-rw-r--r--gemshimfeed152
1 files changed, 152 insertions, 0 deletions
diff --git a/gemshimfeed b/gemshimfeed new file mode 100644 index 0000000..a3eb3c0 --- /dev/null +++ b/gemshimfeed
@@ -0,0 +1,152 @@
1#!/bin/sh
2# generate a Atom feed from a directory, recursively
3# using POSIX sh
4# AUTHOR: Case Duckworth <acdw@acdw.net>
5# LICENSE: MIT
6
7usage() {
8 cat <<END
9$0: generate an Atom feed from directories of files
10INVOCATION:
11 $0 [-h] [-c CONFIG] DIRECTORY...
12
13OPTIONS:
14 -h show this help
15 -c CONFIG change the CONFIG file.
16 Default: $PWD/gemshimfeed.conf.sh
17END
18}
19
20# FEED VARIABLES
21FEED_TITLE=example
22FEED_SUBTITLE="an example"
23FEED_URL="https://example.com/atom.xml"
24SITE_URL="https://example.com/"
25FEED_ID="example.com"
26FEED_COPYRIGHT="(c) 2020 CC-BY-SA nobody"
27FEED_UPDATED=$(date -u +'%FT%TZ')
28
29# FUNCTIONS
30
31recent_files() { # recent_files DIRECTORY FIND_ARG...
32 # list files, in order of recency
33 # BOO: REQUIRES GNU FIND :( :( :( :(
34 # possibly look into https://unix.stackexchange.com/questions/9247/
35 # for more possibilities if you don't have GNU find.
36 dir="$1"
37 shift
38
39 find "$dir" -maxdepth 1 \
40 "$@" \
41 -not -name '.*' \
42 -printf '%T@\t%p\n' |
43 sort -nr |
44 cut -f2
45}
46
47# ENTRY FUNCTIONS
48
49skip_entry() {
50 return 1
51}
52
53entry_url() {
54 basename="${1#$DIRECTORY}"
55 echo "$FEED_URL/$basename"
56}
57
58entry_title() {
59 awk '/^#+[ ]\S/{for(i=2;i<=NF;i++)print $i;}'
60}
61
62entry_summary() {
63 return 1
64}
65
66entry_author() {
67 echo "nobody"
68}
69
70entry_content() {
71 cat "$1"
72}
73
74entry_updated() {
75 # requires stat(1).
76 # probably another way.
77 # possibly using ls(1).
78 stat -c '%y' "$1" |
79 awk '{
80 sub(/\..*/,"",$2);
81 sub(/[0-9][0-9]/,"&:",$3);
82 print $1"T"$2$3;}'
83}
84
85# ATOM FUNCTIONS
86
87atom_header() {
88 cat <<END
89<?xml version="1.0" encoding="utf-8"?>
90<feed xmlns="http://www.w3.org/2005/Atom">
91<title>$FEED_TITLE</title>
92<subtitle>$FEED_SUBTITLE</subtitle>
93<link href="$FEED_URL" rel="self" />
94<link href="$SITE_URL" />
95<id>$FEED_ID</id>
96<generator uri="https://git.sr.ht/~acdw/gemshimfeed" version="infinite>GemShimFeed</generator>
97<rights>$FEED_COPYRIGHT</rights>
98<updated>$FEED_UPDATED</updated>
99END
100}
101
102atom_footer() {
103 cat <<END
104</feed>
105END
106}
107
108atom_entry() { # atom_entry FILE
109 ENTRY_URL="$(entry_url "$1")"
110 ENTRY_TITLE="$(entry_title "$1")"
111 ENTRY_SUMMARY="$(entry_summary "$1")"
112 ENTRY_AUTHOR="$(entry_author "$1")"
113 ENTRY_CONTENT="$(entry_content "$1")"
114 ENTRY_UPDATED="$(entry_updated "$1")"
115 cat <<END
116<entry>
117<id>$ENTRY_URL</id>
118<link rel="alternate" href="$ENTRY_URL" />
119<title>$ENTRY_TITLE</title>
120<summary>$ENTRY_SUMMARY</summary>
121<updated>$ENTRY_UPDATED</updated>
122<author><name>$ENTRY_AUTHOR</name></author>
123<content type="text"><![CDATA[$ENTRY_CONTENT]]></content>
124</entry>
125END
126}
127
128main() {
129 CONFIGFILE="$PWD/gemshimfeed.conf.sh"
130 case "$1" in
131 -h)
132 usage
133 exit 0
134 ;;
135 -c)
136 CONFIGFILE="$2"
137 shift 2
138 ;;
139 esac
140
141 . "$CONFIGFILE" || :
142
143 atom_header
144 for DIR; do
145 for entry in $(recent_files "$DIR" -type f); do
146 if skip_file "$entry"; then continue; fi
147
148 atom_entry "$entry"
149 done
150 done
151 atom_footer
152}