Files for the official Dragora website
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

316 lines
6.0 KiB

#!/bin/bash
#
# addnews
#
# News addition helper for the Dragora GNU/Linux-Libre website
# (https://www.dragora.org)
#
#
# Copyright (C) 2021 Michael Siegel
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#### INCLUDES ####
. include/constants || exit 1
. include/subroutines || exit 1
#### CONSTANTS ####
#### GLOBAL PARAMETERS ####
action=add
date=
title=
url=
#### FUNCTIONS ####
_days_in_month() {
local month="$1"
local year="$2" # Needs to be YYYY.
local days_in_month=(31 28 31 30 31 30 31 31 30 31 30 31)
month="${month#0}" # Strip leading zeroes for use in arithmetic expansion
if [[ "$month" -eq 2 ]]
then
# Give February 29 days if $year is a leap year:
[[ ("$((year % 4))" -eq 0 && "$((year % 100))" -ne 0) || \
"$((year % 400))" -eq 0 ]] && days_in_month[1]=29
fi
printf '%s' "${days_in_month["$((month - 1))"]}"
}
_date_valid () {
local input="$1"
local day=
local month=
local year=
local days_max=
local valid=1
if [[ ! "$input" =~ [0-9]{4}-[0-9]{2}-[0-9]{2} ]]
then
valid=0
else
year="${input:0:4}"
month="${input:5:2}"
day="${input:8:2}"
if (( 10#"$month" < 1 || 10#"$month" > 12 ))
then
_perr "invalid month -- '$month'"
valid=0
else
days_max="$(_days_in_month "$month" "$year")"
if (( 10#"$day" < 1 || 10#"$day" > 10#"$days_max" ))
then
_perr "invalid day of month -- '$day'"
valid=0
else
date_unix_time="$(TZ="$TIMEZONE" \
date -d "${year#0}-${month#0}-${day#0}" '+%s')"
if (( 10#"$date_unix_time" < 0 ))
then
_perr "date out of range (negative Unix time) -- '$input'"
valid=0
fi
fi
fi
fi
[[ "$valid" -eq 0 ]] && return 1
return 0
}
_prompt_date() {
local input=
local date_default; date_default="$(date +%Y-%m-%d)"
while true
do
if [[ -z "$input" ]]
then
printf '%s\n' "Please enter the publishing date [$date_default]:"
printf '%s\n' "$HELP_TIP_INTERACTIVE"
fi
read -rp "$PROMPT" input
if [[ -z "$input" ]]
then
date="$date_default"
break
elif [[ "$input" = "$HELP_COMMAND" ]]
then
_show_help "$FUNCNAME"
elif ! _date_valid "$input" # _date_valid prints error messages.
then
printf '%s\n' "$HELP_TIP_INTERACTIVE"
else
date="$input"
break
fi
done
}
_prompt_title() {
local input=
while true
do
if [[ -z "$input" ]]
then
printf '%s\n' 'Please enter a title:'
printf '%s\n' "$HELP_TIP_INTERACTIVE"
fi
read -rp "$PROMPT" input
if [[ -z "$input" ]]
then
continue
elif [[ "$input" = "$HELP_COMMAND" ]]
then
_show_help "$FUNCNAME"
else
break
fi
done
title="$input"
}
_prompt_url() {
local input=
while true
do
if [[ -z "$input" ]]
then
printf '%s\n' 'Please enter a URL:'
printf '%s\n' "$HELP_TIP_INTERACTIVE"
fi
read -rp "$PROMPT" input
if [[ -z "$input" ]]
then
continue
elif [[ "$input" = "$HELP_COMMAND" ]]
then
_show_help "$FUNCNAME"
# TODO: Implement URL syntax checks!
else
break
fi
done
url="$input"
}
_mk_news_item() {
printf ' <li>%s\\n <a href="%s">%s</a>\\n </li>' "$date" "$url" "$title"
# Escaping `\n` so the result can be used in sed.
}
_add_news() {
local lang=
for lang in $(_get_lang_dirs)
do
cp -a -- "${PAGES_DIR}/${lang}/$NEWS_PAGE" \
"${PAGES_DIR}/${lang}/$NEWS_PAGE".old
sed -i -- \
"s|<ul>|<ul>\n$(_mk_news_item)|" "${PAGES_DIR}/${lang}/$NEWS_PAGE"
done
unset lang
}
_add_latest_news() {
local lnum=
local lang=
for lang in $(_get_lang_dirs)
do
cp -a -- "${PAGES_DIR}/${lang}/$INDEX_PAGE" \
"${PAGES_DIR}/${lang}/$INDEX_PAGE".old
lnum="$(grep -n '^</ul>$' "${PAGES_DIR}/${lang}/$INDEX_PAGE" | cut -c 1,2)"
lnum_start=$((lnum - 4))
lnum_end=$((lnum - 1))
sed -i -- "${lnum_start},${lnum_end} d" "${PAGES_DIR}/${lang}/$INDEX_PAGE"
sed -i -- \
"s|<ul>|<ul>\n$(_mk_news_item)|" "${PAGES_DIR}/${lang}/$INDEX_PAGE"
done
unset lang
}
_revert() {
for lang in $(_get_lang_dirs)
do
if [[ -e "${PAGES_DIR}/${lang}/${NEWS_PAGE}.old" ]]
then
mv -- "${PAGES_DIR}/${lang}/${NEWS_PAGE}.old" \
"${PAGES_DIR}/${lang}/${NEWS_PAGE}" || return 1
else
_perr "cannot find backup file -- ${PAGES_DIR}/${lang}/${NEWS_PAGE}.old"
fi
if [[ -e "${PAGES_DIR}/${lang}/${HOME_PAGE}.old" ]]
then
mv -- "${PAGES_DIR}/${lang}/${HOME_PAGE}.old" \
"${PAGES_DIR}/${lang}/${HOME_PAGE}" || return 1
else
_perr "cannot find backup file -- ${PAGES_DIR}/${lang}/${HOME_PAGE}.old"
fi
done
}
_show_help() {
case "$1" in
global)
cat <<'EOF'
Add a news item interactively
Usage:
addnews [OPTIONS]
Options:
-r Revert latest news addition
--help
Show this help text and exit
EOF
;;
*)
printf '%s\n' "Sorry, no help text available."
;;
esac
}
#### MAIN ####
## Environment checks
_env_checks || _abort
## Action
while [[ "$#" -gt 0 ]]
do
case "$1" in
-r)
shift
action=revert
;;
--help)
_show_help global
exit
;;
--) # End of options
shift
break
;;
*)
_perr "invalid argument -- '$1'"
exit 1
;;
esac
done
if [[ "$action" = revert ]]
then
_revert || _abort
else
_prompt_date || _abort
_prompt_title || _abort
_prompt_url || _abort
_add_news || _abort
_add_latest_news || _abort
fi