3 # fesh - An Atom feed generator for Gemini capsules written in POSIX sh.
5 # Copyright (C) 2021-2022 - Ricardo García Jiménez <ricardogj08@riseup.net>
6 # Copyright (C) 2022 - Fabián Bonetti <fabianbonetti@vk.com>
8 # Licensed under the Apache License, Version 2.0 (the "License");
9 # you may not use this software except in compliance with the License.
10 # You may obtain a copy of the License at:
12 # http://www.apache.org/licenses/LICENSE-2.0
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS,
16 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 # See the License for the specific language governing permissions and
18 # limitations under the License.
22 # Muestra mensajes de errores.
25 printf '%s.\n' "$1" >&2
30 # Muestra un mensaje de ayuda.
32 shelp() { printf '%s' "\
33 fesh 2.2 - An Atom feed generator for Gemini capsules written in POSIX sh.
39 -a <NAME> - Author name [default: capsule].
40 -c <STRING> - Capsule name [default: fesh].
41 -d <DOMAIN> - Capsule domain name [default: localhost].
42 -l <LANG> - Capsule content language [default: es].
43 -n <NUMBER> - Number of entries [default: 15].
44 -o <PATH> - Output directory [default: .].
45 -r <PATH> - Capsule root directory [default: .].
48 fesh -d myblog.com -c 'My blog'
54 # Genera el encabezado del feed de Atom.
57 <?xml version="1.0" encoding="utf-8"?>
58 <feed xmlns="http://www.w3.org/2005/Atom" xml:lang="${FESH_LANG:-es}">
59 <id>${FESH_DOMAIN}/atom.xml</id>
60 <title>${FESH_CAPSULE}</title>
61 <updated>$(LC_ALL=C date "$FDATE")</updated>
63 <name>${FESH_AUTHOR}</name>
65 <link rel="self" href="${FESH_DOMAIN}/atom.xml" type="application/atom+xml"/>
66 <link rel="alternate" href="${FESH_DOMAIN}" type="text/gemini"/>
67 <generator uri="https://github.com/ricardogj08/fesh" version="2.2">fesh</generator>
72 # Elimina espacios sobrantes de un string.
73 # shellcheck disable=SC2048,SC2086
86 # Genera una entrada para el feed de Atom.
91 <title>${TITLE}</title>
92 <updated>${DATE}</updated>
94 <name>${FESH_AUTHOR}</name>
96 <link rel="alternate" href="${URL}" type="text/gemini"/>
102 # Contruye un feed de atom.
105 FDATE=+%Y-%m-%dT%H:%M:%SZ
112 # Lista todos los archivos *.gmi o *.gemini
113 # ordenados por fecha de modificación.
115 find . -type f \( -name \*.gmi -o -name \*.gemini \) \
116 -a ! \( -name index.gmi -o -name index.gemini \) \
117 -exec ls -t {} + 2>/dev/null |
119 while read -r file; do
121 # URL Gemini del archivo.
123 URL="$FESH_DOMAIN/${file#./}"
126 # Título principal del archivo.
128 TITLE=$(grep -se '^#[[:space:]]' "$file" | head -n 1)
129 TITLE=${TITLE#\#[[:space:]]}
130 TITLE=$(trim_all "$TITLE")
133 # Fecha de modificación.
135 DATE=$(LC_ALL=C date -r "$file" "$FDATE" 2>/dev/null ||
136 LC_ALL=C date "$FDATE")
142 [ "$i" -eq "$FESH_NUMBER" ] && break
149 while getopts :a:c:d:l:n:o:r: opt; do
151 a) FESH_AUTHOR="$OPTARG";;
152 c) FESH_CAPSULE="$OPTARG";;
153 #d) FESH_DOMAIN=gemini://${OPTARG}:1965;;
154 d) FESH_DOMAIN=gemini://${OPTARG};; # Sin :1965 por Fabián
155 l) FESH_LANG="$OPTARG";;
156 n) FESH_NUMBER="$OPTARG";;
157 o) FESH_OUTPUT="$OPTARG";;
158 r) FESH_ROOT="$OPTARG";;
160 :) errors "Option -$OPTARG requires an argument"
164 # Decrementa el puntero del argumento $n
165 # para que apunte al siguente argumento.
167 shift $((OPTIND - 1))
170 # Configuración por defecto.
172 : "${FESH_CAPSULE=fesh}"
173 : "${FESH_AUTHOR:=$FESH_CAPSULE}"
174 #: "${FESH_DOMAIN:=gemini://localhost:1965}"
175 : "${FESH_DOMAIN:=gemini://localhost}" # sin :1965 por Fabián
176 : "${FESH_NUMBER:=15}"
177 : "${FESH_OUTPUT:=.}"
179 :> "$FESH_OUTPUT/atom.xml" ||
180 errors "Couldn't create Atom feed file"
182 cd "${FESH_ROOT:-.}" ||
183 errors "Couldn't access capsule root directory"
185 render > "$FESH_OUTPUT/atom.xml"