Added list2map.sh tool

This commit is contained in:
Luxferre
2023-04-03 19:14:01 +03:00
parent f9a9be171c
commit aa3a252203
2 changed files with 62 additions and 1 deletions
+27 -1
View File
@@ -2,7 +2,7 @@
Bopher Tools is a small collection of simple shell scripts that:
- are written in pure Bash with no external dependencies;
- are written in pure Bash with no external dependencies (unless explicitly stated otherwise);
- are totally independent from each other (but can be combined in the true spirit of Unix philosophy);
- only accept input from stdin and only output their results into stdout;
- aim to ease your life when it comes to creating and publishing your own content in Gopherspace.
@@ -133,3 +133,29 @@ When running `cat example.gmi | bash gmi2txt.sh 67 5`, this file translates to t
See ya!
```
## `list2map.sh`
This tool, which probably is the smallest but the most sophisticated one in the entire collection, accepts the list of files and directories (possibly generated with `find` command) and generates, line by line, a portion of Gophermap based on their type (for this, it requires the external `file` command dependency), root directory name and hostname/port number optionally passed to the script on invocation. The tool automatically applies the following rules:
- only the basename part of the file/directory is used as the entry name/description;
- if the file is a directory (MIME type `inode/directory`), the generated selector will actually refer to the `index.map` file in that directory and the entry type will be 1;
- files (or directories) named `index.map` are not themselves included in the output;
- if the file's MIME type starts with `text`, the entry type will be set to 0, otherwise it will be set to 9.
Note that the tool itself doesn't do any filtering on input names or how they are presented. All filtering, if necessary, should be done on the `find` invocation step.
Example - build a Gophermap fragment from this repo's starting directory, excluding all dotfiles, using `.` as root and assuming we'll serve this map from `example.com:777`:
```
$ find . ! -path '.' ! -path '*/.*' | bash tools/list2map.sh . example.com 777
0COPYING /COPYING example.com 777
1tools /tools/index.map example.com 777
0gopherinfo.sh /tools/gopherinfo.sh example.com 777
0phlow.sh /tools/phlow.sh example.com 777
0gmi2map.sh /tools/gmi2map.sh example.com 777
0gmi2txt.sh /tools/gmi2txt.sh example.com 777
0README-tools.md /tools/README-tools.md example.com 777
0list2map.sh /tools/list2map.sh example.com 777
0bopher-ng.sh /bopher-ng.sh example.com 777
0README.md /README.md example.com 777
```
+35
View File
@@ -0,0 +1,35 @@
#!/bin/bash
# A simple tool for Gophermap fragment generation from existing file/directory lists
# Depends on file external command to determine the type
#
# Usage: find [root] [params] | list2map.sh
#
# Created by Luxferre in 2023, released into public domain
shopt -s extglob # enable extended pattern matching (just to be sure)
RDIR="$1" # root directory, no substitution if empty
THOST="$2" # can be empty per spec
TPORT="$3" # can be empty too
INDEXFILE='index.map' # the basename to consider an index file
typequery() { # external command wrapper to fetch the file's MIME type
local res="$(file -Nn --mime-type "$1")"
printf '%s' "${res##*: }"
}
while read -rs fpath; do # fully line-based operation
ftype="$(typequery "$fpath")" # MIME type here
bname="${fpath##*/}" # basename here
[[ "$bname" == "$INDEXFILE" ]] && continue # skip index map
etype=9 # default map entry type is binary until proven otherwise
esel="${fpath##$RDIR}" # if RDIR is empty, they are the same
if [[ "$ftype" == 'inode/directory' ]]; then # it's a directory
etype=1
esel="${esel}/${INDEXFILE}" # update the selector
elif [[ "${ftype%%/*}" == 'text' ]]; then # update etype for text files
etype=0
fi
# output the RFC-compliant Gophermap line
printf '%s%s\t%s\t%s\t%s\r\n' "$etype" "$bname" "$esel" "$THOST" "$TPORT"
done