Date-shifting in iPhoto ’08

I get a lot of requests to add date-shifting support for iPhoto 08 to my iPhoto AppleScripts. But in most cases, the scripts would be completely unnecessary, iPhoto finally built this feature into the application. Here’s how to use it.

Select one or more photos you’d like to adjust, then choose “Adjust Date and Time…” from the Photos menu:

You then change the Adjusted date to the correct time and all the other photos will be shifted to match.

Using this native tool is substantially faster than anything I could do with AppleScript. I’m just kind of sad I never finished up the auto-date difference calculator I was working on.

Home movies as iTunes TV Shows

Update: At some point, probably with iTunes 8 though I didn’t notice at the time, iTunes added support for batch changing video format, making the script featured in this post obsolete… as it should be.


Original post follows.

We usually keep our home movies in iPhoto, but recently I’ve started moving some select clips into iTunes. Unfortunately, the list of Movies quickly becomes unmanageable. These kinds of videos are much easier to work with when grouped as TV shows, but unfortunately iTunes won’t batch convert Video Kind.

So I wrote a script. In addition to defining selected movies as a show, it also tags their season with the current year and sets the Show Title. Here’s the script: (Open in Script Editor)

set showTitle to display dialog “Enter TV Show Title” default answer “Family Videos” buttons {“Cancel”, “Ok”} default button 2

set theYear to year of (current date) as integer

tell application “iTunes”

copy selection to tracklist

repeat with theTrack in tracklist

set show of theTrack to text returned of showTitle

set season number of theTrack to theYear

set video kind of theTrack to TV show

end repeat

end tell


To use that, just select some movies in iTunes and run the script. Whatever’s selected will be tagged and grouped under the title you entered.

Now our home movies are all grouped together and easily synced to iPhones or other iTunes fed products like iPods and Apple TVs. To view videos on any of those devices, the movies will need to be converted to iPod compatible format. QuickTime can do it, but iSquint/VisualHub can do it much faster.

This could have been done with AtomicParsley, but AppleScript is easier and pre-installed on every Mac.

What would be really great is if iTunes and iPhoto could talk to one another and pull video content out. iPhoto has supported movies for years now, why can’t they talk to each other? (because neither was designed for handling video formats?)

There’s plenty of room to improve this, if you do please post a link in the comments.

Tabbed clipboard to HTML Table

I was looking for a quick way to get a structured table from some data I had in Numbers. Unfortunately Numbers isn’t scriptable and doesn’t seem to offer plain HTML export. After a little poking around, I just ended up writing a script to do what I wanted.

This little AppleScript will convert anything text in the clipboard into a simple, unstyled HTML table. View the script in Script Editor

Just save it into your Scripts folder and call it after copying some data to the clipboard. Any text on your clipboard will be converted to a basic, un-styled HTML table, ready to paste.

set oldDelims to AppleScript‘s text item delimiters

set AppleScript‘s text item delimiters to return

set TRs to every text item of (the clipboard as text)

set AppleScript‘s text item delimiters to tab

set theTable to “<table>” & return

repeat with TR in TRs

copy theTable & “<tr>” & return to theTable

repeat with TD in text items of TR

copy theTable & “<td>” & TD & “</td>” & return to theTable

end repeat

copy theTable & “</tr>” & return to theTable

end repeat

copy theTable & “</table>” to theTable

set AppleScript‘s text item delimiters to oldDelims

set the clipboard to theTable notes

Some combination of screwy net access and a LiquidWeb mail server upgrade resulted in my Inbox duplicating all of the enclosed messages. Since I’m nowhere near inbox zero the glitch resulted in a few thousand messages to wade through. I figured I wasn’t the first to deal with this, and quickly found two scripts which id’d duplicate messages: Tim Auton’s Select Duplicates and Andreas Amann’s Mail Scripts. I ended up going with Time Auton’s script because of his description and a quick review of his code. The script finished quickly enough (running from Script Editor) and left me with all the duplicated messages selected and ready to review and delete.

The LiquidWeb mail upgrade caused another problem, my IMAP folders were now grouped inside my Inbox. The solution was to add the IMAP prefix “INBOX” to the account settings, as shown here:

Mail IMAP preferences

And yes, I do really have that many active email accounts. Pity me.

Note about AppleScript records

When combining an existing AppleScript record with another overlapping record, the order of concatenation matters. Consider this example:

set breakfast to {food:"toast", drink:"coffee"}
set lunch to breakfast & {food:"sandwich"}

--- lunch is {food:"toast", drink:"coffee"}

Because breakfast comes before lunch (naturally, when I get to eat breakfast), food is already defined and isn’t recast by the new record. So we get toast for lunch.

Flipping the order of how the lunch record is built gives the expected result, and a better lunch:

set breakfast to {food:"toast", drink:"coffee"}
set lunch to {food:"sandwich"} & breakfast

--- lunch is {food:"sandwich", drink:"coffee"}

Setting icon position and window size on disk images

Setting up icon placement and window sizes on a disk image isn’t as easy as it should be. Here’s part of my solution for automating a designed disk image with AppleScript.

Fixing Window Size

According to this thread on Apple’s Installer-dev list, window size isn’t written until there is some user interaction, specifically clicking either the green zoom button or the little resizing thingie in the lower right corner. I was unable to get UI Scripting to dependably click the resizing corner, but I did notice that two clicks on the zoom button, after setting a window’s size, toggles between the set size and the zoomed size. So I specified my desired window size, then had System Events click the zoom button (button 2) twice:

set bounds of window 1 to {50, 75, 580, 680}
tell application "System Events" to tell process "Finder" to click button 2 of window 1
tell application "System Events" to tell process "Finder" to click button 2 of window 1

Forcing .DS_STORE to Record Icon Positions

The Finder’s .DS_STORE files are a bit of a mystery. The binary format is closed and there is no programatic way of forcing these files to update. Some smart people have suggested some harebrained workarounds for dealing with this problem, but I wanted something cleaner and more flexible.

My solution was to start fresh by obliterating any .DS_STORE files that might be on the disk image; this appears in the window-layout script before doing anything else:

do shell script "rm " & quoted form of POSIX path of dmgPath & ".DS_STORE"

Next the window is sized, icons are positioned and background image is assigned. Then the script waits to eject the disk* until the .DS_STORE file has been created (open in Script Editor):

set waitTime to 0
set ejectMe to false
repeat while ejectMe is false
    delay 1
    set waitTime to waitTime + 1
    if (do shell script "[ -f " & quoted form of POSIX path of dmgPath & ".DS_STORE ]; echo $?") = "0" then set ejectMe to true
end repeat
log "waited " & waitTime & " seconds for .DS_STORE to be created."
eject dmgPath

On my MacBook Pro, it usually takes 4 seconds for the file to appear. First deleting the file makes sure that the resulting file contains all the new placement information.

Next the disk image gets run through DropDMG and is ready for uploading. I’m ejecting the disk image before converting because I’m getting filesystem errors when I try converting while the source DMG is still mounted. I don’t remember that happening in the past, but it’s probably a good idea to eject first anyway.

EXIF and the Unix Strings command

I got an email over the weekend pointing out a bug in my iPhoto Date Reset if an original image contained a single-quote in its name. Most all of my iPhoto images were imported from the camera, so I hadn’t seen this before, but I’m pretty sure I’ve already gotten it fixed.

While fixing that, I did a little revising of the EXIF sniffing script. I was using a one-line Perl snippet to scrape the date out of the first kilobyte of the file. Here’s the command broken across several lines

 perl -e 'open(IMG, q:[ABSOLUTE PATH}:);
 read(IMG, $exif, 1024); 
 $exif =~ s/\n/ /g; 
 $exif =~ s/.*([0-9]{4}(?::[0-9]{2}){2} [0-9]{2}(?::[0-9]{2}){2}).*$/$1/g;
 print STDOUT $exif;'

That worked, but perl one-liners usually need to be enclosed in single-quotes, since AppleScript was filling in the path, single-quotes in the name broke the script. I’m not that fluent in Perl, so there’re probably better ways of doing that.

But then I stumbled across the Unix Strings command. This basically does most of what I was doing. It scrapes a binary file (meaning non-text) and extracts anything that seems to be a string. The output from JPEGs often contains a bunch of gibberish, but right above the gibberish is every unencoded string from the EXIF header.

Using strings, sed for the pattern and head to trim, that somewhat convoluted perl script became this trim little shell script:

 strings [ABSOLUTE PATH] | sed -E -n '/([0-9]{4}(:[0-9]{2}){2} [0-9]{2}(:[0-9]{2}){2})/p' | head -n1

They’re both essentially instant on my computer so I’m not going to bother building a test to figure out which is actually faster.

Next Page »