New static art page

I created a simple, static page generator for showing off art I have gotten over the years. No JavaScript, cloud, CDNs involved.

You can find it on gallery.lightwo.net.

So, what went into it?

First, image tagging. Using EXIF tags, I avoided having to somehow store data about images separately from the images themselves. I did take some liberty to misuse some tags, which may have been a bad idea, but it works...!

Second, CSS...

But it's just visual shit!

Not really. I used it instead of the dreaded JavaScript in order to hide NSFW by default, using the "checkbox hack". Neat, right? it totally wasn't because I can't do JavaScript

Lastly, and most importantly, I did it in... BASH! Because I can't even imagine using a programming language to get something done at this point.

#!/bin/bash

# https://overflow.adminforge.de/exchange/unix/questions/624596/how-do-i-construct-a-script-to-insert-multiple-filenames-in-to-a-html-file

# $1 - attribute to take
function get_attrib() {
    exiftool -m -b -$1 "${image}" 
}

function get_attribs() {
    exiftool -m -imagewidth -imageheight -title -artist -ownername -datetimeoriginal -usercomment "${image}"
}

# It is faster to take all values first and filter them second, rather
# than executing exiftool every time

# $1 - attribute to take, as worded by output
function extract_attrib() {
    echo "${attribs}" | grep "$1" | cut -d':' -f2 | cut -c2-
}

function get_description() {
    echo "${imagedescription}" | while read line
    do
        if [ "${line}" != "" ]
        then
            line=$(echo ${line} | recode u8..html)
            echo "                <p>${line}</p>"
        fi
    done
}

if [ ! -d images ]
then
    >&2 echo "Cannot find images dir"
    exit 1
fi

read -r -d '' before_image <<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
    <title>lightwo's image gallery</title>
    <meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <link rel="icon" type="image/svg+xml" href="/res/favicon.svg" />
</head>
<body>
    <h1>lightwo's image gallery</h1>
    <hr />
    <p class="nocss" style="color: #bb0000; height: 100vh;">
        Warning! Your user agent does not support CSS or you are explicitly blocking it.
        This page relies on CSS to block content only intended to be viewed by mature
        audiences. Proceed at your own risk.
    </p>
    <div> <!-- Why? XHTML 1.1 -->
    <input type="checkbox" id="nsfw_toggle" class="toggle_button" />
    <label for="nsfw_toggle" class="toggle_button"><big>Show NSFW</big> (you must be over the age of 18)</label>

    <div id="image_container">
EOF

read -r -d '' data_image <<EOF
        <div class="image%s" id="%s">
            <a href="images/%s">
                <img src="thumbs/%s" alt="" width="%s" height="%s" />
            </a>
            <div class="image_desc">
                <h2>%s</h2>
%s
                <p>Artist: %s</p>
                <h3>Characters</h3>
                <ul class="characters">
                    %s
                </ul>
                <h3>Tags</h3>
                <ul class="tags">
                    %s
                </ul>
            </div>
        </div>
EOF

read -r -d '' after_image <<EOF
    </div></div>
</body>
</html>
EOF

printf "%s\n" "${before_image}"

for image in `ls -t images/*`
do
    >&2 echo "Getting ${image} attribs..."
    attribs="$(get_attribs)"

    ##
    # Easy
    ##

    filename="$(basename $image)"
    anchor="$(echo $filename | rev | cut -s -d'.' -f2- | rev)" # Filename without extension
    imagewidth="$(extract_attrib 'Image Width')"
    width="${imagewidth}"
    imageheight="$(extract_attrib 'Image Height')"
    height="${imageheight}"
    title="$(extract_attrib 'Title')"
    artist="$(extract_attrib 'Artist')"
    imagedescription="$(get_attrib imagedescription)" # Special case, may contain newlines
    description="$(get_description)"
    #description="$(echo ${imagedescription} | recode u8..html)"
    #description="$(echo ${description//$'\n'/'<br />'})"
    # Unused
    #datetimeoriginal="$(extract_attrib 'Date/Time Original')"

    ##
    # Tricky
    ##

    # Characters (has to be <li> item)
    # Space by design due to data structuring
    ownername=" $(extract_attrib 'Owner Name')"
    characters=""
    OIFS=$IFS
    IFS=,
    for i in ${ownername}
    do
        i="$(echo ${i} | cut -c2-)"
        characters+="<li>${i}</li>"
    done
    IFS=$OIFS

    # Tags (has to be <li> item, special condition if NSFW is one of them)
    # TODO: Possibly append some or all tags as classes? Could be used for cool styling,
    #       but could be tricky due to XHTML 1.1 limitations (A-Z a-Z 0-9 -_:.)
    usercomment="$(extract_attrib 'User Comment')"
    tags=""
    classes=""
    for i in ${usercomment//,/ }
    do
        if [ "${i}" == "nsfw" ]
        then
            classes+=" nsfw"
        fi

        tags+="<li>${i}</li>"
    done

    printf "${data_image}" "${classes}" "${anchor}" "${filename}" "${filename}" "${width}" "${height}" \
    "${title}" "${description}" "${artist}" "${characters}" "${tags}"

    # Generating thumbnail if one does not exist
    if [ ! -f "thumbs/${filename}" ]
    then
        >&2 echo "Generating thumbnail..."
        mkdir -p thumbs
        convert "${image}" -resize '500x500>' "thumbs/${filename}"
    fi
done

printf "%s\n" "${after_image}"

The assumed file structure is ./index.html, ./images/*.{png,jpg,...}, and thumbnails are generated in ./thumbs.

It's stupid, but it works!