#!/usr/bin/ruby #require 'yaml' require 'rubygems' require 'flickr' require 'osx/cocoa' include OSX OSX.require_framework 'ScriptingBridge' # set up Flickr and check we're authed API_KEY = "" SHARED_SECRET = "" flickr_id = "" # config - aspirational, this tags_direction = "in" # "out", "both" meta_direction = "both" # "in", "out" # utility AppleScript debugging method def dump( thingy ) puts thingy.to_s ( thingy.class.objc_instance_methods - SBApplication.objc_instance_methods ).sort.each do |m| puts " * #{ m }" end end # cache auth details dir = File.expand_path '~/.flickr-match' `mkdir -p #{dir}` unless File.exist?(dir) flickr = Flickr.new(File.join(dir, 'rflickr.cache'), API_KEY, SHARED_SECRET) unless flickr.auth.token flickr.auth.getFrob url = flickr.auth.login_link puts "You must visit #{url} to authorize this application. Press enter "+ 'when you have done so. This is the only time you will have to do this.' gets flickr.auth.getToken flickr.auth.cache_token puts "OK, thanks. Rerun this script and it should go from there." exit end # get Flickr photos now authed fphoto_lookup = Hash.new fphotos = flickr.photos.search(flickr_id, nil, nil, nil, nil, nil, nil, nil, nil, 'date_upload, date_taken, o_dims', '100') # TODO map fphotos.each do |photo| fphoto_lookup[photo.datetaken.to_i] = photo end # puts fphoto_lookup # now loop through photo information iPhoto = SBApplication.applicationWithBundleIdentifier_("com.apple.iPhoto") iPhoto.photos.each do |photo| # cleverer- search for photos with a given date? # maybe if we can fix the predicate select bug name = photo.name # keywords = photo.keywords taken = photo.date epoch = taken.timeIntervalSince1970.to_i tagged = false; flickr_tags = Hash.new if (fphoto_lookup.has_key?(epoch)) # get the corresponding Flickr photo and put out some info fphoto = fphoto_lookup[epoch] puts("photo "+name.to_s+" matches "+fphoto.id) #puts(" "+fphoto_lookup[epoch].url+" taken on") #puts(" "+taken.to_s+"\n") # get the Flickr-side tags flickr_tags = fphoto.tags.reject{ |k| k.raw.to_s.match(':.+=') } flickr_tags = flickr_tags.map{ |k| k.raw.to_s } #puts (" - '"+flickr_tags.join("', '")+"'") # get the iPhoto-side keywords iphoto_keys = photo.keywords.arrayByApplyingSelector("name") if iphoto_keys.containsObject("flickr") # note it then remove it so that we can sync what's left with Flickr tagged = true iphoto_keys.removeObject("flickr") end #puts (" + '"+iphoto_keys.componentsJoinedByString("', '")+"'") #puts (" + and is tagged 'Flickr'? "+tagged.to_s.capitalize) # add Flickr keyword if necessary (TODO add all keywords(!) if !tagged # iPhoto.activate photo.select # because ScriptingBridge appears broken, we hand this off to AS. # sigh. # photo.assignKeywordString("flickr") `osascript -e 'tell application "iPhoto" to assign keyword string "flickr"'` puts (" + locally tagged 'flickr'"); end # add tags for local paths (TODO sync iPhoto keywords) tags = Array.new; home = File.expand_path '~' tags << '"file:name='+photo.imageFilename.to_s+'"' tags << '"file:location='+photo.imagePath.to_s.sub(home, "~")+'"' # would like to add original, but AppleScript doesn't expose it, sigh # could hackily reveal using System Events and query Finder. Ugh. flickr.photos.addTags(fphoto.id, tags) puts (" - tagged with "+tags.join(" ")) end end