The audience at Seven on Seven watched a projection of David Kravitz’s screen as he chatted with Frances Stark in the Messages app for Mac (known as iChat up until 2012). This was their performance Opening the Kimono, a highlight of the conference. Later we kicked ourselves for not capturing David’s screen during the performance. Our documentation consists of this video and an .ichat log file–which David kindly provided. This post is about playing back Opening the Kimono from the log in real-time using AppleScript. For context about the piece, see this article on Rhizome.

What does one get when opening a chat log in Messages? Pretty pastel chat bubbles. But this format is not so easy to parse. To wrangle the log file, I used the beautifully-named software Logorrhea. Logorrhea exports iChat logs as text files. The first line looks like:

SevenOnSevenFrancesStarkDavidKravitz davidkravitz 05/03/2014 16:57:43 hi frances!

The above looks oddly like TSV (Tab-Separated Values). By changing the extension to .tsv, spreadsheet programs will happily open it, yielding something like:

A B C D E SevenOnSevenFrancesStarkDavidKravitz davidkravitz 05/03/2014 16:57:43 hi frances! SevenOnSevenFrancesStarkDavidKravitz francesstark 05/03/2014 16:57:49 well hello David! … … … … …

I’m no spreadsheet wizard, so to find the time elapsed between messages I use Python’s datetime module.

>>> import datetime >>> >>> message_time = '16:57:43' >>> next_message_time = '16:57:49' >>> >>> delta = datetime . datetime . strptime ( next_message_time , '%H:%M:%S' ) - datetime . datetime . strptime ( message_time , '%H:%M:%S' ) >>> print delta . seconds 6 >>>

But what I really want is to convert the log data into a native AppleScript data type–I don’t want to parse anything in AppleScript, ever. Python’s built-in CSV module can parse TSV as well, and with some clever string formatting, one can convert the rows of data into an AppleScript list of lists, which can later be plopped into an AppleScript source file. Here is code to do this:

import csv import datetime DELIM = ' \t ' PATH = '/Users/scott/Desktop/iChat Export.tsv' row_buffer = [] output = [] with open ( PATH , 'rU' ) as tsvfile : tsvreader = csv . reader ( tsvfile , delimiter = DELIM ) # load rows in buffer so we can look ahead row_buffer = [ row for row in tsvreader ] for idx , row in enumerate ( row_buffer ): try : next_row = row_buffer [ idx + 1 ] delta = ( datetime . datetime . strptime ( next_row [ 3 ], '%H:%M:%S' ) \ - datetime . datetime . strptime ( row [ 3 ], '%H:%M:%S' )) . seconds except IndexError : delta = 0 output . append ( '{{"{}",{},"{}"}}' . format ( row [ 1 ] . split ( '@' )[ 0 ], delta , row [ 4 ] . rstrip ( '

' ))) print '{' + ', ' . join ( output ) + '}'

A subset of the output from the above:

{{"davidkravitz", 6, "hi frances!"}, {"francesstark", 8, "well hello David!"}, {"davidkravitz", 30, "how’s it going?"}, {"francesstark", 9, "I’m feeling more than a little excited about much of what we discussed yesterday"}, {"davidkravitz", 17, "yeah me too"}, {"davidkravitz", 4, "we should start by telling the audience a bit about the start of this whole thing"}, {"davidkravitz", 15, "namely"}, {"davidkravitz", 6, "i had a friend who suggested that we do performance art"}, {"davidkravitz", 6, "well, what he called performance art"}, {"francesstark", 52, "hahahhaha"}}

AppleScript allows OS level automation for programs that implement the interface for it (most do, which makes it very useful). To fake the conversation, two chat clients (iChat and Adium) are automated to talk to each other. In the following code sample, pretend I’ve already assigned all the output from the above into a variable called theBigList.

repeat with i from 1 to count of theBigList set theLine to items of item i of theBigList set theSender to item 1 of theLine set theDelay to item 2 of theLine set theMessage to item 3 of theLine if ( theSender = "davidkravitz" ) then tell application "iChat" set theBuddy to buddy "protonpopsicle" of service "AIM" send theMessage to theBuddy end tell end if if ( theSender = "francesstark" ) then tell application "Adium" send the active chat message theMessage end tell end if delay theDelay end repeat

Your browser does not support the video tag.

After all that work, we (Rhizome) ended up manually recreating the performance with human actors. Why? With the automated method, one cannot see messages being typed into the message box before they are sent. Even though it is possible to simulate this typing with AppleScript, the rhythm of the typing, the puases for comprehension and other subtleties of the performance are not present in the log file. Any further attempt would be a mini Turing Test, where a bot must be programmed to type in such a way as to fool us into believing it is David Kravitz. However, I was able to re-use much of this code to create a script for the human actors which included timing cues.

Footnotes