Skip to content

Instantly share code, notes, and snippets.

@bhalash
Last active May 7, 2017 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhalash/a7fd1f8080a92c2df7553b126725dc28 to your computer and use it in GitHub Desktop.
Save bhalash/a7fd1f8080a92c2df7553b126725dc28 to your computer and use it in GitHub Desktop.
Instasort
#!/usr/bin/env bash
#
# Sort automatically-uploaded Dropbox photographs and videos into correct
# folders after removing crud like gifs and screenshots:
#
# 1. A dated folder (e.g. 1970-01-01 for an image taken on January, 1970) for
# non-square (non-Instagram) images.
# 2. My dump folder for square Instagram images.
#
# Blame Mark (mark@bhalash.com) for this.
#
# Debug
# set -x
uploads_folder=$HOME'/Dropbox/Camera Uploads/'
instagram_folder=$HOME'/Dropbox/Photos/Instagram/'
IFS='
'
if [[ $UID == 0 ]]; then
exit 1
elif [[ ! -d "$uploads_folder" ]] || [[ ! -d "$instagram_folder" ]]; then
exit 2
fi
function trim_spaces() {
# Safely remove spaces in the file name.
new_name=$(echo "$1" | sed -e 's/ /_/g')
mv "$1" $new_name && echo $new_name
}
function test_aspect_ratio() {
# Test whether the aspect ratio of image $1 == $2:1
x=$(identify -format '%w' $1)
y=$(identify -format '%h' $1)
if [[ ! $file =~ \.jpg$ ]]; then
echo 1
return 1
fi
if [[ $x -ge $y ]]; then
x=$(echo "scale=0; $x * $2" | bc -l)
elif [[ $y -ge $x ]]; then
y=$(echo "scale=0; $y * $2" | bc -l)
fi
if [[ $x -eq $y ]]; then
echo 0
else
echo 1
fi
}
function make_dated_directory() {
# Creates a dated folder and moves the image into it.
directory_name=${1:2:10}
if [[ ! -d $directory_name ]]; then
mkdir $directory_name
fi
mv $1 $directory_name
}
# Find (well, shell regex) behaves differently on OS X. See:
# https://stackoverflow.com/questions/5905493/why-isnt-this-regex-working-find-regex-m-h
# https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man7/re_format.7.html#//apple_ref/doc/man/7/re_format
cd "$uploads_folder"
# find . -maxdepth 1 -type f -regex "^.*\(png\|gif\)$" -exec rm {} \;
find . -maxdepth 1 -type f -name ".*png" -o -name "*.gif" -exec rm {} \;
# for file in $(find . -maxdepth 1 -type f -regex '^.*\s.*\(jpg\|mov\)$'); do
for file in $(find . -maxdepth 1 -type f -name "* *.jpg" -o -name "* *.mov"); do
file=$(trim_spaces "$file")
if [[ $(test_aspect_ratio $file 1) -eq 0 ]]; then
mv $file "$instagram_folder"
else
make_dated_directory $file
fi
done
exit 0
#!/usr/bin/env zsh
#
# Functions
#
is_square() {
#
# Check if Photograph is Square
#
[[ $(identify -format '%w' "$1") == $(identify -format '%h' "$1") ]]
echo $?
}
is_image() {
#
# Check Mimetype
#
grep 'image' <<< $(file --mime-type "$1") > /dev/null 2>&1
echo $?
}
send_to_dated_directory() {
#
# Create Directory from Date in Filename
# Images imported from Dropbox are named in format "2015-12-27 22.13.26.jpg"
#
local filename_date=${1:0:10}
if [[ $filename_date =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
mkdir $filename_date > /dev/null 2>&1
mv "$1" $filename_date
fi
}
#
# Variables
#
uploads_folder="${HOME}/Dropbox/Camera Uploads/"
instagram_folder="${HOME}/Dropbox/Photos/Instagram/"
#
# Main Loop
#
if [[ ! -d $uploads_folder ]] || [[ ! -d $instagram_folder ]]; then
exit 1
fi
cd "$uploads_folder"
for file in *.*; do
case ${file##*.} in
gif|png) rm "$file";;
mov|jpg) mv "$file" ${file// /_} && file=${file// /_};;
esac
if [[ -f $file ]]; then
if [[ $(is_image $file) == 0 ]] && [[ $(is_square $file) == 0 ]]; then
mv $file "$instagram_folder"
else
send_to_dated_directory $file
fi
fi
done
#!/usr/bin/env zsh
#
# Functions
#
#
# Check if Photograph is (Approximately) Square
#
# While it was originally written to detect explicitly square images, it will
# now detect squareness within a tolerance of 10 pixels. Uses the absolute value
# of the size.
#
function is_square {
local WIDTH=$(identify -format '%w' $1)
local HEIGHT=$(identify -format '%h' $1)
local SIZE=`expr $WIDTH - $HEIGHT`
[[ ${SIZE#-} -le ${2:=10} ]]
echo $?
}
#
# Create Directory from Date in Filename
# Images imported from Dropbox are named in format "2015-12-27 22.13.26.jpg"
#
function send_to_dated_directory {
local FILENAME_DATE=${1:0:10}
local DATE_REGEX='^[0-9]{4}-[0-9]{2}-[0-9]{2}$'
if [[ $FILENAME_DATE =~ $DATE_REGEX ]]; then
mkdir $FILENAME_DATE > /dev/null 2>&1
mv "$1" $FILENAME_DATE
fi
}
#
# Move File to Appropriate Location
#
# 1. To a dated folder if not an Instagram image.
# 2. To the Instagram folder otherwise.
#
function move_file {
local EXTENSION_REGEX='^jpg$'
if [[ ${1##*.} =~ $EXTENSION_REGEX ]] && [[ $(is_square $1) == 0 ]]; then
mv $1 "$INSTAGRAM_FOLDER"
else
send_to_dated_directory $1
fi
}
#
# Variables
#
UPLOADS_FOLDER="${HOME}/Dropbox/Camera Uploads/"
INSTAGRAM_FOLDER="${HOME}/Dropbox/Photos/Instagram/"
cd "$UPLOADS_FOLDER"
for FILE in *.*; do
if [[ ! -f "$FILE" ]]; then
continue
fi
NICENAME=$((tr '[A-Z]' '[a-z]' | tr ' ' '_') <<< "$FILE")
mv "$FILE" $NICENAME && FILE=$NICENAME
case ${FILE##*.} in
gif|png) rm $FILE;;
*) move_file $FILE;;
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment