Skip to content

Instantly share code, notes, and snippets.

@voccs
Created June 27, 2012 08:39
Show Gist options
  • Save voccs/3002495 to your computer and use it in GitHub Desktop.
Save voccs/3002495 to your computer and use it in GitHub Desktop.
Split negatives from Adobe Lightroom into DVD-sized libraries for backup to disc.
(*
Splits a Lightroom folder into DVD burnable folders.
Usage
Pick a starting photo and supply the script with Lightroom's
storage location and what disc number you're at. Pay attention,
this script asks for input because AppleScript does not supply
a sane way to burn automatically. After the initial dialogs,
the script will show you a burn folder when one is ready. You
have to hit burn and swap out discs. This script checks in on
you periodically for when the burn is complete before it moves to
the next volume. The script remembers where it left off after
each burn so you can resume later. It will not burn a partially
full disc, possibly leaving some photos unburned so they can fill
out a future disc.
Requirements
Storage is in a specific folder structure based on date:
Lightroom/YYYY/YYYY-MM-DD/
The containing directory (Lightroom above) does not need to be
named anything specifically, but it should contain only
Lightroom-related folders.
It should also not contain any other four-digit number named
folders, only those generated by Lightroom.
The script picks out what it considers later photos by comparing
creation and modification dates of files and directories to that
of the start photo. No photos with a creation date earlier than
the start photo will be burned during the run; no directories with
creation or modification dates earlier than its creation date will
have its contents considered.
Use the command line to delete defaults of com.voccs.BurnPhotoBackups
if the Lightroom location, volume number, or start photo needs
to be reset.
The catalog is not burned with this. Do that separately when
it makes the most sense to you; obviously the catalog does change
over time, so you'll have to keep making new copies of it.
*)
-- Size of a DVD.
set LIBRARY_SIZE_LIMIT to 4.7E+9
-- Ask the user the volume number if not set in defaults.
set volume_number to 1
try
set volume_number to (do shell script "defaults read com.voccs.BurnPhotoBackups VolumeNumber") as number
on error
set volume_number to text returned of (display dialog "Enter the volume number to start burning with (you'll only have to enter this once)." default answer volume_number)
do shell script "defaults write com.voccs.BurnPhotoBackups VolumeNumber -int " & volume_number
end try
-- Ask the user to pick the Lightroom folder if not set in defaults.
set pictures_folder to path to pictures folder from user domain as string
try
set photos_folder to POSIX file (do shell script "defaults read com.voccs.BurnPhotoBackups LightroomHome")
on error
set photos_folder to choose folder with prompt "Select Lightroom's folder (you only need to do this once)." default location POSIX path of pictures_folder
do shell script "defaults write com.voccs.BurnPhotoBackups LightroomHome -string " & quoted form of POSIX path of photos_folder as string
end try
-- Ask the user to pick the starting photo if defaults doesn't know; set this only when the program is finished though.
try
set starting_photo to POSIX file (do shell script "defaults read com.voccs.BurnPhotoBackups StartPhoto") as alias
on error
set starting_photo to choose file with prompt "Select the first photo that hasn't been burned." default location POSIX path of photos_folder
end try
set full_list to {}
set full_list_ref to a reference to full_list
set average_size to 0
set estimate_discs to 0
-- Get a list of all files from the start to the last chronological photo.
tell application "System Events"
set starting_photo_folder to (container of starting_photo)
set starting_year_folder to (container of starting_photo_folder)
set unfiltered_list to {}
set unfiltered_list_ref to a reference to unfiltered_list
copy items of starting_photo_folder to unfiltered_list_ref
-- My Lightroom installation has a specific storage setup based on date. This may not be universally true. Checking creation and modification date of folders since modification changes when new things are added (or old things removed).
set sibling_day_list to (folders of starting_year_folder)
repeat with current_item in sibling_day_list
if the name of current_item is not the name of starting_photo_folder and (the creation date of current_item ≥ creation date of starting_photo or the modification date of current_item ≥ creation date of starting_photo) then
set scratch_list to (items in current_item)
repeat with scratch_item in scratch_list
copy scratch_item to the end of unfiltered_list_ref
end repeat
end if
end repeat
-- This year folder name check in particular may not hold up.
set sibling_year_holder to (container of starting_year_folder)
set sibling_year_list to (folders of sibling_year_holder)
repeat with current_item in sibling_year_list
set isYear to (do shell script "echo " & the name of current_item & " | egrep '^[0-9]{4}$' | wc -l") as number
if isYear > 0 and the name of current_item is not the name of starting_year_folder and (the creation date of current_item ≥ creation date of starting_photo or the modification date of current_item ≥ creation date of starting_photo) then
set current_item_list to (folders of current_item)
repeat with day_folder in current_item_list
set scratch_list to (items of day_folder)
repeat with scratch_item in scratch_list
copy scratch_item to the end of unfiltered_list_ref
end repeat
end repeat
end if
end repeat
-- Filter all aggregated files for only newer files
repeat with current_item in unfiltered_list_ref
if the creation date of current_item ≥ creation date of starting_photo then
copy current_item to end of full_list_ref
end if
end repeat
-- Estimate number of discs based on size of first file, but note it may be different
set average_size to get physical size of disk item (POSIX path of starting_photo)
set estimate_size to average_size * (count of full_list_ref)
set estimate_discs to estimate_size / LIBRARY_SIZE_LIMIT
end tell
set continuing to button returned of (display dialog "You'll need approximately " & (round estimate_discs rounding up) & " discs or more. Continue?" buttons {"Cancel", "Continue"} default button 2 giving up after 10)
if continuing is "Cancel" then return
set disc_size to 0
set disc_list to {}
tell application "System Events"
repeat with to_burn_file in full_list_ref
set this_burn_file_size to get physical size of disk item (POSIX path of to_burn_file)
if disc_size + this_burn_file_size < LIBRARY_SIZE_LIMIT then
set disc_size to disc_size + this_burn_file_size
copy to_burn_file as alias to end of disc_list
else
set burn_folder_name to "Volume" & volume_number
-- put together burnable folder of listed files, with relative paths to photos_folder
do shell script "cd /tmp/; mkdir " & burn_folder_name
do shell script "cd /tmp/; mkdir " & burn_folder_name & ".fpbf"
set burn_folder_contents to POSIX file ("/tmp/" & burn_folder_name) as alias
set burn_folder to POSIX file ("/tmp/" & burn_folder_name & ".fpbf") as alias
set val_list to {}
repeat with burn_file in disc_list
set val to (the name of container of container of burn_file as string) & "/" & (the name of container of burn_file as string)
copy val to the end of val_list
end repeat
with timeout of (30 * 60) seconds
tell application "Finder"
duplicate disc_list to burn_folder_contents
make new alias file at burn_folder to burn_folder_contents
reveal burn_folder
end tell
end timeout
set made_list to {}
repeat with n from 1 to count of disc_list
set partial_path to item n of val_list
if partial_path is not in made_list then
do shell script "cd /tmp/" & burn_folder_name & "/; mkdir -p " & partial_path
copy partial_path to end of made_list
end if
do shell script "cd /tmp/" & burn_folder_name & "/; mv " & (name of item n of disc_list as string) & " " & partial_path
end repeat
display dialog "Time to burn. Insert a new disc if needed. Click 'Burn' in the Finder window that just opened up. I'll check up on you periodically." buttons {"OK"} giving up after 10
-- Ask every eleven minutes
set continuing to ""
repeat while continuing is "Wait" or continuing is ""
delay (11 * 60)
set continuing to button returned of (display dialog "Continue if the burn is complete, otherwise Wait, and I'll ask again in a bit." buttons {"Wait", "Continue"} default button 1 giving up after 15)
end repeat
do shell script "rm -rf /tmp/" & burn_folder_name
do shell script "rm -rf /tmp/" & burn_folder_name & ".fpbf"
set volume_number to volume_number + 1
-- Waypoint; finished my own burning before figuring out how to fix the StartPhoto save
do shell script "defaults write com.voccs.BurnPhotoBackups VolumeNumber -int " & volume_number
--do shell script "defaults write com.voccs.BurnPhotoBackups StartPhoto -string " & (quoted form of POSIX path of (to_burn_file as alias))
set disc_list to {to_burn_file as alias}
set disc_size to get physical size of disk item (POSIX path of to_burn_file)
end if
end repeat
end tell
if (count of disc_list) > 0 then
set first_item to first item of disc_list
display dialog "Finished. The process skipped " & (count of disc_list) & " photos to seed the next disc."
do shell script "defaults write com.voccs.BurnPhotoBackups VolumeNumber -int " & volume_number
do shell script "defaults write com.voccs.BurnPhotoBackups StartPhoto -string " & (quoted form of POSIX path of first_item)
else
display dialog "Finished. Somehow that worked out perfectly and no photos were left straggling at the end."
do shell script "defaults write com.voccs.BurnPhotoBackups VolumeNumber -int " & (volume_number + 1)
do shell script "defaults delete com.voccs.BurnPhotoBackups StartPhoto"
end if
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment