Files
keywords2insta/keywords2insta.sh
Bruno21 58da213080 Version 2
-use json data from exiftool
-support all APN Makers (not only Canon)
-some bugfixs
2023-07-18 20:14:51 +02:00

656 lines
18 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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=()
# Display Instagram AND/OR Flickr tags
insta=true
flickr=true
opt_others=false
opt_lens=false
opt_model=false
opt_region=false
opt_nature=false
opt_wildlife=false
opt_all=true
long_path=`pwd`"/"`basename "$0"` # /Users/bruno/Documents/Scripts/kymsu2/keywords2insta.sh
#long_path=$(realpath "$0") # vide
echo "long: $long_path"
dir=$(dirname "$0")
#dir="$0"
echo "dir: $dir"
trim () {
read -rd '' $1 <<<"${!1}"
}
alpha_name=
alpha () {
array=()
#declare -A ilce=( ['ILCE-7M3']="Alpha 7 III" ['ILCE-7M4']="α7 IV" ['ILCE-7MRM5']="α7R V" ['ILCE-7SM3']="Alpha 7S III" ['ILCE-7RM4']="α7R IV" ['ILCE-7RM3']="α7R III" ['ILCE-7C']="Alpha 7C" )
declare -A ilce
if [ -f $dir/sony.csv ]; then
#echo "Loading Sony APNs..."
while IFS=';' read -ra array;
do
key="${array[0]}"
value="${array[1]}"
ilce["$key"]="$value"
done < $dir/sony.csv
fi
for val in "${!ilce[@]}"
do
[[ ${val} == "$model" ]] && alpha_name="${ilce[$val]}"
done
}
showHelp() {
echo -e "${greenbold}keywords2insta${reset} v1.1"
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=()
array2=()
declare -A dico
if [ -f $dir/keywords.csv ]; then
echo "Loading keyword dictionary..."
while IFS=';' read -ra array2;
do
fr+=("${array2[0]}")
en+=("${array2[1]}")
done < $dir/keywords.csv
j=0
for i in "${fr[@]}"
do
x="${en[$j]}"
dico+=( ["$i"]="$x" )
((j=j+1))
done
fi
echo -e "\n${greenbold}keywords2insta${reset} v2.0"
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).
#exif=$(exiftool -Canon -s -Keywords -j "$file")
exif=$(exiftool -j "$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).
# exif
#echo "$exif"
#if (jq -e '.[] | has("Make")' <<< "$exif"); then
# make=$(echo "$exif" | jq -j '.[] | .Make')
#else
# make="z"
#fi
#make=$(echo "$exif" | jq -e '.[] | has("Make") | .Make')
make=$(echo "$exif" | jq -j '.[] | .Make | select( . != null )')
model=$(echo "$exif" | jq -j '.[] | .Model | select( . != null )')
date_original=$(echo "$exif" | jq -j '.[] | .DateTimeOriginal | select( . != null )')
speed=$(echo "$exif" | jq -j '.[] | .ShutterSpeed | select( . != null )')
aperture=$(echo "$exif" | jq -j '.[] | .Aperture | select( . != null )')
iso=$(echo "$exif" | jq -j '.[] | .ISO | select( . != null )')
lens=$(echo "$exif" | jq -j '.[] | .Lens | select( . != null )')
lensID=$(echo "$exif" | jq -j '.[] | .LensID | select( . != null )')
lensModel=$(echo "$exif" | jq -j '.[] | .LensModel | select( . != null )')
focal=$(echo "$exif" | jq -j '.[] | .FocalLength | select( . != null )')
echo
if [[ -n $iso ]] && [[ -n $speed ]] && [[ -n $aperture ]]; then
printf " %-10s %-35s \n" "Speed:" "${speed}"
printf " %-10s %-35s \n" "Aperture:" "f/${aperture}"
printf " %-10s %-35s \n" "ISO:" "${iso}"
printf " %-10s %-35s \n" "Date:" "${date_original}"
printf " %-10s %-35s \n" "Maker:" "${make}"
[[ "$make" =~ ^SONY ]] && alpha
printf " %-10s %-35s \n" "APN:" "$alpha_name (${model})"
printf " %-10s %-35s \n" "Focal:" "${focal}"
if [[ -n $lensID ]]; then
printf " %-10s %-35s \n" "LensID:" "${lensID}"
l="$lensID"
elif [[ -n $lensModel ]]; then
printf " %-10s %-35s \n" "LensModel:" "${lensModel}"
l="$lensModel"
else
printf " %-10s %-35s \n" "Lens:" "${lens}"
l="$lens"
fi
echo
fi
# keywords
k=$(echo "$exif" | jq --compact-output --raw-output '.[] | .Keywords[]?' | tr "\n" "," | sed 's/\,$//')
#k=$(echo "$exif" | sed -n '/^Keywords/p' | awk -F":" '{print $2}' | sed 's/^ *//g')
if [ -z "$k" ]; then
echo -e "\n${bold}${red}No Keywords found !${reset}"
echo "Quit."
#exit 5
fi
IFS="," read -a key <<< "$k"
#echo "key:${key[@]}_"
#echo "dico:${dico[@]}_"
for i in "${key[@]}"
do
#echo "@$i@"
# @ bouton d'or@
# xargs: unterminated quote
#ii=$(echo "$i" | xargs -0) # trim $i
#ii=$(echo "$i" | sed 's/ *$//g')
ii="$i"
trim ii
#trim i
#echo "i:$i"
#echo "ii:$ii"
if [[ ! "$ii" =~ ^_ ]]; then
#echo "ii: $ii"
#echo ${dico["$ii"]}
if [[ ${dico["$ii"]} ]] ; then
k_en=${dico["$ii"]}
else
k_en=""
fi
k_fr="$ii"
#echo "k_fr:$k_fr"
#echo "k_en:$k_en"
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
#echo "keyword_insta:$keyword_insta"
#echo "keyword_flickr:$keyword_flickr"
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
# "Make": "OM Digital Solutions",
# "Model": "OM-5", "OM-1"
# "Make": "SONY",
# "Model": "ILCE-7M3", "ILCE-7M4"
# "Make": "FUJIFILM",
# "Model": "X-T5",
# "Make": "Panasonic",
# "Model": "DC-S5",
# "Make": "LEICA CAMERA AG",
# "Model": "LEICA Q3", "LEICA SL2-S"
# "Make": "NIKON CORPORATION",
# "Model": "NIKON D850",
# "Make": "NIKON CORPORATION",
# "Model": "NIKON Z 9",
# "Make": "Canon",
# "Model": "Canon EOS R7",
#mod=("${model}")
#m=("${model}")
#echo "mod:${mod[@]}_"
#echo "m:${m[@]}_"
if [[ "$make" =~ ^Panasonic ]] || [[ "$make" =~ ^SONY ]] || [[ "$make" =~ ^FUJI ]]; then
mod=("${make} ${model}")
mod+=("${make}")
mod+=("${model}")
mod+=("${make,,}photography")
elif [[ "$make" =~ ^"OM Digital Solutions" ]]; then
mod=("${make} ${model}") # OM Digital Solutions OM-5
mod+=("Olympus") # Olympus
mod+=("${model}") # OM-5
elif [[ "$model" =~ ^NIKON ]] || [[ "$model" =~ ^LEICA ]]; then
mod=("${make}")
z=$(echo "${make,,}" | awk '{print $1}') ## nikon
y=$(echo "${make}" | awk '{print $1}') ## NIKON
mod+=("${z}photography") # nikonphotography leicaphotography
mod+=("${y}") # NIKON LEICA
mod+=("${model}") # NIKON Z 9 LEICA Q3
# awk -F"|" '{$1=$2=$3=""; print $0}' PURCHASE_testing.csv > testing.csv
w=$(echo "${model}" | awk '{$1=""; print $0}' | xargs)
mod+=("${w}")
elif [[ "$model" =~ ^Canon ]]; then
mod+=("Canon")
mod+=("${make,}photography")
[[ "$model" = *EOS* ]] || mod+=("EOS") # EOS
z=$(echo "$model" | sed 's/Canon\ //g' | xargs)
y=$(echo "$model" | sed 's/EOS//g' | sed 's/[ ][ ]*/ /g' | xargs)
mod+=("${z}") # EOS R6
mod+=("${y}") # Canon R6
fi
#echo "mod:${mod[@]}_"
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
#echo "model_flickr: $model_flickr"
#echo "model_insta: $model_insta"
#lens
# "LensModel": "E 28-200mm F2.8-5.6 A071",
# "Lens": "E 28-200mm F2.8-5.6 A071",
# "LensID": "Tamron 28-200mm F2.8-5.6 Di III RXD",
# "LensModel": "FE 35mm F2.8 ZA",
# "Lens": "FE 35mm F2.8 ZA",
# "LensID": "FE 35mm F2.8 ZA"
# LensID": "OLYMPUS M.12-45mm F4.0"
# "LensModel": "OLYMPUS M.12-45mm F4.0",
# "Lens": "OLYMPUS M.12-45mm F4.0",
# "LensModel": "OLYMPUS M.300mm F4.0",
# "Lens": "OLYMPUS M.300mm F4.0",
# "LensID": "OLYMPUS M.300mm F4.0"
# "Lens": "OLYMPUS M.300mm F4.0", "Lens": "OLYMPUS M.12-45mm F4.0",
# "LensModel": "OLYMPUS M.300mm F4.0", "LensModel": "OLYMPUS M.12-45mm F4.0",
# Leica no Lens no LensID
# "LensModel": "SUMMILUX 1:1.7/28 ASPH.", "Leica APO-Summicron-SL 35mm f/2 ASPH",
# "LensModel": "Leica APO-Summicron-SL 35mm f/2 ASPH",
# "Lens": "Leica APO-Summicron-SL 35mm f/2 ASPH",
# "LensID": "Leica APO-Summicron-SL 35mm f/2 ASPH"
# "Lens": "Fujifilm Fujinon XF18mmF1.4 R LM WR",
# "LensModel": "Fujifilm Fujinon XF18mmF1.4 R LM WR",
# LensID": "LUMIX S 20-60mm F3.5-5.6"
# "Lens": "LUMIX S 20-60/F3.5-5.6",
# "LensModel": "LUMIX S 20-60/F3.5-5.6",
# "LensID": "Fujifilm Fujinon XF18mm F1.4 R LM WR"
# "Lens": "400mm f/2.8",
# "LensID": "AF-S VR Nikkor 400mm f/2.8G ED",
# Nikon si LensModel vide => LensID
# "LensModel": "VR 300mm f/2.8G",
# "Lens": "300.0 mm f/2.8",
# "LensID": "VR 300mm f/2.8G"
# "LensModel": "EF600mm f/4L IS III USM",
# "LensID": "Canon EF 600mm f/4L IS III USM"
# "Lens": "EF600mm f/4L IS III USM",
# 1 LensID puis 2 LendModel
lens_flickr="\"${l}\" "
lens_insta="$(echo "$l" | sed 's/ //g' | sed -r 's/[^ ]+/#&/g') "
#echo "lens_flickr: $lens_flickr"
#echo "lens_insta: $lens_insta"
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
# 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
# copy tags to clipboard
if [ "$insta" = true ]; then
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 "\nPress <Enter> to get the Flickr' tags..."
read -p ""
fi
if [ "$flickr" = true ]; then
if [[ "$OSTYPE" == "linux-gnu" ]] && [ -x "$(command -v xsel)" ]; then
xsel -b <<< "$keywords_flickr"
elif [[ "$OSTYPE" == "darwin"* ]] && [ -x "$(command -v pbcopy)" ]; then
pbcopy <<< "$keywords_flickr"
fi
[ "$insta" = true ] && echo -e "\n${bold}Here the Flickr's tags too !${reset}" || echo -e "\n${bold}The Flickr's tags are available in your clipboard !${reset}"
echo "$keywords_flickr"
fi