#!/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 " 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 ${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 ${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} ${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"