Using AppleScript To Send Key Presses

I’ve taken a break from my regular JavaScript, PHP and Perl scripting, and taken a look at AppleScript instead.

I’ve been playing a Flash game in a browser, and in this game you have to run by continuously and rapidly pressing the ‘a’ key to boost your speed. Readers of a certain age will know this is very similar to Daley Thompson’s Decathalon. The first few goes went OK, but weren’t spectacular as my arm started to get tired. There must be a way of automating this… right?

Yes there is, AppleScript on my Mac to the rescue. I can create a script to send key press events to Safari, which very kindly passes it over to the Flash game if that is in focus.

Firstly you need to tell AppleScript to target Safari.

tell application "Safari"
activate
end tell

Now we just need to send events claiming that the ‘a’ key has been pressed, after the activate command.

tell application "System Events"
repeat 50 times
keystroke "a"
delay 0.05
end repeat
end tell

That code will press the “a” key every 0.05 seconds 50 times. That’s 20 “a”‘s a second, for 2 and a half seconds.

Save the code under a suitable filename and call it using the osascript command.

Draw Something Solver – The Idea

I’ve been ill recently, and during my stay in hospital I discovered Draw Something. It’s basically a digital version of Pictionary played over the Internet on your phone.

I have noticed a few solvers have been written, and while I am recovering from my illness I have decided to try to write something to do the same function as I feel up to it, and to keep my skills up to date before I return to work.

I have an iPhone 4S, so anything I write about will be related to that device.

It seems the main tasks would be…

  • Obtain a list of words Draw Something uses
  • Obtain screenshots of the app
  • Extract words from the screenshots
  • Extract the number of letters in the solution from the screenshot
  • Find the possible words that match

Obtaining a list of words may be tricky as Draw Something uses quite a few proper nouns such as names. To start with the words on my Macbook in the /usr/share/dict/words file should be a good start until I find a better list.

The easiest way to get some screenshots would be to take them directly on my iPhone (press and hold the Home button then pressing the Sleep/Wake button, then using Preview on my Mac to import to my Macbook).

Extracting the number of words and number of letters in the solution from the screenshots will mean inspecting the image and doing some basic OCR.

Finding the possible words would be a case of sorting all the words into alphabetical lists of letters and comparing them.

To be continued…

Disabling The Zend Framework ViewRenderer

There are times when using the Zend Framework that you don’t want a view to render.

For example, you may be generating a feed programaticaly, or you may be using a templating engine such as Twig for some or all paths.

By default, the front controller enables the ViewRenderer action helper. It is the job of the ViewRenderer to inject the view object into the controller and to automatically render the view. The idea is that you don’t need to worry about manually instantiating view objects in your controller, the helper does it for you.

It’s actually very simple to disable this behaviour, and there are several ways to do it.

Firstly, if you want to disable this functionality across your application, you could use the following in the application.ini file…

resources.frontController.noViewRenderer = true

This can also be set programatically…

Zend_Controller_Front::getInstance()->setParam('noViewRenderer', true);

A better approach would be to simply remove the ViewRenderer helper.

$this->_helper->removeHelper('viewRenderer');

If you don’t want the ViewRenderer disabled across your entire application, you can set it locally in a controller…

$this->_helper->viewRenderer->setNoRender(true);

Using Node.js To Send A Heartbeat To A Python Server

I’ve been looking back at some old code and I found an old piece on using Perl to send a heartbeat to a Python server.

Recently I’ve been using the excellent node.js to do some cool JavaScript on the server side instead of in a client on a web broswer. I thought it would be fun to covert this simple script over to JavaScript.

This example is based on recipe 13.11 in the Python Cookbook.

The script needs to send a UDP datagram to a server listening on port 43278. In this example the server will be listening on localhost, 127.0.0.1.

As with the Perl script, we’ll set a few “constants” to let us change things easily if we want to. As JavaScript doesn’t have constants in this example we’ll just use variables. Firstly we nee to require “dgram” so we can use UDP datagrams. We’ll set the server ip address, the port to use, the time in seconds to send the heartbeat, a debug flag if we want to see a message on the console everytime we send a message, and the message itself “PyHB”.

var dgram = require('dgram');
var message = new Buffer("PyHB");
var server_ip = '127.0.0.1';
var server_port = 43278;
var beat_period = 5;
var debug = 1;

We’ll need to send out our heartbeat every beat_period seconds. To do this we can use JavaScript’s setInterval function to execute code every X milliseconds. As we’ve defined our beat_period in seconds, we’ll need to mulitply this value by 1000 to get the time in milliseconds.

setInterval(function() {
// datagram code goes here.
}, beat_period * 1000);

The code to send the datagram is really simple, 3 lines infact. We create a client socket, send the message then close the client socket.

var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, server_port, server_ip);
client.close();

Putting this together, along with a bit of debugging information, we get the following code.

var dgram = require('dgram');
var message = new Buffer("PyHB");
var server_ip = '127.0.0.1';
var server_port = 43278;
var beat_period = 5;
var debug = 1;
console.log("Sending heartbeat to IP " + server_ip + " , port " + server_port);
console.log("press Ctrl-C to stop");
setInterval(function() {
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, server_port, server_ip);
client.close();
if (debug)
console.log("Time: " + new Date());
}, beat_period * 1000);

I hope that was a useful introduction to sending messages using UDP in Node.js.

Faking A Fixed Background In An iOS Web App

If the lack of a fixed background image position has been bugging you when your building your HTML / CSS based iOS apps, then I thought I’d share a work around I’ve been using.

If you are creating a native app from this in XCode then you would almost certainly be embedding the web page in a UIWebView. This is where the magic works.

Create a UIImageView with your background image on, then place your UIWebView directly over this image.

In your Objective-C you need to set the UIWebView‘s background colour to clearColor and make the UIWebView opaque. If your UIWebView is called webView the following two lines of Objective-C will do this.

[webView setBackgroundColor:[UIColor clearColor]];
[webView setOpaque:NO];

Your background image should now show through the webpage and be visible as the background.

MooTools 1.2 Beginners Guide Book Review

MooTools 1.2 Beginners Guide from Packt Publishing
After a year of using jQuery, I have an upcoming project that requires me to go back to MooTools. A lot of my MooTools knowledge was rather rusty, but a couple of weeks ago the nice people at Packt published a new book called MooTools 1.2 Beginner’s Guide and I managed to get my hands on a copy.

MooTools 1.2 Beginner’s Guide by Jacob Gube and Garrick Cheung promises readers they will “learn how to create dynamic, interactive, and responsive cross-browser web application using one of the most popular JavaScript frameworks”, and it certainly does that.

The book is very clearly written, with plenty of step by step examples. You’ll need a basic understanding of HTML, CSS and JavaScript but not much more.

The book starts out explaining what MooTools is, how to go about downloading it and then using it on a web page. It clearly explains the difference in using normal JavaScript code and MooTools code, before moving on to DOM selectors and other key utilities in the MooTools library. In addition to this, there are chapters on events, AJAX, animations and plugins.

When the book arrived I expected a very simple book, and I have to admit to having been pleasantly surprised. As well as being an excellent tutorial for beginners, there is actually quite a lot for the more experienced developer and I found myself picking up quite a few new tricks, and clarifying my knowledge in a few places. One area that MooTools has always been weak in comparison to rival frameworks like jQuery has been the quality of the documentation and tutorials for beginners, this book really addresses that area and should be a welcome addition to the library of any MooTools developer.

MooTools 1.2 Beginners Guide Official Website.

Python, XML and iTunes

As I’ve taken the week off work, I thought as well as spending time with my family, I’d brush up my Python skills as they’ve been a bit neglected of late.

I’ve never tried XML parsing with Python so thought I’d cover that. Apple’s iTunes has the ability to export information about your music in XML and I’d been meaning to take a look at that for a while. Why not combine the two, so here’s my take on parsing iTunes export information with Python.

I thought i’d work on a small subset of my library, the ones I’ve actually paid to download from iTunes compared to the ones converted from CD.

Rob's purchased iTunes tracks

The exported XML data is a bit peculiar. I would have assumed it to be values enclosed by sensible tag names e.g <artist>Human League</artist>. However, it’s actually a bunch of neighbouring tags and values like this <key>Artist</key><string>Sheb Wooley</string>

Here’s a snippet from the actual data export I ran…

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Major Version</key><integer>1</integer>
<key>Minor Version</key><integer>1</integer>
<key>Application Version</key><string>6.0.5</string>
<key>Features</key><integer>1</integer>
<key>Music Folder</key><string>file://localhost/D:/Documents%20and%20Settings/Windows%20User/My%20Documents/My%20Music/iTunes/iTunes%20Music/</string>
<key>Library Persistent ID</key><string>C5DD29C89369B278</string>
<key>Tracks</key>
<dict>
<key>312</key>
<dict>
<key>Track ID</key><integer>312</integer>
<key>Name</key><string>The Purple People Eater</string>
<key>Artist</key><string>Sheb Wooley</string>
<key>Album</key><string>20th Century Rocks: 50's Rock 'n Roll - At the Hop</string>
<key>Genre</key><string>Pop</string>
<key>Kind</key><string>Protected AAC audio file</string>
<key>Size</key><integer>2260837</integer>
<key>Total Time</key><integer>135533</integer>
<key>Disc Number</key><integer>1</integer>
<key>Disc Count</key><integer>1</integer>
<key>Track Number</key><integer>5</integer>
<key>Year</key><integer>2001</integer>
<key>Date Modified</key><date>2006-09-28T09:54:23Z</date>
<key>Date Added</key><date>2006-09-28T09:54:10Z</date>
<key>Bit Rate</key><integer>128</integer>
<key>Sample Rate</key><integer>44100</integer>
<key>Play Count</key><integer>11</integer>
<key>Play Date</key><integer>-1042489964</integer>
<key>Play Date UTC</key><date>2007-01-24T08:55:32Z</date>
<key>Normalization</key><integer>7764</integer>
<key>Compilation</key><true/>
<key>Artwork Count</key><integer>1</integer>
<key>Persistent ID</key><string>302B45E87F01479F</string>
<key>Track Type</key><string>File</string>
<key>Protected</key><true/>
<key>Location</key><string>file://localhost/D:/Documents%20and%20Settings/Windows%20User/My%20Documents/My%20Music/iTunes/iTunes%20Music/Compilations/20th%20Century%20Rocks_%2050's%20Rock%20'n%20Roll%20-/05%20The%20Purple%20People%20Eater.m4p</string>
<key>File Folder Count</key><integer>4</integer>
<key>Library Folder Count</key><integer>1</integer>
</dict>
<key>313</key>
<dict>
<key>Track ID</key><integer>313</integer>
<key>Name</key><string>Daisy Daisy</string>
<key>Artist</key><string>Johnny O'Tolle &#38; His Naughty Band</string>
<key>Album</key><string>Gay 90's</string>
<key>Genre</key><string>Vocal</string>
<key>Kind</key><string>Protected AAC audio file</string>
<key>Size</key><integer>2346412</integer>
<key>Total Time</key><integer>125084</integer>
<key>Disc Number</key><integer>1</integer>
<key>Disc Count</key><integer>1</integer>
<key>Track Number</key><integer>2</integer>
<key>Track Count</key><integer>10</integer>
<key>Year</key><integer>2006</integer>
<key>Date Modified</key><date>2006-09-28T09:59:52Z</date>
<key>Date Added</key><date>2006-09-28T09:59:38Z</date>
<key>Bit Rate</key><integer>128</integer>
<key>Sample Rate</key><integer>44100</integer>
<key>Play Count</key><integer>6</integer>
<key>Play Date</key><integer>-1038647848</integer>
<key>Play Date UTC</key><date>2007-03-09T20:10:48Z</date>
<key>Artwork Count</key><integer>1</integer>
<key>Persistent ID</key><string>302B45E87F01490F</string>
<key>Track Type</key><string>File</string>
<key>Protected</key><true/>
<key>Location</key><string>file://localhost/D:/Documents%20and%20Settings/Windows%20User/My%20Documents/My%20Music/iTunes/iTunes%20Music/Johnny%20O'Tolle%20&#38;%20His%20Naughty%20Band/Gay%2090's/02%20Daisy%20Daisy.m4p</string>
<key>File Folder Count</key><integer>4</integer>
<key>Library Folder Count</key><integer>1</integer>
</dict>

This makes parsing the data a bit trickier than I had hoped for. I was hoping to use a nice simple XPath expression, but data like this looks like it’s more a job for a SAX based approach.

I took a look in O’Reilly’s excellent Programming Python, and found a nice SAX parser example to modify.

As it’s just a quick test, I’m making a few assumptions on the XML data that a production system would have to handle. In this case, I’m assume a tag order of Track ID, Name and Artist. Using this order, each time we see one of those tags come past, we can make up a Track object and store the relevant data. In this case, when we see Track ID we need a new Track object to store the data in. When we see Name, we store the track name in the object and when we see Artist we save the artist, push the Track object to our list of Tracks and clear the current Track object.

That’s a bit long winded, so here’s the code.

import xml.sax.handler
class ITunesHandler(xml.sax.handler.ContentHandler):
def __init__(self):
self.parsing_tag = False
self.tag = ''
self.value = ''
self.tracks = []
self.track = None
def startElement(self, name, attributes):
if name == 'key':
self.parsing_tag = True
def characters(self, data):
if self.parsing_tag:
self.tag = data
self.value = ''
else:
# could be multiple lines, so append data.
self.value = self.value + data
def endElement(self,name):
if name == 'key':
self.parsing_tag = False
else:
if self.tag == 'Track ID':
# start of a new track, so a new object
# is needed.
self.track = Track()
elif self.tag == 'Name' and self.track:
self.track.track = self.value
elif self.tag == 'Artist' and self.track:
self.track.artist = self.value
# assume this is all the data we need
# so append the track object to our list
# and reset our track object to None.
self.tracks.append(self.track)
self.track = None
class Track:
def __init__(self):
self.track = ''
self.artist = ''
def __str__(self):
return "Track = %snArtist = %s" % (self.track,self.artist)

In the real world, the Track class would offer a lot more functionality, in this case, it’s just for holding data and providing a pretty printer.

Now we need to parse the XML and display the results, here’s the code…

parser = xml.sax.make_parser()
handler = ITunesHandler()
parser.setContentHandler(handler)
parser.parse('D:\Documents and Settings\Windows User\Desktop\Purchased.xml')
for track in handler.tracks:
print track

Let’s run that code and see what we get…

Track = The Purple People Eater
Artist = Sheb Wooley
Track = Daisy Daisy
Artist = Johnny O'Tolle & His Naughty Band
Track = Don't Dilly Dally
Artist = Kidzone
Track = Jump In My Car
Artist = David Hasselhoff
Track = Puff, the Magic Dragon
Artist = Peter, Paul And Mary
Track = You Give Love a Bad Name
Artist = Bon Jovi
Track = Heart of Glass
Artist = Blondie
Track = Grace Kelly
Artist = Mika
Track = Standing In the Way of Control
Artist = Gossip
Track = Physical
Artist = Olivia Newton-John
Track = Don't You Want Me
Artist = The Human League
Track = Have a Drink On Me
Artist = Lonnie Donegan
Track = My Old Man's a Dustman
Artist = Lonnie Donegan

That’s great! OK, I’m not going to win any awards for my taste in music, but at least I can now think about building music services that use this data.

Using Twitter From Perl

The world and his dog is currently looking at Twitter and eyeing up the possibilities it offers.

I thought i’d jump on the bandwagon, and have a look at the Twitter API.

I wanted to post to a timeline, so the solution is to use one of the update methods. I chose to the XML one, though there is a JSON one also available.

To post to the timeline, Twitter expects an HTTP POST request with a status parameter containing the message you want to post. It associates this to your account by using HTTP’s basic authorization functionality.

It’s simple to throw together a spot of Perl code to post messages to Twitter knowing this. Have a look at this example…


my $message = "A test post from Perl";
my $req = HTTP::Request->new(POST =>'http://twitter.com/statuses/update.xml');
$req->content_type('application/x-www-form-urlencoded');
$req->content('status=' . $message);
$req->authorization_basic($username, $password);
my $resp = $ua->request($req);
my $content = $resp->content;
print $content;

You need to set $username and $password to your username and password, and $message to whatever message you want to appear on your timeline (in this case, “A test post from Perl”).

Using A Bluetooth GPS From Python

Following on from my earlier posting on programming bluetooth from Python, I tried talking to a bluetooth GPS unit from Python.

I have a cheap MSI Starfinder SF100 bluetooth GPS that transmits NMEA format positioning information over a bluetooth socket. So, the first thing we have to do is to is to open a bluetooth socket.

import bluetooth
# bluetooth address of the GPS device.
addr = "00:08:1B:C2:AA:6D"
# port to use.
port = 1
# create a socket and connect to it.
socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
socket.connect((addr, port))

Fingers crossed we should now be connected to the GPS unit. In the real world we’d also be checking for exceptions to make sure we really have been able to connect, but this is just a simplified example.

Now we need to receive data from the GPS.

data = ""
while True:
data = socket.recv(1024)

Here we’re initialising a holding variable called data where the received data from the bluetooth socket goes, then we create an infinate loop and continually receive data from the bluetooth socket we creataed earlier.

We should now have some data coming in, so to test it we can just print it out.

print data

Here’s what we get back.

$GPRMC,225406.537,A,5046.3972,N,00017.
3365,E,0.00,,300107,,,A*7E
$GPGGA,225407.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,
M,,,,0000*33
$GPGSA,A,3,27,10,29,28,08,,,,,,,,3.9,1.7,3.5*35
$GPRMC,225407.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*7F
$GPGGA,225408.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,M,,,,0000*3C
$GPGSA,A,3,27,1
0,2
9,28,08,,,,,,,,3.9,1.7,3.5*35
$GPGSV,2,1,08,10,70,218,31,08,64,067
,35,29,49,287,30,27,37,058,40*70
$GPGSV,2,2,08,26,35,283,,28,34,133,45,24,27,254,22,21,12,324,*72
$GPRMC,225408.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*70
$GPGGA,225409.537,5046.3972,N,00017.3365,E,1,06,1.4,55.5,M,,,
,0000*3D

Oh dear, although we are receiving data over the bluetooth socket, it’s in random packet sizes. The NMEA data we want is sent in lines terminated with a carriage return and a line feed. So how can we get the data in this format?

Well we need to use Python’s string manipulation methods. We can use the splitlines method to split the data into a list of lines. As we can’t be sure we have a complete line at the end of the list we need to check there is a carriage return and linefeed there. By default splitlines helpfully removes these, so we need to tell it to keep them in place, after all we can use the strip method later to remove them manually. So all we need to do now is to check the last line in the list has the carriage return and linefeed, if it doesn’t we need to make sure the next data received from the bluetooth socket is appended to the end before we repeat the process again. Imagine we create a holding variable called olddata at the same time as data and this is to hold a copy of the last line. Here’s the code…

# make sure we actually have some data.
if len(data) > 0:
# append the old data to the front of data.
data = olddata + data
# split the data into a list of lines, but make
# sure we preserve the end of line information.
lines = data.splitlines(1)
# iterate over each line
for line in lines:
# if the line has a carriage return and a
# linefeed, we know we have a complete line so
# we can remove those characters and print it.
if line.find("rn") != -1 :
line = line.strip()
print line
# empty the olddata variable now we have
# used the data.
olddata = ""
# else we need to keep the line to add to data
else :
olddata = line

We now have some useful data coming in…

$GPRMC,225406.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*7E
$GPGGA,225407.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,M,,,,0000*33
$GPGSA,A,3,27,10,29,28,08,,,,,,,,3.9,1.7,3.5*35
$GPRMC,225407.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*7F
$GPGGA,225408.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,M,,,,0000*3C
$GPGSA,A,3,27,10,29,28,08,,,,,,,,3.9,1.7,3.5*35
$GPGSV,2,1,08,10,70,218,31,08,64,067,35,29,49,287,30,27,37,058,40*70
$GPGSV,2,2,08,26,35,283,,28,34,133,45,24,27,254,22,21,12,324,*72
$GPRMC,225408.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*70
$GPGGA,225409.537,5046.3972,N,00017.3365,E,1,06,1.4,55.5,M,,,,0000*3D

As you can see the NMEA strings are simply comma seperated blocks of data.

The most useful string is the one with the actual position in. This string is the one starting with $GPRMC. If we look out for this line and split it’s data, we can get our latitude and longitude and use it as we please.

gpsstring = line.split(',')
if gpsstring[0] == '$GPRMC' :
print "Lat: " + gpsstring[3] + gpsstring[4]
print "Long: " + gpsstring[5] + gpsstring[5]

This gives us…

Lat:  5046.3972N
Long: 000017.3365

Which translates to 50 deg 46.3972′ N and 0 deg 17.3365 E.

There you have it, it’s time to start geocoding you data.

iTunes Auto Updating Now Playing in VB2005

Previously I’ve covered how to link into the iTunes COM library from VB 2005 to show now playing information. This article assumes you have already read that, or have it to hand.

Taking this application further, wouldn’t it be useful for our application to automatically update itself when a track changes takes place on iTunes?

Well I hope you are saying yes, as it’s what I’m going to cover now.

iTunes can inform our application of changes of track if we choose to listen for it’s OnPlayerPlayEvent event.

If you are not sure what an event is, it’s basically a way for one program to tell another that something has happened in that program and the other program may wish to react to it. In this case, a different track has started playing in iTunes.

So how can we get our application to listen out for this? Well firstly we need to say that our programme is interested in these events. We do this by using VB 2005’s WithEvents keyword when we create our interface into iTunes.

So previously we did this using the following code.

Dim app As New iTunesApp()

Now we have to add in the WithEvents keyword as follows.

Private WithEvents app As New iTunesApp

Now our program can listen out for events from iTunes. You may have noticed I’ve changed Dim to Private. This is because for this example I’m going to use a Windows Application and not a Console application as before.

Next we have to create our event handler so we can react to the events iTunes is sending us.

The easiest way to do this is use the method generator at the top of the code view in Visual Basic 2005 Express Edition. My iTunes object is called app so we select this, then OnPlayerPlayEvent to create our event handler stub.

Creating an iTunes event in VB2005

This passes in the variable iTrack as an Object. We know this is really an IITTrack object, so we need to cast it as such.

Dim track As IITTrack
track = CType(iTrack, IITTrack)

This creates a new varible called track and casts the existing iTrack variable as an IITTrack using CType.
Doing this, we have easy access to the track data passed to us by iTunes in the event.
We need to do something with this information seeing as we’ve gone to all the trouble of asking iTunes for it. The easiest thing to do is to just display a small window with the name of the current track.

MsgBox(track.name)

Obviously this is a simplified version of a real program, but it should give you an idea of how to get events from a remote program into your VB2005 application.