#!/usr/bin/env oil # A quick script on moving a file with embedded data. # It can only detect certain files and write the metadata with a certain program. # For the argument, it needs the path of the files to be moved. # Dependencies: # * Oil shell v0.8.8 # * vorbis-tools v1.4.2 # * exiftool v12.16 # * file 5.38 # * coreutils 8.32 shopt --set strict:all var help_section = "A script for embedding metadata and renaming them files. edit-file-metadata [options...] FILE Options: -h, --help Show the help section. -a, --author [AUTHOR] Set the author. -d, --date [DATE] Set the date. -t, --title [TITLE] Set the title. --skip Skip the prompt for missing metadata and only change the needed metadata. This only works if you've set any of the metadata in the command line. --json Return a JSON object on stdout. --move Move the filename from the kebab-case of the title. " var path = '' var author = '' var title = '' var pub_date = '' var skip = false var json_data = false var move = false while test $# -gt 0 { case $1 { -h|--help) echo $help_section exit 0 ;; -a|--author) set author = $2 shift 2 ;; -t|--title) set title = $2 shift 2 ;; -d|--date) set pub_date = $2 shift 2 ;; --skip) set skip = true shift ;; --json) set json_data = true shift ;; --move) set move = true shift ;; *) set path = $1 shift ;; } } proc kebab-case(word) { # Convert into lower case. set word = $(echo $word | tr '[:upper:]' '[:lower:]') # What happens to this line: # * Convert all whitespace and dashes into a single dash. # * Remove all invalid characters (all that are not alphanumeric characters and dashes). # * Remove leading and trailing dashes. set word = $(echo $word | sed --regexp-extended --expression 's/\s+|-+/-/g' --expression 's/[^.a-z0-9-]//g' --expression 's/^-+|-+\$//g') echo $word } proc prompt(string, :out, prefix = ">> ") { >&2 printf "%s\\n%s" $string $prefix read --line setref out = $_line } proc file_parse(path, :out) { var extension_regex = / '.' ![ '.' ]+ %end / var file = {} set file['dir'] = $(dirname $path) set file['name'] = $(basename $path | sed --regexp-extended "s|(.+)${extension_regex}|\\1|") set file['ext'] = $(basename $path | sed --regexp-extended "s|.+(${extension_regex})|\\1|") set file['mime_type'] = $(file --mime-type --brief $path) setref out = file } test -f $path || { >&2 echo "${path} is not a regular file" exit 1 } # Prompt for the missing metadata (if it's configured to not skip, anyways). if (not skip) { test $title || prompt "What is the title?" :title test $author || prompt "Who are the authors?" :author test $pub_date || prompt "When this file published?" :pub_date } # Writing up the metadata time! # Each file type has a different way of embedding metadata so it needs different tools. # We'll use exiftool as a catch-all since it supports the most out of... 15 file types I considered. case $(file --mime-type --brief $path) { "audio/ogg") vorbiscomment --write $path --tag "TITLE=${title}" --tag "ARTIST=${author}" --tag "DATE=${pub_date}" || opustags $path --in-place --delete-all --add "TITLE=${title}" --add "ARTIST=${author}" --add "DATE=${pub_date}" ;; *) exiftool -title="${title}" -author="${author}" -date="${pub_date}" ${path} ;; } file_parse $path :file_info if (json_data) { var metadata = {} set metadata['file'] = file_info set metadata['title'] = $title set metadata['author'] = $author set metadata['date'] = $pub_date json write :metadata } if (move) { mv $path "${file_info['dir']}/$(kebab-case $title)${file_info['ext']}" }