summaryrefslogtreecommitdiff
path: root/prepare
diff options
context:
space:
mode:
Diffstat (limited to 'prepare')
-rwxr-xr-xprepare483
1 files changed, 483 insertions, 0 deletions
diff --git a/prepare b/prepare
new file mode 100755
index 0000000..fa9e6ed
--- /dev/null
+++ b/prepare
@@ -0,0 +1,483 @@
+#!/bin/sh -e
+
+#===============================================================
+# Filename : prepare
+# Purpose : Prepare wallpapers for Adélie desktop environments.
+# Authors : Zach van Rijn <me@zv.io>
+# License : Apache 2.0
+# Revision : 20231202
+#===============================================================
+
+#===============================================================
+# README
+#===============================================================
+
+##
+# This script transforms source images, including Adélie logos,
+# into a set of wallpapers suitable for packaging.
+#
+# There are two distinct output products:
+#
+# (1) a "core" or "slim" bundle, containing a lightweight set of
+# default wallpaper(s) and/or branding; and
+#
+# (2) a "full" bundle containing all available wallpapers, which
+# is suitable for use when disk space isn't a major concern.
+#
+#
+#
+# requirements
+# ------------
+#
+# * imagemagick
+#
+#
+# usage
+# -----
+#
+# To process all source images and generate a tarball for upload
+# to 'distfiles', simply run the following command:
+#
+# $ ./prepare
+#
+# Any tarball of the same name will be silently overwritten.
+#
+
+
+#---------------------------------------------------------------
+# configuration: source image input
+#---------------------------------------------------------------
+
+##
+# Distfiles mirror.
+#
+HOST="https://distfiles.adelielinux.org";
+
+
+##
+# Adélie brand asset bundle version.
+#
+# This corresponds to the commit of 'adelie/site-ng' from which
+# the brand assets were generated. A tarball matching this hash
+# must exist in the '<HOST>/source/site-ng-images/' directory.
+#
+# See https://git.adelielinux.org/adelie/site-ng for details.
+#
+HASH=ca57e2bd46f11bf2efdebbca8c7813235744fd5f;
+
+
+##
+# Name of the containing directory and tarball on distfiles.
+#
+NAME="site-ng-images";
+
+
+#---------------------------------------------------------------
+# configuration: processed image output
+#---------------------------------------------------------------
+
+##
+# Name of output directory. Please ensure it is in '.gitignore'.
+#
+KEEP="output";
+
+
+##
+# Choose an output file type.
+#
+TYPE="jpg";
+
+
+##
+# Table of aspect ratios to generate wallpapers for.
+#
+# Format: RATIO SCALE [SCALE ...]
+#
+# Scale is distributed, e.g.:
+#
+# "4:3 640" --> (640*4)x(640*3) = 2560x1920
+#
+# Note that many popular aspect ratios are approximate. We are
+# only concerned with getting to the right ballpark.
+#
+# Table rows MUST BE SORTED FROM GREATEST TO LEAST.
+#
+MAKE=$(grep -v ^# <<EOF
+4:3 640 400 256 200
+5:4 480 256
+3:2 854
+16:10 160 120 105 80
+16:9 240 160 120 90
+21:9 122
+EOF
+);
+
+
+#---------------------------------------------------------------
+# internal: meta
+#---------------------------------------------------------------
+
+HERE="$(dirname $(readlink -f ${0}))";
+cd "${HERE}";
+
+
+##
+# Check for required tools.
+#
+for k in curl composite convert magick; do
+ if ! command -v ${k} 2>&1 >/dev/null; then
+ printf "E: required utility '%s' not found!\n" "${k}";
+ exit 1;
+ fi
+done
+
+
+##
+# Tag first, then generate release the tarball. Sanity checks do
+# not prevent someone from being stupid, but they can avoid some
+# common errors. We want to reduce surprises/ensure consistency.
+#
+VTAG=$(git describe --abbrev=0 2>/dev/null || true);
+if test -z "${VTAG}"; then
+ printf "E: you need to tag at least one commit!\n";
+ exit 1;
+fi
+if test $(git rev-list ${VTAG}..HEAD | wc -l) -gt 0; then
+ printf "E: you need to be checked out at a tag!\n";
+ exit 1;
+fi
+if test $(git ls-remote --tags origin ${VTAG} | wc -l) -eq 0; then
+ printf "E: tag '%s' does not exist on origin!\n" "${VTAG}";
+ exit 1;
+fi
+
+
+##
+# Name of build directory. Please ensure it is in '.gitignore'.
+#
+TEMP="build";
+
+
+##
+# Name of source directory.
+#
+IMGS="src";
+
+
+##
+# Ensure that no images have conflicting names.
+#
+# FIXME: factor out 'background lockscreen' here and elsewhere.
+#
+for k in background lockscreen; do
+ if test -d "${IMGS}"/${k}; then
+ printf "E: not allowed to name image '%s'!\n" "${k}";
+ exit 1;
+ fi
+done
+
+
+#---------------------------------------------------------------
+# internal: support routines
+#---------------------------------------------------------------
+
+##
+# size_only DIR RATIO SCALE [SCALE ...]
+#
+size_only ()
+{
+ data="${1}"; shift;
+ size="${1}"; shift;
+ from="${1}"; # NO SHIFT
+ list="${@}";
+
+ ##
+ # FIXME: assumes 'a:b' where 'a' and 'b' are integers. This
+ # should check that this actually holds.
+ #
+ case "${size}" in
+ *:*)
+ ;;
+ *)
+ printf "E: invalid aspect ratio '%s'!\n" "${size}";
+ exit 1;
+ ;;
+ esac
+
+ ##
+ # Generated images have known sizes that do not change.
+ #
+ from_x=$((${from}*${size%:*}));
+ from_y=$((${from}*${size#*:}));
+
+ printf "Processing %s...\n" "${size}";
+ for k in ${list}; do
+ x=$((${k}*${size%:*}));
+ y=$((${k}*${size#*:}));
+ printf " * Generating %4sx%4s (scale: %s)\n" "${x}" "${y}" "${k}";
+ find "${data}" -mindepth 1 -maxdepth 1 -type d | sort | while read image; do
+ name=$(printf "%s\n" "${image}" | cut -d/ -f3); # sloppy, sorry
+ case "${name}" in
+ background|lockscreen)
+ type="png"; # override for quality
+ ;;
+ *)
+ type="${TYPE}";
+ ;;
+ esac
+ printf " - '%s'\n" "${name}";
+ mkdir -p "${KEEP}"/${name};
+ convert "${image}/${from_x}x${from_y}.png" -resize ${x}x${y}^ "${KEEP}"/${name}/${x}x${y}.${type};
+ done
+ done
+}
+
+#---------------------------------------------------------------
+# internal: core
+#---------------------------------------------------------------
+
+mkdir -p "${HERE}/${TEMP}";
+mkdir -p "${HERE}/${KEEP}";
+
+##
+# Fetch the specified brand asset bundle from distfiles.
+#
+# TODO: error checking, return codes etc.
+#
+(
+ cd "${TEMP}";
+
+ if ! test -e ${NAME}-${HASH}.tar.gz; then
+ curl -O "${HOST}"/source/${NAME}/${NAME}-${HASH}.tar.gz;
+ fi
+
+ tar -xf ${NAME}-${HASH}.tar.gz;
+)
+
+
+#---------------------------------------------------------------
+# internal: generate minimal wallpapers
+#---------------------------------------------------------------
+
+##
+# The default "core" or "slim" wallpaper is made on the fly and
+# not provided as a rasterized image from the start.
+#
+
+##
+# make_fake GRADIENT_FROM GRADIENT_TO XxY TEMPLATE OUTPUT
+#
+make_fake ()
+{
+ size="${1}"; shift; # geometry
+ hexa="${1}"; shift; # gradient from
+ hexb="${1}"; shift; # gradient to
+ temp="${1}"; shift; # template
+ name="${1}"; shift; # output filename
+
+ printf "Generating %5s ('%s')...\n" "${size}" "${name}";
+ magick \
+ -define gradient:angle=65 \
+ -size ${size} \
+ gradient:"${hexa}"-"${hexb}" \
+ "${name}" \
+ ;
+
+ # FIXME: this is literal magic?
+ composite \
+ -compose atop \
+ -gravity southwest \
+ -background none \
+ "${TEMP}"/polyguin.svg \
+ "${name}" \
+ "${name}" \
+ ;
+ composite \
+ -compose atop \
+ -gravity southeast \
+ -background none \
+ "${TEMP}"/gen_polylogo_template_${temp}.png \
+ -geometry +50+20 \
+ "${name}" \
+ "${name}" \
+ ;
+}
+
+
+##
+# Generate starting templates. That is, generate the largest one
+# possible for each aspect ratio.
+#
+printf "%s\n" "${MAKE}" | while read ratio scale _; do
+ # compute largest required
+ x=$((${scale}*${ratio%:*}));
+ y=$((${scale}*${ratio#*:}));
+
+ ############################################################
+ # FIXME!
+ # FOR SOME REASON, CHANGING '#EEEEEF' TO '#EEEEEE' OR FROM
+ # '#303031' TO '#303030' WILL DISCARD COLOR INFORMATION OF
+ # THE COMPOSITED SVG. WTF. WE LEVERAGE THIS THOUGH...
+ ############################################################
+
+ # background (we want the buggy black/white version)
+ mkdir -p "${TEMP}"/generated/background;
+ make_fake ${x}x${y} "#bbbbbb" "#eeeeee" black_x200 "${TEMP}"/generated/background/${x}x${y}.png;
+ #make_fake ${x}x${y} "#bbbbbb" "#eeeeef" black_x200 "${TEMP}"/generated/background/${x}x${y}.png;
+
+ # lockscreen (we want the color version)
+ mkdir -p "${TEMP}"/generated/lockscreen;
+ #make_fake ${x}x${y} "#151515" "#303030" white_x200 "${TEMP}"/generated/lockscreen/${x}x${y}.png;
+ make_fake ${x}x${y} "#151515" "#303031" white_x200 "${TEMP}"/generated/lockscreen/${x}x${y}.png;
+done
+
+
+#---------------------------------------------------------------
+# internal: scale all wallpapers
+#---------------------------------------------------------------
+
+##
+# To generate "real" wallpapers, we simply resize them. This can
+# be be improved significantly, but that is a future problem.
+#
+make_real ()
+{
+ size="${1}"; shift; # geometry
+ temp="${1}"; shift; # template
+ name="${1}"; shift; # output filename
+
+ # TODO: add filename extension checker?
+
+ printf "Generating %5s ('%s')...\n" "${size}" "${name}";
+ convert "${file}" -resize ${size}^ "${name}";
+}
+
+
+##
+# Source images may not all be consistent in their aspect ratios
+# or dimensions. We will scale (crop) source images to match the
+# sizes of the generated core templates.
+#
+printf "%s\n" "${MAKE}" | while read ratio scale _; do
+ # compute largest required
+ x=$((${scale}*${ratio%:*}));
+ y=$((${scale}*${ratio#*:}));
+
+ find "${IMGS}" -mindepth 1 -maxdepth 1 -type d | sort | while read k; do
+ file="$(find ${k} -type f -name 'image.*')";
+
+ if test $(printf "%s\n" "${file}" | wc -l) -ne 1; then
+ printf "E: not exactly one image at '%s'!\n" "${k}";
+ exit 1;
+ fi
+
+ # FIXME: is it OK to hard-code '.png' here?
+ name=$(printf "%s\n" "${file}" | cut -d/ -f2); # sloppy, sorry
+ mkdir -p "${TEMP}"/generated/${name};
+ make_real ${x}x${y} "${file}" "${TEMP}"/generated/${name}/${x}x${y}.png;
+ done
+done
+
+
+#---------------------------------------------------------------
+# output: scale all wallpapers
+#---------------------------------------------------------------
+
+##
+# For each input image, generate a full set of output images.
+#
+# Note that this loop includes all columns; rely on 'size_only'
+# to handle the rest.
+#
+printf "%s\n" "${MAKE}" | while read k; do
+ size_only "${TEMP}"/generated ${k};
+done
+
+
+#---------------------------------------------------------------
+# output: metadata
+#---------------------------------------------------------------
+
+##
+# FIXME: make this not ugly
+#
+temp=$(mktemp);
+cat >> "${temp}" <<"EOF"
+gnome-background-properties/Adelie.xml
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
+<wallpapers>
+EOF
+
+find "${TEMP}"/generated -mindepth 1 -maxdepth 1 -type d | sort | while read k; do
+ name=$(printf "%s\n" "${k}" | cut -d/ -f3); # sloppy, sorry
+ # fix structure
+ mv "${KEEP}"/${name} "${KEEP}"/${name}.tmp;
+ mkdir -p "${KEEP}"/${name}/contents;
+ mv "${KEEP}"/${name}.tmp "${KEEP}"/${name}/contents/images;
+
+ # compute metadata
+ case "${name}" in
+ background)
+ description="Default Background";
+ author_name="Adélie Platform Team";
+ ;;
+ lockscreen)
+ description="Default Lockscreen";
+ author_name="Adélie Platform Team";
+ ;;
+ *)
+ . "${IMGS}"/${name}/MANIFEST;
+ ;;
+ esac
+
+ # write metadata to 'manifest.desktop'
+ # FIXME: we can do better than 'tr' below, but also what are
+ # the actual requirements? I'm just emulating what exists...
+ cat > "${KEEP}"/${name}/contents/metadata.desktop <<EOF
+[Desktop Entry]
+Name=${description}
+X-KDE-PluginInfo-Name=$(printf "%s\n" "${description}" | tr ' ' '-')
+X-KDE-PluginInfo-Author=${author_name}
+X-KDE-PluginInfo-License=CC-BY-SA-4.0
+EOF
+
+ # write metadata to 'gnome-background-properties/Adelie.xml'
+ find "${KEEP}"/${name}/contents/images -type f | grep -v metadata.desktop | sort | while read file; do
+ cat >> "${temp}" <<EOF
+ <wallpaper deleted="false">
+ <name>${description}</name>
+ <filename>/usr/share/wallpapers/${name}/contents/images/${file##*/}</filename>
+ <options>zoom</options>
+ </wallpaper>
+EOF
+ done
+done
+
+##
+# FIXME: make this not ugly
+#
+cat >> "${temp}" <<EOF
+</wallpapers>
+EOF
+
+
+#---------------------------------------------------------------
+# output: create tarball
+#---------------------------------------------------------------
+
+mkdir -p adelie-wallpapers-${VTAG}/usr/share;
+
+# wallpapers
+mv "${KEEP}" adelie-wallpapers-${VTAG}/usr/share/wallpapers;
+
+# gnome-background-properties
+mkdir -p adelie-wallpapers-${VTAG}/usr/share/gnome-background-properties;
+mv "${temp}" adelie-wallpapers-${VTAG}/usr/share/gnome-background-properties/Adelie.xml;
+
+# generate tarball
+tar -pcJf adelie-wallpapers-${VTAG}.tar.xz adelie-wallpapers-${VTAG};
+
+# clean up
+rm -fr "${TEMP}"/generated;
+rm -fr adelie-wallpapers-${VTAG}; \ No newline at end of file