mirror of
https://github.com/standardebooks/web.git
synced 2025-07-07 15:20:32 -04:00
240 lines
8.6 KiB
Bash
Executable file
240 lines
8.6 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
usage(){
|
|
fmt <<EOF
|
|
DESCRIPTION
|
|
Deploy a Standard Ebook source repository to the web.
|
|
|
|
USAGE
|
|
deploy-ebook-to-www [-v,--verbose] [-g,--group GROUP] [--webroot WEBROOT] [--weburl WEBURL] DIRECTORY [DIRECTORY...]
|
|
DIRECTORY is a bare source repository.
|
|
GROUP is a groupname. Defaults to "se".
|
|
WEBROOT is the path to your webroot. Defaults to "/standardebooks.org".
|
|
WEBURL is the URL the website is served on. Defaults to "https://standardebooks.org".
|
|
EOF
|
|
exit
|
|
}
|
|
die(){ printf "\033[0;7;31mError:\033[0m %s\n" "${1}" 1>&2; exit 1; }
|
|
require(){ command -v "$1" > /dev/null 2>&1 || { suggestion=""; if [ -n "$2" ]; then suggestion=" $2"; fi; die "$1 is not installed.${suggestion}"; } }
|
|
# End boilerplate
|
|
|
|
verbose="false"
|
|
group="se"
|
|
webRoot="/standardebooks.org/web"
|
|
webUrl="https://standardebooks.org"
|
|
|
|
if [ $# -eq 0 ]; then
|
|
usage
|
|
fi
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-h|--help)
|
|
usage ;;
|
|
-v|--verbose)
|
|
verbose="true"
|
|
shift 1
|
|
;;
|
|
-g|--group)
|
|
[ -n "$2" ] || die "Group cannot be empty."
|
|
group="$2"
|
|
shift 2
|
|
;;
|
|
--webroot)
|
|
[ -n "$2" ] || die "Web root can't be empty."
|
|
webRoot="$2"
|
|
shift 2
|
|
;;
|
|
--weburl)
|
|
[ -n "$2" ] || die "Web URL can't be empty."
|
|
webUrl="$2"
|
|
shift 2
|
|
;;
|
|
*) break ;;
|
|
esac
|
|
done
|
|
|
|
if ! [ "$(getent group "${group}")" ]; then
|
|
die "Group ${group} does not exist. Either use --group or create the group."
|
|
fi
|
|
|
|
if ! [ -d "${webRoot}" ]; then
|
|
die "${webRoot} does not exist or is not a directory."
|
|
fi
|
|
|
|
# Check for dependencies
|
|
require "convert" "Try: apt-get install imagemagick"
|
|
require "rsvg-convert" "Try: apt-get install librsvg2-bin"
|
|
require "git" "Try: apt-get install git"
|
|
require "php" "Try: apt-get install php-cli"
|
|
require "se" "Read: https://github.com/standardebooks/tools"
|
|
|
|
scriptsDir="$(dirname "$(readlink -f "$0")")"
|
|
|
|
if ! [ -x "${scriptsDir}"/reset-php-fpm-opcache ]; then
|
|
die "\"${scriptsDir}\"/reset-php-fpm-opcache is not an executable file."
|
|
fi
|
|
|
|
if ! [ -f "${scriptsDir}"/generate-opds.php ]; then
|
|
die "\"${scriptsDir}\"/generate-opds.php\" is not a file or could not be found."
|
|
fi
|
|
|
|
if ! [ -f "${scriptsDir}"/generate-rss.php ]; then
|
|
die "\"${scriptsDir}\"/generate-rss.php\" is not a file or could not be found."
|
|
fi
|
|
|
|
mkdir -p "${webRoot}"/www/images/covers/
|
|
|
|
for dir in "$@"
|
|
do
|
|
if [ "${dir}" = "" ]; then
|
|
continue
|
|
fi
|
|
|
|
repoDir=$(realpath "${dir%/}")
|
|
baseName=$(basename "${repoDir}")
|
|
|
|
if [ "${baseName}" = ".git" ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ ! -d "${repoDir}" ]; then
|
|
die "Invalid repo root: ${repoDir}"
|
|
fi
|
|
|
|
if ! pushd "${repoDir}" > /dev/null; then
|
|
echo "Couldn't cd into ${repoDir}. Skipping."
|
|
continue
|
|
fi
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Entering %s\n" "${repoDir}"
|
|
fi
|
|
|
|
if git show HEAD:src/epub/content.opf | grep --quiet --extended-regexp "<dc:date>1900-01-01T00:00:00Z</dc:date>"; then
|
|
printf "Looks like a draft ebook, skipping\n"
|
|
continue
|
|
fi
|
|
|
|
webDir=$(git show HEAD:src/epub/content.opf | grep --only-matching --extended-regexp "<dc:identifier id=\"uid\">url:https://standardebooks.org/ebooks/[^<]+<\/dc:identifier>" | sed --regexp-extended "s/<[^>]+?>//g" | sed --regexp-extended "s/^url:https:\/\/standardebooks.org\/ebooks\/?//")
|
|
|
|
if [ "${webDir}" = "" ]; then
|
|
die "Empty webdir!"
|
|
fi
|
|
|
|
workDir=$(mktemp -d)
|
|
imgWorkDir=$(mktemp -d)
|
|
webDir="${webRoot}/www/ebooks/${webDir}"
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Generating cover image for web ... "
|
|
fi
|
|
|
|
urlSafeIdentifier=$(git show HEAD:src/epub/content.opf | grep --only-matching --extended-regexp "<dc:identifier id=\"uid\">url:https://standardebooks.org/ebooks/[^<]+<\/dc:identifier>" | sed --regexp-extended "s/<[^>]+?>//g" | sed --regexp-extended "s|url:https://standardebooks.org/ebooks/||g" | sed --regexp-extended "s|/|_|g")
|
|
|
|
# Build the hero image for individual ebook pages
|
|
git show HEAD:images/cover.jpg > "${imgWorkDir}/${urlSafeIdentifier}.jpg"
|
|
cp "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg"
|
|
# Resize and crop the image to 2156 width, 720 height, and starting at the coords 0,1078
|
|
convert -resize "1078" -crop "1078x359+0+539" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}-hero.jpg"
|
|
convert -resize "2156" -crop "2156x718+0+1078" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" "${imgWorkDir}/${urlSafeIdentifier}-hero@2x.jpg"
|
|
|
|
# Build the cover image thumbnail
|
|
git show HEAD:images/cover.jpg > "${imgWorkDir}/${urlSafeIdentifier}.jpg"
|
|
git show HEAD:images/cover.svg > "${imgWorkDir}/${urlSafeIdentifier}.svg"
|
|
sed -i "s/cover\.jpg/${urlSafeIdentifier}\.jpg/g" "${imgWorkDir}/${urlSafeIdentifier}.svg"
|
|
cp "${imgWorkDir}/${urlSafeIdentifier}.svg" "${imgWorkDir}/${urlSafeIdentifier}@2x.svg"
|
|
|
|
# Due to a bug in `convert` we have to use rsvg-convert to convert SVG to PNG, then work on the PNG with `convert`.
|
|
rsvg-convert --keep-aspect-ratio --format png --output "${imgWorkDir}/${urlSafeIdentifier}.png" "${imgWorkDir}/${urlSafeIdentifier}.svg"
|
|
rsvg-convert --keep-aspect-ratio --format png --output "${imgWorkDir}/${urlSafeIdentifier}@2x.png" "${imgWorkDir}/${urlSafeIdentifier}@2x.svg"
|
|
|
|
# Resize and compress the image (formula from Google Page Speed Insights)
|
|
convert -resize "196" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}.png" "${imgWorkDir}/${urlSafeIdentifier}.jpg"
|
|
convert -resize "392" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}@2x.png" "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg"
|
|
|
|
mv "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" "${imgWorkDir}/${urlSafeIdentifier}-cover@2x.jpg"
|
|
mv "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}-cover.jpg"
|
|
|
|
sudo chgrp --preserve-root --recursive "${group}" "${imgWorkDir}/${urlSafeIdentifier}"*
|
|
sudo chmod --preserve-root --recursive g+w "${imgWorkDir}/${urlSafeIdentifier}"*
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Done.\n"
|
|
printf "Building ebook ... "
|
|
fi
|
|
|
|
git clone --quiet "${repoDir}" "${workDir}"
|
|
|
|
mkdir "${workDir}/dist"
|
|
|
|
# Build the ebook
|
|
if ! se build --output-dir="${workDir}/dist" --check --kindle --kobo --covers "${workDir}"; then
|
|
rm --preserve-root --recursive --force "${workDir}"
|
|
die "Error building ebook, stopping deployment."
|
|
fi
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Done.\n"
|
|
fi
|
|
|
|
# Get the last commit date so that we can update the modified timestamp in
|
|
# deployed content.opf. generate-opds uses this timestamp in its output.
|
|
modifiedDate=$(TZ=UTC git log --date=iso-strict-local -1 --pretty=tformat:"%cd" --abbrev-commit | sed "s/+00:00/Z/")
|
|
sed --in-place --regexp-extended "s/<meta property=\"dcterms:modified\">.+?<\/meta>/<meta property=\"dcterms:modified\">${modifiedDate}<\/meta>/" "${workDir}/src/epub/content.opf"
|
|
|
|
# Delete the contents of the old webdir
|
|
rm --preserve-root --recursive --force "${webDir}"
|
|
|
|
# Re-create the webdir
|
|
mkdir -p "${webDir}"
|
|
|
|
# Move contents of the work dir over
|
|
mv "${workDir}"/* "${webDir}/"
|
|
|
|
# Move the cover images over
|
|
mv "${imgWorkDir}/${urlSafeIdentifier}"*.jpg "${webRoot}/www/images/covers/"
|
|
|
|
# Delete the now-empty work dir (empty except for .git)
|
|
rm --preserve-root --recursive --force "${workDir}" "${imgWorkDir}"
|
|
|
|
sudo chgrp --preserve-root --recursive "${group}" "${webDir}"
|
|
sudo chmod --preserve-root --recursive g+ws "${webDir}"
|
|
|
|
sudo chgrp --preserve-root --recursive "${group}" "${webRoot}/www/images/covers/"
|
|
sudo chmod --preserve-root --recursive g+ws "${webRoot}/www/images/covers/"
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Rebuilding web library cache ... "
|
|
fi
|
|
|
|
"${scriptsDir}"/rebuild-library-cache
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Done.\n"
|
|
fi
|
|
|
|
popd > /dev/null || die "Couldn't pop directory."
|
|
done
|
|
|
|
# Build the OPDS catalog
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Rebuilding OPDS catalog ... "
|
|
fi
|
|
|
|
bash -c "php \"${scriptsDir}\"/generate-opds.php --webroot \"${webRoot}\" --weburl \"${webUrl}\" > \"${webRoot}\"/www/opds/all.xml; export XMLLINT_INDENT=\$(printf \"\\t\") && xmllint --c14n \"${webRoot}\"/www/opds/all.xml | (printf \"%s\\n\" \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\" && cat) | xmllint --output \"${webRoot}\"/www/opds/all.xml --format -"
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Done.\n"
|
|
fi
|
|
|
|
# Build the new releases RSS feed
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Rebuilding new releases RSS feed ... "
|
|
fi
|
|
|
|
bash -c "php \"${scriptsDir}\"/generate-rss.php --webroot \"${webRoot}\" --weburl \"${webUrl}\" > \"${webRoot}\"/www/rss/new-releases.xml"
|
|
|
|
if [ "${verbose}" = "true" ]; then
|
|
printf "Done.\n"
|
|
fi
|