4

I've been looking around via Google for some pointers to get me going on something I need to do in iPhoto via AppleScript, but so far haven't found a whole lot. There are various old discussions of scripts for various old versions of iPhoto floating around, but nothing that's been particularly helpful with what I need. Basically, in pseudo-code, I'm looking to do this:

for each photo in library
  if photo.Description contains "a known string"
    photo.Description = photo.Description.Replace("a known string", "")
  end if
end for

That is, I have a piece of errant text which has made its way into every (well, nearly every) photo in my library. I'm guessing I botched up a batch change at some point in the past and didn't notice it until now. Either that or the upgrade from iPhoto '08 to '11 did it somehow. Either way, the net result is the same.

I'm not well-versed in AppleScript, and am having trouble just finding the right syntax/vocabulary to use in this. Basically, I'm at the tell application "iPhoto" part, but don't know what to tell it. If the hierarchy of how photos in the library are organized is important:

  1. Every photo is organized chronologically into events. (Events are my primary form of organization.)
  2. There are a good number of albums, but not everything is in an album.
  3. There is a single smart album which contains every errant photo. This is, of course, based on the presence of the known string in the photo description. So I suppose that may need to be kept in mind if the final code loops through photos in this smart album, since the smart album may be changing the array being iterated over, no?

Does anybody have any references or sample code to help get me going? Conversely, does anybody know of a better way to do this one-time mass fix?

Edit: I ran a test with the following code:

tell application "iPhoto"
    activate
    set thePhotos to get every photo
    repeat with aPhoto in thePhotos
        if aPhoto's comment contains "[known string]" then
            log aPhoto's comment
            tell aPhoto to set it's comment to text 1 thru (offset of "[known string]" in aPhoto's comment) of aPhoto's comment
            log aPhoto's comment
            exit repeat
        end if
    end repeat
end tell

Which resulted in the following output:

tell application "iPhoto"
    activate
    get every photo
    get comment of photo id 4.294977224E+9
    (*comment of photo id 4.294977224E+9*)
    offset of "[known string]" in comment of photo id 4.294977224E+9
    «event ascrgdut»
    offset of "[known string]" in comment of photo id 4.294977224E+9
end tell
tell current application
    offset of "[known string]" in «class pcom» of «class ipmr» id 4.294977224E+9
Result:
error "iPhoto got an error: Can’t make comment of photo id 4.294977224E+9 into type string." number -1700 from comment of photo id 4.294977224E+9 to string

Edit: I had some time to tinker with it this morning and it looks like some type casting was all that was needed. This code is now successfully changing the first matching photo it finds:

tell application "iPhoto"
    activate
    set thePhotos to get every photo
    repeat with aPhoto in thePhotos
        if aPhoto's comment contains "[known string]" then
            log aPhoto's comment as text
            set theComment to aPhoto's comment as text
            set theComment to text 1 thru (offset of "[known string]" in theComment) of theComment
            tell aPhoto to set it's comment to theComment
            log aPhoto's comment as text
            exit repeat
        end if
    end repeat
end tell

Now to back up my library and remove the exit repeat. And probably go do something else for a while as it runs :)

David
  • 208,112
  • 36
  • 198
  • 279

2 Answers2

4

Here's a 'brute force' version. This will loop through every photo. You could make this more elegant by restricting to certain albums if you wanted.

tell application "iPhoto"
    set thePhotos to get every photo
    repeat with aPhoto in thePhotos
        if aPhoto's comment contains "theString" then
            tell aPhoto to set it's comment to "newString"
        end if
    end repeat
end tell
dscl
  • 1,616
  • 7
  • 28
  • 48
  • @dscl: Running a test on this with an `exit repeat` after the first catch of the conditional, but I get an error. Adding the Events output to the question. Maybe `comment` should be something like `description` instead? Maybe `comment` is an object which itself has a text field I'm looking for? – David Jan 18 '11 at 01:29
  • @david: What version of iPhoto are you using? They may have changed the names from the version I tested in. – dscl Jan 18 '11 at 15:48
  • @dscl: '11 (recently upgraded from '08 through the new app store, so the library was originally '08). – David Jan 18 '11 at 16:52
  • @david: Ahh okay, I'm on iPhoto '08 as well, but I have some friends who should have 11. I'll take a look at the library on one of their machines first chance I get. – dscl Jan 18 '11 at 20:48
  • @dscl: Awesome. Is this something I can look into as well? I guess I just don't really know where to start with AppleScript development. But if there's an library or object model I can reference then I can do a little experimentation in the code. – David Jan 18 '11 at 20:51
  • @david: I should be going to my buddies tonight who has iPhoto '11 so I can look at it then. Sorry for the delay. In the meantime if you open up script editor while iPhoto is loaded you can view the application's Library. Check out the properties of the Photo object. – dscl Jan 20 '11 at 14:07
  • @dscl: I'm looking through the "Dictionary" feature in AppleScript Editor now (just poking around, never saw this part before). When I go to iPhoto's Dictionary, select iPhoto suite, and photo, it shows the "comment" property as text. Strange. – David Jan 20 '11 at 14:20
  • @dscl: I had some time to tinker with it this morning and it looks like it just needed some type casting in order to work (updated code is in the question). Thanks for the help! – David Jan 23 '11 at 14:50
1

What about this. You would need to make an album or smart album of the items you wish to impact, but this is less destructive anyway.

tell application "iPhoto"
    activate
    set thePhotos to get every photo in current album whose comment contains "TEST123"
    repeat with aPhoto in thePhotos
        tell aPhoto to set it's comment to "123TEST"
    end repeat
end tell
Bubba
  • 19
  • 3