#!/usr/bin/env bash

# This script takes all the jpg and mp4 files in a directory and
# organises them into a folder structure based on the month and year
# they were last modified (taken).

# Sources and References
#  - Bash controlled paralellisation - http://unix.stackexchange.com/a/216475/64687

DRY_RUN=false

while test $# -gt 0
do
	case "$1" in
		--help)
			echo organise-photos
			echo "    by Starbeamrainbowlabs <feedback@starbeamrainbowlabs.com>"
			echo "This script takes all the jpg and mp4 files in a directory and organises them into a folder structure based on the month and year they were last modified (taken)."
			echo 
			echo "Options:"
			echo "    --help"
			echo "         Show this help message"
			echo "    --dry-run"
			echo "         Do a dry run - don't actually move any files."
			exit 
			;;
		--dry-run)
			echo Activating dry run mode.
			DRY_RUN=true
	esac
	shift
done

Months=(Zero January February March April May June July August September October November December);

handle_file() {
	local filename=$1;
	
	echo -ne "Processing ${filename} - ";
	
	rawFilename=$(basename "${filename}");
	extension=${filename##*.};
	extension=${extension,,};
	
	takenYear=$(date -r "${filename}" +%Y);
	takenMonth=$(date -r "${filename}" +%-m);
	takenMonthText=$(date -r "${filename}" +%B);
	
	# Extract the date taken from jpegs
	if [[ "${extension}" == "jpg" ]] || [[ "${extension}" == "jpeg" ]];
	then
		takenDate=$(jhead "${filename}" | grep -i 'Date/Time' | cut -d' ' -f6-7);
		takenChars=$(echo ${takenDate} | wc -c);
		if [[ ${takenChars} -gt 1 ]];
		then
			takenYear=$(echo ${takenDate} | cut -d ':' -f1);
			takenMonth=$(echo ${takenDate} | cut -d ':' -f2);
			takenMonthUnpadded=$(echo ${takenMonth//0});
			takenMonthText=${Months[$takenMonthUnpadded]};
		fi
	fi
	
	takenMonth=$(printf "%02d" "${takenMonth}");
	
	newFolder="${takenYear}/${takenMonth}-${takenMonthText}/";
	newFilename="${newFolder}/${filename}";
	
	echo -ne "filing in ${newFolder} - ";
	
	if [ "$DRY_RUN" = true ] ; then
		echo dry run
		continue
	fi
		
	mkdir -p "${newFolder}";
	mv "${filename}" "${newFilename}";
	
	echo Done\!;
}

# Set the number of paralell jobs to the number of cpus
N=$(grep -c ^processor /proc/cpuinfo);

find . -maxdepth 1 \( -iname "*.jpg" -o -iname "*.mp4" -o -iname "*.avi" -o -iname "*.png" \) -print0 | while read -r -d '' filename
do
	((i=i%N)); ((i++==0)) && wait;
	handle_file "${filename}"
done

echo "*** Complete! ***"

exit 0

