Created
September 19, 2017 03:22
-
-
Save brokensandals/4b602110adcc58d56346514ad9309668 to your computer and use it in GitHub Desktop.
script & launchd config for importing photos from a folder into the Photos app on Mac
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
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Label</key> | |
<string>net.brokensandals.photos.sync.applefromgoogle</string> | |
<key>Program</key> | |
<string>/Users/jacob/dotfiles/bin/sync-apple-photos-from-google-photos.rb</string> | |
<key>StartCalendarInterval</key> | |
<array> | |
<dict> | |
<key>Hour</key> | |
<integer>0</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
<dict> | |
<key>Hour</key> | |
<integer>3</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
<dict> | |
<key>Hour</key> | |
<integer>6</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
<dict> | |
<key>Hour</key> | |
<integer>9</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
<dict> | |
<key>Hour</key> | |
<integer>12</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
<dict> | |
<key>Hour</key> | |
<integer>15</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
<dict> | |
<key>Hour</key> | |
<integer>18</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
<dict> | |
<key>Hour</key> | |
<integer>21</integer> | |
<key>Minute</key> | |
<integer>0</integer> | |
</dict> | |
</array> | |
<key>StandardOutPath</key> | |
<string>/Users/jacob/log/sync-apple-photos-from-google-photos-stdout.log</string> | |
<key>StandardErrorPath</key> | |
<string>/Users/jacob/log/sync-apple-photos-from-google-photos-stderr.log</string> | |
</dict> | |
</plist> |
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
#!/usr/bin/env ruby | |
require 'digest' | |
require 'open3' | |
google_photos_dir = '/Users/jacob/Google Drive/Google Photos' | |
apple_photos_dir = '/Users/jacob/Pictures/Photos Library.photoslibrary/Masters' | |
def get_photo_paths(dir) | |
Dir.glob(File.join(dir, '**', '*.*')) | |
end | |
def get_photo_paths_by_digest(dir) | |
get_photo_paths(dir).group_by { |path| Digest::MD5.file(path).hexdigest } | |
end | |
google_photos = get_photo_paths_by_digest(google_photos_dir) | |
puts "Google Photos Count: #{google_photos.count}" | |
apple_photos = get_photo_paths_by_digest(apple_photos_dir) | |
puts "Apple Photos Count: #{apple_photos.count}" | |
missing_from_apple = google_photos.keys - apple_photos.keys | |
unless missing_from_apple.count > 0 | |
puts "No photos missing from Apple Photos." | |
exit 0 | |
end | |
puts "Apple Photos is missing #{missing_from_apple.count} photos:" | |
missing_from_apple.each { |digest| puts google_photos[digest].first } | |
if missing_from_apple.count > 100 && ARGV[0] != '--force' | |
STDERR.puts "There are a large number of photos to import. If you are sure this is correct, rerun with --force" | |
system 'osascript', '-e', "display notification \"Skipped sync for #{missing_from_apple.count} photos; script must be run with --force to import this many\" with title \"Google->Apple Photos Sync\"" | |
exit 1 | |
end | |
add_file_script_lines = missing_from_apple.map do |digest| | |
"set end of filesToImport to POSIX file \"#{google_photos[digest].first}\"" | |
end | |
script = <<-APPLESCRIPT | |
set filesToImport to {} | |
#{add_file_script_lines.join("\n")} | |
with timeout of 30 * 60 seconds | |
tell application "Photos" | |
import filesToImport | |
end tell | |
end timeout | |
APPLESCRIPT | |
puts "Running applescript to import photos..." | |
script_stdout, script_stderr, script_status = Open3.capture3('osascript', stdin_data: script) | |
puts script_stdout unless script_stdout.empty? | |
STDERR.puts script_stderr unless script_stderr.empty? | |
puts "Finished with exit code #{script_status}" | |
unless script_status == 0 | |
system 'osascript', '-e', "display notification \"Failed sync for up to #{missing_from_apple.count} photos\" with title \"Google->Apple Photos Sync\"" | |
exit 1 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment