I often see a single photo/art gallery with a nested folder structure that Stash treats as multiple galleries.
For example, Stash would look at a structure like this and make galleries of the 6 innermost folders that have pictures:
Cosplayer/
March 2022/
Gwen Stacy/
Cosplay Photoset/
Boudoir Photoset/
Backstage/
Videos/
Marin Kitagawa/
Cosplay Photoset/
Boudoir Photoset/
Backstage/
Videos/
The innermost folder structure is important, but it is not the most natural grouping, and causes related items to get separated in the app.
If you create a zip file of each related gallery, it will preserve the file structure within that zip file and Stash will treat it as a single gallery. But you don’t want to include videos in the zip file as they will not be seen by Stash or CBZ viewers.
Gwen Stacy/
Gwen Stacy.cbz
Videos/
Marin Kitagawa/
Marin Kitagawa.cbz
Videos/
Here is a script to make a single uncompressed zip file from all images in a folder and its subfolders, without also including videos.
#!/bin/sh -e -u
# make-cbz.sh
# Create a .CBZ file of all the images in a directory.
# Leave non-image files in place.
# Example:
# > make-cbz.sh images/
# ...
# Created images.cbz
# Example: zip all subdirectories
# > for f in */; do make-cbz.sh "$f"; done
# ...
# Created a.cbz
# Created b.cbz
# Created c.cbz
echo
DIR="$1"
shift
if [ ! -d "$DIR" ]; then
echo Error: "$DIR" is not a directory. Cancelled.
exit 1
fi
# Work relative to parent folder of dir, to simplify path within zip file.
cd "$DIR"
DIR="$(basename "$PWD")"
cd ..
# Check whether this zipfile has already been created.
ZIPFILE="${DIR%/}.cbz"
if [ -f "$ZIPFILE" ]; then
echo Error: "$ZIPFILE" already exists. Cancelled.
exit 2
fi
if [ -f "${DIR}/$(basename "$ZIPFILE")" ]; then
echo "$ZIPFILE" already exists within "$DIR". Skipped.
exit 0
fi
echo Creating "$ZIPFILE"...
# Simple command to zip only common image suffixes
# zip -0 --latest-time -m -r "$ZIPFILE" "$DIR" \
# -i '*.jpeg' -i '*.jpg' -i '*.gif' -i '*.png' -i '*.svg' -i '*.webp' \
# -i '*.JPEG' -i '*.JPG' -i '*.GIF' -i '*.PNG' -i '*.SVG' -i '*.WEBP'
# Function to identify image files based on contents
function list_images() {
local IFS="$(printf "\x1E\n")"
find "$1" -exec file --separator "$IFS" {} \; \
| grep -i "image data" \
| cut -d "$IFS" -f 1 - \
| sort --version-sort
}
if [ -z "$(list_images .)" ]; then
echo No image files found in "$DIR". Skipped.
exit 0
fi
# Zip identified images with no compression, and remove original files
list_images "$DIR" | zip -0 --latest-time -m "$ZIPFILE" -@
if [ ! -f "$ZIPFILE" ]; then
echo Error: "$ZIPFILE" was not created.
exit 3
fi
echo Created "$ZIPFILE"
# Remove empty folders.
find "$DIR" -name ".DS_Store" -delete
find "$DIR" -type d -empty -delete
# If main directory was not empty, move zipfile into it to stay with related files.
if [ -d "$DIR" ]; then
mv "$ZIPFILE" "$DIR"/
echo Moved "$ZIPFILE" into "$DIR/"
fi