1
1
Fork 1
aid/build/build.sh

321 lines
13 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
#shellcheck disable=SC1003,SC2312
# SC1003=Want to escape a single quote?
# SC2312 Consider invoking this command separately
## SCRIPT INFORMATION
# ------------------------------------------------------------------------------
# Name : add directory item (add-directory-item.sh)
# License : Non-Profit Open Software License ("Non-Profit OSL") 3.0
# Dependencies : pcre2grep, tidy
# Author : 12bytes.org
# Code : cin/pages: Alternative Information Directory - Codeberg.org
# : https://codeberg.org/12bytes/aid
#
# Comment : this script is used to create an HTML text block containing
# : all required information for adding a new website to the
# : directory.
#
## LICENSE
# ------------------------------------------------------------------------------
# This program is free software as afforded by the Non-Profit Open Software
# License ("Non-Profit OSL") 3.0, a copy of which should have been included. The
# license can be viewed on-line at: https://opensource.org/licenses/NPOSL-3.0
# ------------------------------------------------------------------------------
#
## TODO
# we could grab website favicons
# curl --output="${sDomain}.WHAT?" "https://t0.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&url=${sUrl}&size=16"
# curl --output="${sDomain}.WHAT?" "https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=${sUrl}&size=16"
# "t<n>" can be 0 to 3
# size seems to default to 16x16 if not specified
# another one...
# https://api.faviconkit.com/&${sDomain}/32
sScriptVersion='20230823'
sItem=''
sCat=''
iAddedPrimary=0
# char encoding/replacements for titles, descriptions
#declare -A aaPrintChars=(['&']='&amp;' ['<']='&lt;' ['>']='&gt;' ['“']='"' ['”']='"' ['„']='"' ['❛']="'" ['❜']="'" ['']="'" ['`']="'" ['´']="'")
# if using iconv
declare -A aaPrintChars=(['&']='&amp;' ['<']='&lt;' ['>']='&gt;' ['„']='"' ['❛']="'" ['❜']="'" ['`']="'")
# encode unsafe chars for URLs
declare -A aaUrlChars=(['"']='%22' ['<']='%3C' ['>']='%3E' ['{']='%7B' ['}']='%7D' ['|']='%7C' ['\']='%5C' ['^']='%5E' ['`']='%60' [' ']='%20')
a=(
''
' --------------------------------------------------------'
' ADD AN ITEM TO THE ALTERNATIVE INFORMATION DIRECTORY'
' --------------------------------------------------------'
''
'NOTES:'
''
'DO NOT EDIT THE INDEX.HTML FILE DIRECTLY. To edit the directory, edit the'
'appropiate file in the /cats directory, then select the "Rebuild the directory"'
'item from the menu.'
''
'Use the following template when adding a secondary website:'
'<channel owner> (<platform name>)'
'Example: Mr. Kitten (YouTube)'
''
"build.sh v${sScriptVersion}"
)
printf '%s\n' "${a[@]}"
# gen the list of categories from the files in the /cats folder
i="$(find 'cats/' -maxdepth 1 -type 'f' | wc -l)"
if [[ "${i}" -lt 1 ]] ; then
printf '%s\n' 'ERROR: No files were found in the /cats directory.'
exit
fi
for s in 'cats/'* ; do
aCatFiles+=("$(basename "${s}")")
done
while true ; do
if [[ -z "${sCat}" ]] ; then
a=('Select a category' 'Rebuild the directory' 'Quit')
elif [[ "${iAddedPrimary}" -eq 0 ]] ; then
a=('Add primary website' 'Quit')
else
a=('Add secondary website' 'Commit' 'Quit')
fi
[[ -n "${sCat}" ]] && printf '\n%s\n' "Selected category: ${sCat}"
printf '\n'
select sSelect in "${a[@]}" ; do
printf '\n'
case "${sSelect}" in
('Select a category')
sItem=''
select sCat in "${aCatFiles[@]}"
do
break
done
if [[ ! -f "cats/${sCat}" ]] ; then
a=(
'ERROR: File not found.'
'Press any key to return to the menu.'
)
printf '%s\n' "${a[@]}"
read -rsN1
continue 2
fi
;;
('Add primary website'|'Add secondary website')
read -erp 'Website title: '
sTitle="${REPLY}"
if grep --fixed-strings --ignore-case ">${sTitle}<" -- '../index.html' > '/dev/null' ; then
a=(
"NOTICE: ${sTitle} is already in the directory."
'Press any key to return to the menu.'
)
printf '%s\n' "${a[@]}"
read -rsN1
continue 2
fi
# strip/encode unsafe chars for title
sTitle="$(perl -fp -e 's|[^[:print:]]||g' <<< "${sTitle}")"
sTitle="$(iconv --to-code='ASCII//TRANSLIT' <<< "${sTitle}")"
sTitle="$(sed -E 's/[[:space:]]{2,}/ /g' <<< "${sTitle}")"
for sKey in "${!aaPrintChars[@]}" ; do
sTitle="${sTitle//"${sKey}"/"${aaPrintChars[${sKey}]}"}"
done
if [[ "${sSelect}" = 'Add primary website' ]] ; then
if [[ -n "${sItem}" ]] ; then
a=(
'Changes must be committed before adding another item.'
'Press any key to return to the menu.'
)
printf '%s\n' "${a[@]}"
read -rsN1
continue 2
fi
# website description
read -erp 'One-line website description: '
sDescrip="${REPLY}"
if [[ -n "${sDescrip}" ]] ; then
# strip/encode unsafe chars for description
sDescrip="$(perl -fp -e 's|[^[:print:]]||g' <<< "${sDescrip}")"
sDescrip="$(iconv --to-code='ASCII//TRANSLIT' <<< "${sDescrip}")"
sDescrip="$(sed -E 's/[[:space:]]{2,}/ /g' <<< "${sDescrip}")"
for sKey in "${!aaPrintChars[@]}" ; do
sDescrip="${sDescrip//"${sKey}"/"${aaPrintChars[${sKey}]}"}"
done
else
sDescrip='No description available.'
fi
sItem="<div class=\"gridItem\" tabindex=\"0\"><h3>${sTitle}</h3><p>${sDescrip}</p><ul>"
aPreview=(
"PRIMARY TITLE: ${sTitle}"
"DESCRIPTION: ${sDescrip}"
)
else
aPreview+=("SECONDARY TITLE: ${sTitle}")
fi
# website url
sERE='^https?:\/\/[a-z0-9]+\.[a-z0-9]+[a-z0-9.]*\/'
while true ; do
read -erp 'Website URL: '
sUrl="${REPLY}"
[[ "${sUrl}" =~ ${sERE} ]] && break
a=(
'WARNING: The URL appears to be invalid.'
'Do you want to accept it anyway? [y/N]'
)
printf '%s\n' "${a[@]}"
read -rsN1
[[ "${REPLY}" = 'y' ]] && break
done
# strip/encode unsafe chars in url
sCleanUrl="$(perl -fp -e 's|[^[:print:]]||g' <<< "${sUrl}")"
sCleanUrl="$(iconv --to-code='ASCII//TRANSLIT' <<< "${sCleanUrl}")"
for sKey in "${!aaUrlChars[@]}" ; do
sCleanUrl="${sCleanUrl//"${sKey}"/"${aaUrlChars[${sKey}]}"}"
done
s="$(pcre2grep --only-matching=1 'https?:\/\/(?:www\.)?(.+)' <<< "${sCleanUrl}")"
if grep --fixed-strings --ignore-case "${s}" -- '../index.html' > '/dev/null' ; then
sItem=''
sCat=''
a=(
'NOTICE: This URL is already in the directory.'
'Press any key to return to the menu.'
)
printf '%s\n' "${a[@]}"
read -rsN1
continue 2
elif [[ "${sCleanUrl}" != "${sUrl}" ]] ; then
xdg-open "${sCleanUrl}" &> '/dev/null' & disown
a=(
"Original URL : ${sUrl}"
"Cleaned URL : ${sCleanUrl}"
'The cleaned URL was opened in your browser.'
'Is the URL correct? [Y/n]'
)
printf '%s\n' "${a[@]}"
read -rsN1
[[ "${REPLY}" = 'n' ]] && sItem='' && sCat='' && continue 2
fi
sItem+="<li><a href=\"${sCleanUrl}\">${sTitle}</a></li>"
aPreview+=("URL: ${sCleanUrl}")
[[ "${sSelect}" = 'Add primary website' ]] && iAddedPrimary=1
;;
('Rebuild the directory'|'Commit')
iAddedPrimary=0
printf '%s\n' 'Backing up directory files...'
s="$(date '+%F_%T')"
mkdir --parents -- "backups/${s}/cats/"
cp -- '../about.html' '../downloads.html' '../index.html' '../submissions.html' "backups/${s}/"
cp --recursive -- 'cats/' "backups/${s}/"
aFiles=('index.html') # files to process in the loop
if [[ "${sSelect}" = 'Commit' ]] ; then
a=(
'Item preview:'
"${aPreview[@]}"
'Accept this submission? [Y/n]'
)
printf '%s\n\n ' "${a[@]}"
read -rsN1
[[ "${REPLY}" = 'n' ]] && sItem='' && sCat='' && continue 2
printf '%s\n' 'Creating category file...'
printf '%s\n' "${sItem}</ul></div>" >> "cats/${sCat}"
sort --ignore-case --ignore-leading-blanks --output="cats/${sCat}" -- "cats/${sCat}"
else
printf '%s\n' 'Rebuild all directory files? [Y/n]'
read -rsN1
[[ "${REPLY}" = 'n' ]] && continue 2
printf '%s\n' 'Rebuilding category files...'
for sFile in "${aCatFiles[@]}" ; do
sort --ignore-case --ignore-leading-blanks --output="cats/${sFile}" -- "cats/${sFile}"
done
aFiles+=('about.html' 'downloads.html' 'submissions.html') # files to process in the loop
fi
sItem='' sCat=''
sDate="$(date --utc '+%b %d, %Y (GMT)')"
for sFile in "${aFiles[@]}" ; do
printf '%s\n' "Building ${sFile}..."
aFile=("$(<'parts/head.html')")
aFile+=("$(<"parts/${sFile}")")
if [[ "${sFile}" = 'index.html' ]] ; then
for s in "${aCatFiles[@]}" ; do
# format anchor links in grid
s1="${s//' '/}"
s1="${s1//'&'/}"
s1="${s1^^}"
s2="${s//'&'/'&amp;'}" # encode '&' chars for link text
aFile+=(
"<h2 class=\"cat\" id=\"${s1}\">${s2}</h2>"
'<div class="grid">'
"$(<"cats/${s}")"
'</div>'
)
done
aFile+=('</div>')
aFile=("${aFile[*]//'{TITLE}'/'Alternative Information Directory'}")
aFile=("${aFile[*]//'{UTC_DATE}'/"${sDate}"}")
elif [[ "${sFile}" = 'about.html' ]] ; then
aFile=("${aFile[*]//'{TITLE}'/'About | Alternative Information Directory'}")
elif [[ "${sFile}" = 'downloads.html' ]] ; then
aFile=("${aFile[*]//'{TITLE}'/'Downloads | Alternative Information Directory'}")
elif [[ "${sFile}" = 'submissions.html' ]] ; then
aFile=("${aFile[*]//'{TITLE}'/'Submissions | Alternative Information Directory'}")
fi
aFile+=("$(<'parts/tail.html')")
printf '%s\n' 'Running tidy...'
if ! tidy -errors -quiet <<< "${aFile[*]}" ; then
a=(
''
"ERROR: tidy encountered a problem with ${sFile}."
''
'Press any key to continue.'
)
printf '%s\n' "${a[@]}"
read -rsN1
fi
printf '%s\n' "${aFile[@]}" > "../${sFile}"
done
xdg-open '../index.html' &> '/dev/null' & disown
a=(
'Finished!'
''
'The index.html page was opened in your browser.'
''
)
printf '%s\n' "${a[@]}"
;;
('Quit')
exit
;;
(*) printf '%s\n' 'Invalid choice.'
continue 2
;;
esac
break
done
done
exit