Created
March 17, 2012 08:49
-
-
Save shouya/2056807 to your computer and use it in GitHub Desktop.
A batch operation script to sync the pictures from my phone to pc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
: << DOC | |
This script does scan all the photo from my phone and pull them out into a | |
temporary directory. After then, it will arrange the photos into special | |
directory by taken date, and if the target directory does not exist, the script | |
will create one to store such files. Subsequently and optionally, it could | |
convert all the photos imported into wiki image size and put the outputs into | |
another temporary directory, and show me them to deal. | |
Special Tools Requirement: | |
* Android Debug Bridge (adb) | |
* wikiphoto (another script written by me) | |
* ImageMagick (convert) | |
* bc | |
* exiv2 | |
Have fun! | |
DOC | |
# Configurations | |
## Environment Setting | |
use_sudo="yes" | |
open_program=gnome-open | |
## Target Directory Setting | |
target_dir="$HOME/Pictures/" | |
uncat_dir="$HOME/Pictures/else" | |
## Import Setting | |
need_root="no" | |
photo_dir="/sdcard/DCIM" | |
import_hidden_dir="no" | |
match_regex=".*\.(png|jp[e]?g)$" | |
## Wikify Setting | |
wikify="yes" | |
wikify_dir="$HOME/Pictures/wiki" | |
wikify_script="$HOME/script/wikiphoto" | |
## Others | |
open_dir_at_the_end="yes" | |
# Here is the END of configuration | |
# Program Body | |
# Do NOT modified the code below unless you know what you're doing | |
# global variables | |
_sub_dirs= | |
_tmp_dir= | |
_org_dir=`pwd` | |
_photo_lst= | |
_jpg_date= | |
_wikify_name= | |
# Functions | |
# Meta Functions | |
exec_cmd() { | |
cmd="$1" | |
(sleep 0.3; echo "$cmd"; echo exit) | | |
adb shell | | |
sed -e '1 d' -e '$ d' | |
} | |
clean_and_exit() { | |
[ -d "$_tmp_dir" ] && { | |
rm -rf "$_tmp_dir" | |
} | |
[ -z "$1" ] && exit 1 || exit $1 | |
} | |
# chop last character of a line | |
chop() { | |
sed 's/.$//' | |
} | |
# check if file is a jpg | |
is_jpg() { | |
result="`file "$1" | grep -i 'JPEG' | wc -l`" | |
[ "$result" -eq "0" ] && | |
return 1 || | |
return 0 | |
} | |
# acquire a jpg file's shooting date | |
jpg_date() { | |
jpg="$1" | |
[ ! -z "$(exiv2 "$jpg" 1>/dev/null 2>/dev/stdout)" ] && return 1 | |
_jpg_date=$( | |
exiv2 "$jpg" 2>/dev/null | | |
grep timestamp | | |
sed -r -e 's/.*:\s//' \ | |
-e 's/([0-9]{4}):([0-9]{2}):([0-9]{2}).*$/\1 \2 \3/' | |
) | |
[ -z "$_jpg_date" ] && | |
return 1 || | |
return 0 | |
} | |
# get special field | |
get_field() { | |
awk "{print \$$1}" | |
} | |
# ask whether the file will be overrieded | |
ask_override() { | |
org="$1" | |
dst="$2" | |
o_ctime="`stat $org | sed -n '/^Change/p' | | |
sed -r 's/Change:\s(.*)\..*$/\1/'`" | |
d_ctime="`stat $dst | sed -n '/^Change/p' | | |
sed -r 's/Change:\s(.*)\..*$/\1/'`" | |
o_size="`stat $org | sed -n '/Size/p' | | |
sed -r 's/.*Size:\s([0-9]*).*/\1/'`" | |
d_size="`stat $dst | sed -n '/Size/p' | | |
sed -r 's/.*Size:\s([0-9]*).*/\1/'`" | |
echo "File conflict:" | |
echo " Original $org(ctime: $o_ctime, size: $o_size)" | |
echo " Destination $dst(ctime: $d_ctime, size: $d_size)" | |
echo -n "Do you want to override it (y/N): " | |
read user_input | |
case "$user_input" in | |
[yY]* ) return 0;; | |
[nN]* ) return 1;; | |
esac | |
return 1 | |
} | |
wikify_name() { | |
org_name="$1" | |
_wikify_name=$( | |
echo $org_name | | |
sed -r 's/(.*)\.(.*)$/\1.wiki.\2/' | |
) | |
[ -z "$_wikify_name" ] && return 1 | |
return 0 | |
} | |
# Main implement starts here | |
# try to start adb deamon | |
start_server() { | |
echo -n "Restarting the server..." | |
[ "$need_root" = "yes" ] && { | |
[ "$use_sudo" = "yes" ] && { | |
sudo adb kill-server | |
sudo adb start-server > /dev/null | |
} || { | |
su -c "adb kill-server && adb start-server > /dev/null" | |
} | |
} || { | |
adb kill-server | |
adb start-server > /dev/null | |
} | |
[ "$?" -ne "0" ] && { | |
echo "Failed!" | |
return 1 | |
} || { | |
echo "Succeed!" | |
return 0 | |
} | |
} | |
# check device whether it is avalible, return 0 if succeed. | |
check_device() { | |
echo -n "Checking device connection..." | |
[ $(adb devices | wc -l) -ge '3' ] || { | |
echo "Failed!" | |
return 1 | |
} | |
echo "Succeed!" | |
return 0 | |
} | |
# check the photo directory if exists | |
check_photo_dir() { | |
echo -n "Checking photo directory..." | |
[ $(exec_cmd "cd $photo_dir" | wc -l) = "4" ] && { | |
echo "Failed!" | |
return 1 | |
} || { | |
echo "Succeed!" | |
return 0 | |
} | |
} | |
# list all the subdirectoris below the photo directoy on the device | |
list_sub_dir() { | |
dir_org=$(exec_cmd "ls -l -a $photo_dir" | | |
grep '^d' | | |
awk '{print $6}') | |
_sub_dirs=$( | |
[ "$import_hidden_dir" = "yes" ] && { | |
echo "$dir_org" | |
} || { | |
echo "$dir_org" | while read ln | |
do | |
[ -z "$(echo $ln | sed '/^\./d')" ] || { | |
echo $ln | |
} | |
done | |
} ) | |
_sub_dirs=$( | |
echo "$_sub_dirs" | while read ln | |
do | |
echo "$photo_dir/$ln" | |
done | |
) | |
return 0 | |
} | |
# make a temporary directory | |
make_temp_dir() { | |
echo -n "Making temporary directory..." | |
_tmp_dir="`mktemp -d`" | |
[ "$?" -ne "0" ] && { | |
echo "Failed!" | |
return 1 | |
} | |
echo "Succeed!" | |
return 0 | |
} | |
# transfer the files from device to the temporary directory | |
pull_files() { | |
echo "Transfering photos (this process may take long time)..." | |
echo "$_sub_dirs" | while read dir | |
do | |
dir=`echo "$dir" | chop` | |
echo "Now transfering: $dir" | |
adb pull "$dir" 2>/dev/null 1>/dev/null | |
[ "$?" -ne "0" ] && { | |
echo "Error when transfering $dir" | |
return 1 | |
} | |
done | |
return 0 | |
} | |
# scan all photos imported into a list | |
scan_photos() { | |
echo -n "Scanning photos imported..." | |
_photo_lst=$(find -regextype posix-extended \ | |
-type f -a \ | |
-iregex "$match_regex") | |
[ "$?" -ne 0 ] && { | |
echo "Failed!" | |
return 1 | |
} | |
echo "Succeed!" | |
return 0 | |
} | |
process_jpg() { | |
photo="$1" | |
jpg_date "$photo" || { | |
process_else "$photo" | |
return $? | |
} | |
year=`echo $_jpg_date | get_field 1` | |
month=`echo $_jpg_date | get_field 2` | |
date=`echo $_jpg_date | get_field 3` | |
target_file_dir="$target_dir/$year/$month/$date" | |
target="$target_file_dir/$photo" | |
# copying file to spcial directory | |
mkdir -p "$target_file_dir" 2>/dev/null | |
[ -e "$target" ] && { | |
[ `md5sum "$photo" | get_field 1` = \ | |
`md5sum "$target" | get_field 1` ] && { | |
# skip the file | |
return 0 | |
} || { | |
ask_override "$photo" "$target" && | |
cp -f "$photo" "$target" | |
} | |
} || { | |
cp -f "$photo" "$target" | |
} | |
echo -n "Imported & categoried $photo" | |
# generate wiki image | |
[ "$wikify" != "yes" ] || wikify_name "$photo" || { | |
echo "." | |
return 0 | |
} | |
mkdir -p "$wikify_dir" 2>/dev/null | |
$wikify_script "$photo" 1>/dev/null 2>/dev/null | |
mv -bf "$_wikify_name" "$wikify_dir" 2>/dev/null | |
echo " and wikified." | |
return 0 | |
} | |
process_else() { | |
photo="$1" | |
mkdir -p "$uncat_dir" 2>/dev/null | |
target="$uncat_dir/$photo" | |
[ -e "$target" ] && { | |
[ `md5sum "$photo" | get_field 1` = \ | |
`md5sum "$target" | get_field 1` ] && { | |
# skip the file | |
return 0 | |
} || { | |
ask_override "$photo" "$target" && | |
mv -f "$photo" "$target" | |
} | |
} || { | |
mv -f "$photo" "$target" | |
} | |
echo "Imported uncategoried $photo." | |
return 0 | |
} | |
process_all_photos() { | |
echo "$_photo_lst" | while read photo | |
do | |
is_jpg "$photo" && { | |
process_jpg "$photo" | |
} || { | |
process_else "$photo" | |
} | |
done | |
return 0 | |
} | |
open_output_dir() { | |
[ "$open_dir_at_the_end" != "yes" ] && return 0 | |
$open_program "$target_dir" | |
} | |
# Main flow | |
start_server || clean_and_exit | |
check_device || clean_and_exit | |
check_photo_dir || clean_and_exit | |
list_sub_dir # || clean_and_exit | |
make_temp_dir || clean_and_exit | |
cd "$_tmp_dir" || clean_and_exit | |
pull_files || clean_and_exit | |
scan_photos || clean_and_exit | |
process_all_photos || clean_and_exit | |
open_output_dir || clean_and_exit | |
clean_and_exit | |
# EOF | |
# Shou Ya | |
# Morning Mar 17, 2012 yet another sleepless night! | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment