Files
keywords2insta/keywords2insta.sh
2022-08-22 06:57:31 +02:00

424 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
red="\033[1;31m"
greenbold="\033[1;32m"
green="\033[0;32m"
yellow="\033[0;33m"
bold="\033[1m"
#bold_under="\033[1;4m"
underline="\033[4m"
reset="\033[0m"
# Tags automatically added
# You can add tags to this 4 arrays
wild=("wildlife" "wildlifephoto" "wildlifephotographer")
nat=("naturelovers" "natureshot" "naturephotography")
reg=("Bourgogne" "Burgundy" "Bourgogne Franche-Comté" "Côte d'or")
#others=("lanscape" "animal")
others=()
# tags -t mammifere foret animal
opt_others=false
opt_lens=false
opt_model=false
opt_region=false
opt_nature=false
opt_wildlife=false
opt_all=true
showHelp() {
echo -e "${greenbold}keywords2insta${reset} v0.5"
echo -e "Bruno <bruno<clicclac.info>"
echo -e "Read exif and keywords from an image file, and copy them to the clipboard, "
echo -e " ready for Instagram and Flickr."
echo
echo -e "${yellow}USAGE:${reset}"
echo -e "${green}keyword2insta [-Options...] -f <file>${reset}"
echo -e "If no option is chosen, all tags are added (default). "
echo -e "Keywords taken from exifs are automatically added."
echo -e "You can add keywords permanently by adding them to the ${underline}others array${reset} at the start of the script. (See others=())"
echo -e "The images files are not modified."
echo
echo -e "${yellow}OPTIONS:${reset}"
echo -e " ${green}-f${reset}, ${green}--file <file>${reset} Image file"
echo -e " ${green}-l${reset}, ${green}--lens${reset} Add lens exif"
echo -e " ${green}-m${reset}, ${green}--model${reset} Add APN model exif"
echo -e " ${green}-n${reset}, ${green}--nature${reset} Add nature related keywords"
echo -e " ${green}-r${reset}, ${green}--region${reset} Add region related keywords"
echo -e " ${green}-t${reset} <keyword>${reset} Add some additionnals keywords"
echo -e " ${green}-w${reset}, ${green}--wildlife${reset} Add wildlife related keywords"
echo -e " ${green}-h${reset}, ${green}--help${reset} Display this help"
echo
echo -e "${yellow}REQUIEREMENTS:${reset}"
echo -e " -${underline}exiftool${reset} for extract exifs ${bold}(requis)${reset}"
echo -e " brew install exiftool"
echo -e " -${underline}iconv${reset} for suppress accent (optional"
echo -e " brew install iconv"
echo -e " -${underline}gawk${reset} for suppress doubles (optional)"
echo -e " brew install gawk"
echo
echo -e "${yellow}EXAMPLES:${reset}"
echo -e " keyword2insta -f image.jpg"
echo -e " keyword2insta -lm -f image.jpg"
echo -e " keyword2insta --lens --model --file image.jpg"
echo -e " keyword2insta -lm -t deer mammal animal -f deer.jpg"
echo
echo -e "${yellow}EXIT CODES:${reset}"
echo -e " 0: Success !"
echo -e " 1: Exiftool could not be found."
echo -e " 2: No image file."
echo -e " 3: Unknown long option."
echo -e " 4: Unknown short option."
echo -e " 5: No Keywords found in image file."
}
# https://stackoverflow.com/questions/402377/using-getopts-to-process-long-and-short-command-line-options
# le 1er : de $optspec supprime le message d'erreur
unset -v tags
#OPTIND=1
optspec=":wnrf:t:mlh-:"
while getopts "$optspec" opt
do
case $opt in
-) case "${OPTARG}" in
help) showHelp; exit;;
wildlife) opt_wildlife=true;;
nature) opt_nature=true;;
region) opt_region=true;;
file)
file="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
;;
file=*)
file=${OPTARG#*=}
#opt=${OPTARG%=$file}
opt="$(printf "%s\n" "${OPTARG}" | cut -d'=' -f1 )" ; file="$(printf "%s\n" "${OPTARG}" | cut -d'=' -f2-)"
;;
model) opt_model=true;;
lens) opt_lens=true;;
*)
if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" = ":" ]; then
echo "Unknown option --${OPTARG}" >&2
fi
exit 3
;;
esac;;
w) opt_wildlife=true;;
n) opt_nature=true;;
r) opt_region=true;;
f) file="${OPTARG}";;
t) tags=("$OPTARG")
until [[ $(eval "echo \${$OPTIND}") =~ ^-.* ]] || [ -z $(eval "echo \${$OPTIND}") ]; do
tags+=($(eval "echo \${$OPTIND}"))
OPTIND=$((OPTIND + 1))
done
;;
m) opt_model=true;;
l) opt_lens=true;;
h)
showHelp
exit 0
;;
*)
if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then
echo "Non-option argument: '-${OPTARG}'" >&2
fi
exit 4
;;
esac
done
#shift $((OPTIND-1))
if [ $opt_lens = true ] || [ $opt_model = true ] || [ $opt_region = true ] || [ $opt_nature = true ] || [ $opt_wildlife = true ]; then
opt_all=false
fi
if [ ${#others[@]} -gt 0 ] || [ ${#tags[@]} -gt 0 ]; then
opt_others=true
fi
t=$(echo "${tags[@]}" | sed -r 's/[^ ]+/,&/g')
if ! command -v exiftool &> /dev/null; then
echo -e "${bold}exiftool${reset} could not be found !\n"
echo -e "You should install ${bold}exiftool${reset}:\n"
echo -e " - brew install exiftool"
echo -e ""
exit 1
fi
[ ! -f "$file" ] && echo -e "${bold}${red}No input file !${reset}" && exit 2
# dico français / anglais
fr=()
en=()
array=()
declare -A dico
if [ -f ./keywords.csv ]; then
while IFS=';' read -ra array;
do
fr+=("${array[0]}")
en+=("${array[1]}")
done < keywords.csv
j=0
for i in "${fr[@]}"
do
x="${en[$j]}"
dico+=( ["$i"]="$x" )
((j=j+1))
done
fi
echo -e "\n${bold}Reading $file exif...${reset}"
exif=$(exiftool -Canon -s -Keywords "$file")
# The exiftool application exits with a status of 0 on success, or 1 if an
# error occurred, or 2 if all files failed the -if condition (for any of
# the commands if -execute was used).
# keywords
k=$(echo "$exif" | sed -n '/^Keywords/p' | awk -F":" '{print $2}' | sed 's/^ *//g')
if [ -z "$k" ]; then
echo -e "${bold}${red}No Keywords found !${reset}"
echo "Quit."
exit 5
fi
IFS="," read -a key <<< "$k"
for i in "${key[@]}"
do
ii=$(echo "$i" | xargs) # trim $i
if [[ ! "$ii" =~ ^_ ]]; then
if [[ ${dico["$ii"]} ]] ; then
k_en=${dico["$ii"]}
else
k_en=""
fi
k_fr="$ii"
if [ -n "$k_en" ]; then
[[ "$k_fr" = *" "* ]] && keyword_flickr+="\"${k_fr}\" " || keyword_flickr+="${k_fr} "
[[ "$k_en" = *" "* ]] && keyword_flickr+="\"${k_en}\" " || keyword_flickr+="${k_en} "
keyword_insta+="#${k_fr// /} #${k_en// /} "
else
[[ "$k_fr" = *" "* ]] && keyword_flickr+="\"${k_fr}\" " || keyword_flickr+="${k_fr} "
keyword_insta+="#${k_fr// /} "
fi
fi
done
# model
# Canon EOS R6 Canon EOS 5D Mark III Canon EOS-1D Mark IV Canon EOS 20D
m=$(echo "$exif" | sed -n '/^Model/p' | awk -F":" '{print $2}' | xargs)
mod=("${m}") # Canon EOS R6
if [[ "$m" =~ ^Canon ]]; then
mod+=("Canon")
mod+=("canonphotography")
[[ "$m" = *EOS* ]] || mod+=("EOS") # EOS
z=$(echo "$m" | sed 's/Canon\ //g' | xargs)
y=$(echo "$m" | sed 's/EOS//g' | sed 's/[ ][ ]*/ /g' | xargs)
mod+=("${z}") # EOS R6
mod+=("${y}") # Canon R6
fi
for i in "${mod[@]}"
do
model+="${i} "
if [[ "$i" = *" "* ]]; then
model_flickr+="\"${i}\" "
else
model_flickr+="${i} "
fi
model_insta+="#${i// /} " # supprime tous les espaces et ajoute le #
done
#lens
l=$(echo "$exif" | sed -n '/^Lens/p' | awk -F":" '{print $2}' | sed 's/\///g' | xargs)
lens_flickr="\"${l}\" "
lens_insta="$(echo "$l" | sed 's/ //g' | sed -r 's/[^ ]+/#&/g') "
for i in "${wild[@]}"
do
if [[ "$i" = *" "* ]]; then
wildlife_flickr+="\"${i}\" "
else
wildlife_flickr+="${i} "
fi
#wildlife_insta+="#"$(echo "${i}" | iconv -f UTF-8-MAC -t ascii//translit | sed 's/[^a-zA-Z 0-9]//g' | sed 's/ //g')" "
wildlife_insta+="#$(echo "${i}" | iconv -f UTF-8-MAC -t ascii//translit | sed 's/[^a-zA-Z 0-9]//g' | sed 's/ //g') "
done
for i in "${nat[@]}"
do
if [[ "$i" = *" "* ]]; then
nature_flickr+="\"${i}\" "
else
nature_flickr+="${i} "
fi
nature_insta+="#$(echo "${i}" | iconv -f UTF-8-MAC -t ascii//translit | sed 's/[^a-zA-Z 0-9]//g' | sed 's/ //g') "
done
for i in "${reg[@]}"
do
if [[ "$i" = *" "* ]]; then
region_flickr+="\"${i}\" "
else
region_flickr+="${i} "
fi
region_insta+="#$(echo "${i}" | iconv -f UTF-8-MAC -t ascii//translit | sed 's/[^a-zA-Z 0-9]//g' | sed 's/ //g') "
done
: <<'END_COMMENT'
echo "Model flickr: $model_flickr"
echo "Model insta: $model_insta"
echo
echo "Keywords flickr: $keyword_flickr"
echo "Keywords insta: $keyword_insta"
echo
echo "Lens flick: $lens_flickr"
echo "Lens_insta: $lens_insta"
echo
echo "Wildlife flickr: $wildlife_flickr"
echo "Wildlife insta: $wildlife_insta"
echo
echo "Nature flickr: $nature_flickr"
echo "Nature insta: $nature_insta"
echo
echo "Region flickr: $region_flickr"
echo "Region insta: $region_insta"
echo
echo "tags: ${tags[@]}"
echo "others: ${others[@]}"
echo "file: $file"
echo "wildlife: $opt_wildlife"
echo "nature: $opt_nature"
echo "region: $opt_region"
echo "model: $opt_model"
echo "lens: $opt_lens"
echo "all: $opt_all"
echo
END_COMMENT
if [ $opt_all = false ]; then
if [ $opt_wildlife = false ]; then
wildlife_flickr=""
wildlife_insta=""
fi
if [ $opt_nature = false ]; then
nature_flickr=""
nature_insta=""
fi
if [ $opt_region = false ]; then
region_flickr=""
region_insta=""
fi
if [ $opt_lens = false ]; then
lens_flickr=""
lens_insta=""
fi
if [ $opt_model = false ]; then
model_flickr=""
model_insta=""
fi
fi
keywords_flickr="$keyword_flickr$model_flickr$lens_flickr$wildlife_flickr$nature_flickr$region_flickr"
keywords_insta=$(echo "$keyword_insta$model_insta$lens_insta$wildlife_insta$nature_insta$region_insta" | awk '{print tolower($0)}')
if [ $opt_others = true ]; then
# insert tags added with option -t to others's tag array
others+=($(echo "$t" | tr ',' ' '))
for i in "${others[@]}"
do
if [[ ${dico["$i"]} ]] ; then
o_en=${dico["$i"]}
else
o_en=""
fi
if [ -n "$o_en" ]; then
[[ "$i" = *" "* ]] && others_flickr+="\"${i}\" " || others_flickr+="${i} "
[[ "$o_en" = *" "* ]] && others_flickr+="\"${o_en}\" " || others_flickr+="${o_en} "
others_insta+="#${i// /} #${o_en// /} "
else
[[ "$i" = *" "* ]] && others_flickr+="\"${i}\" " || others_flickr+="${i} "
others_insta+="#${i// /} "
fi
done
keywords_flickr+="$others_flickr"
keywords_insta+="$others_insta"
fi
: <<'END_COMMENT'
echo "$keywords_flickr"
echo
echo "$keywords_insta"
echo
END_COMMENT
# suppress accent (bug in macos) => add sed => suppress punctuation too
# https://stackoverflow.com/questions/806199/how-to-fix-weird-issue-with-iconv-on-mac-os-x
if ! command -v iconv &> /dev/null; then
echo -e "\n${bold}iconv${reset} could not be found !\n"
echo -e "It's required for suppress accents."
echo -e "You should install ${bold}icon${reset}:"
echo -e " - brew install iconv"
echo -e ""
else
keywords_insta=$(echo "$keywords_insta" | iconv -f UTF-8-MAC -t ascii//translit | sed 's/[^a-zA-Z 0-9 \#]//g')
fi
# suppress duplicates (gawk)
if ! command -v gawk &> /dev/null; then
echo -e "\n${bold}gawk${reset} could not be found !\n"
echo -e "It's required for suppress duplicates."
echo -e "You should install ${bold}gawk${reset}:"
echo -e " - brew install gawk"
echo -e ""
else
#keywords_flickr=$(echo "$keywords_flickr" | gawk -v RS="[ \n]" -v ORS=" " '!($0 in a){print;a[$0]}')
keywords_insta=$(echo "$keywords_insta" | gawk -v RS="[ \n]" -v ORS=" " '!($0 in a){print;a[$0]}')
fi
if [[ "$OSTYPE" == "linux-gnu" ]] && [ -x "$(command -v xsel)" ]; then
xsel -b <<< "$keywords_insta"
elif [[ "$OSTYPE" == "darwin"* ]] && [ -x "$(command -v pbcopy)" ]; then
pbcopy <<< "$keywords_insta"
fi
echo -e "\n${bold}The Instagram's tags are available in your clipboard !${reset}"
echo "$keywords_insta"
echo -e "\n${bold}Here the Flickr's tags too !${reset}"
echo "$keywords_flickr"