From ee7ab22140c5f4833ddf659b1ca83219bbb461c2 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Sun, 31 Jan 2021 22:59:37 -0600 Subject: [PATCH] Init --- README.txt | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ spacetemplate | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 README.txt create mode 100755 spacetemplate diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..6bbb49e --- /dev/null +++ b/README.txt @@ -0,0 +1,112 @@ +================================================================================ +SPACETEMPLATE +================================================================================ +Spacetemplate lets you recursively apply a directory "template" to another +directory (on Haiku). + +For example, let's say you are very particular in how your "Music" folder +windows look in Tracker― you need the "Music" folder to be a particular size, at +a particular spot, and you want all artists to be in another spot, and all +albums in another spot. + +You could manually move and resize every folder in Music, but that's annoying. +Or you could write a script to apply a given template to all Music subdirectories. + +… That's what this is. The template script. + +======================================== +USAGE +======================================== + +$ spacetemplate templatefolder folder + +There are no arguments― it'll just apply the template folder to the folder. + + +======================================== +TEMPLATES +======================================== +A template folder hierarchy should look like the target folder's. +It'll copy the attributes from the template folder to the corresponding target, +for example: + + template/Apple/ --> target/Apple/ + template/Apple/Dad --> target/Apple/Dad/ + template/Pear/Mom --> target/Pear/Mom/ + +If a folder is in the target but doesn't have a match in the template, it'll +be ignored. + +There is a fallback: _default_ + +_default_ will match any folder in matches to its parent folder, as long +as there isn't a direct match. + +So: + template/_default_/ --> target/Apple/ + template/_default_/Dad/ --> target/Apple/Dad/ + template/_default_/_default_/ --> target/Pear/Mom/ + +Keep in mind, though, that if there is a direct template for a folder, it won't +match a _default_ in the same parent directory. Default is for any folder there +is no direct match for. + + template/_default_/ --> target/Pear/ + template/Apple/ --> target/Apple/ + +Since there is a direct match to Apple, template/_default_/ won't be applied +to Apple. Only template/Apple/ will. + +There is a wildcard, too: _all_ + +_all_ will match all (surprise) folders in its parent directory, even if they +have direct matches. It's basically _default_ applied to everything. + + template/_default_/ --> target/Pear/ + template/_all_/ --> target/Pear/ + template/Apple/ --> target/Apple/ + template/_all_/ --> target/Apple/ + +_default_ applies to Pear, but not Apple― _all_ applies to both Pear and Apple. + +One more bit: _default_ and _all_ matches won't copy over the position of the +folder (trk/pinfo_le). Since if it did that, you'd end up with a bunch of +folders piled on top of each other. What a hassle. +Direct matches will copy location over, though. + +The order of application is: + # _all_ + # _default_ + # Direct + +If there is a direct match, it will apply after _all_. If there is a _default_, +it will apply before _all_. + + +======================================== +EXAMPLE +======================================== +Sooo back to the music organization problem… +Here's an example of how you'd solve that. + + template/_default_/ --> Music/*/ + template/_default_/_default_/ --> Music/*/*/ + +Kinda anti-climactic, for all that build-up… +Alright, let's make it more interesting. + +"Rhapsody of Fire" is a band that's had several incarnations, so it would make +sense if you grouped all the Rhapsody derivatives into a single directory, as +an exception to the above rules. + + template/Rhapsody/_default_/ --> Music/Rhapsody/*/ + template/Rhapsody/_default_/_default_/ --> Music/Rhapsody/*/*/ + +Still not very interesting. Dang. Well, you get the point lol + + +======================================== +BORING STUFF +======================================== +MIT License +Jaidyn Ann, diff --git a/spacetemplate b/spacetemplate new file mode 100755 index 0000000..96e82c0 --- /dev/null +++ b/spacetemplate @@ -0,0 +1,112 @@ +#!/bin/sh +# -------------------------------------- +# name: spacetemplate +# main: +# lisc: MIT +# date: 2021 +# -------------------------------------- + +# Recursively apply a template directory to a target directory. +function apply_template { + local template="$1" + local target="$2" + + echo "$target…" + copy_template "$template" "$target" + + apply_specific all "$template" "$target" + + for file in "$template"/*; do + local basename="$(basename "$file")" + + if test -d "${target}/$basename" \ + -a ! "$basename" = '*' + then + if test -h "$file"; then file="$(readlink "$file")"; fi + apply_template "$file" "${target}/$basename" + fi + done + + apply_specific default "$template" "$target" +} + +# Check if a specific template folder (_all_ or _default_) exists for given +# template and target, and apply where necessary. +function apply_specific { + local type="$1" + local template="$2" + local target="$3" + + if test -e "${template}/_${type}_"; then + local type_template="${template}/_${type}_" + + if test -h "$type_template"; then + type_template="$(readlink "$type_template")" + fi + + for file in "$target"/*; do + local basename="$(basename "$file")" + local apply=0 + if test "$basename" = '*'; then break; fi + + if test "$type" = "all"; then apply=1; fi + if test ! -d "${template}/$basename"; then apply=1; fi + + if test "$apply" -eq 1; then + apply_template "$type_template" "$file" 0 + fi + done + fi +} + + +# Actually copy over attributes from template file to target file +function copy_template { + local template="$1" + local target="$2" + + if test ! -d "$target"; then return; fi + if test -h "$template"; then template="$(readlink "$template")"; fi + if test ! -d "$template"; then return; fi + + catattr -r _trk/pinfo_le "$target" 2> /dev/null \ + > "$TEMP" + + copyattr "$template" "$target" + addattr -f "$TEMP" -t raw _trk/pinfo_le "$target" 2> /dev/null + + echo "" \ + > "$TEMP" +} + + +function help { + echo "usage: $(basename $0) [-h] templatedir directory" + echo + echo \ +"Makes a target directory have attributes matching the templatedir, according +to certain rules. Useful if you're particular about where folders' windows +should be. + +See the README for information on the structure of template dirs." + exit 1 +} + + +while getopts ":h" arg; do + case $arg in + h) help;; + esac +done + +shift $(($OPTIND - 1)) +TEMPLATE=$1 +TARGET=$2 + +if test -z "$TEMPLATE" -o -z "$TARGET"; then help; fi +if test ! -e "$TEMPLATE" -o ! -e "$TARGET"; then help; fi + +TEMP="$(mktemp)" +apply_template "$TEMPLATE" "$TARGET" + +rm "$TEMP"