« March 2008 | Main | July 2008 »

Main > Software

April 21, 2008

Python Rosetta Stone Automation

Many, many months ago I had a long, long layover in the airport in Madrid. On the flight over from the States I had grown increasingly frustrated with the interface to "The Rosetta Stone" language learning software. Now I must confess, there actually is little to get wrong in this interface as the majority of the interaction with the software is done via clicking one of four buttons. However, I come from the UNIX world where I prefer everything to be able to be driven from a set of keyboard shortcuts and so I committed my layover to automating The Rosetta Stone.

Tonight I find myself writing from yet another long, long layover and I find myself revisiting The Rosetta Stone to brush up on my Spanish. I remembered my little application I wrote in Spain and so I made a few tweaks and decided to share it, just in case anybody should find it useful.

If anything, it demonstrates two concepts:

Here is the entire application. It is less than 50 meaningful lines of code:

import os
import sys
import time
from msvcrt import getch

sys.path.append("../win32automation")

import win32automation

os.system("title KeySetta")
win32automation.spawnProcess(
    r"C:\Program Files\The Rosetta Stone\The Rosetta Stone\TheRosettaStone.exe")
while 1:
    print "Waiting for application to start..."
    result = win32automation.windowFocus("The Rosetta Stone")
    if result:
        print "Window found!"
        break
    time.sleep(1.0)
print "Waiting 5 seconds for login screen to appear..."
time.sleep(5.0)
win32automation.sendKeys('jordanh{ENTER}')

print """
   Keyboard to Mouse Macros Enabled:

     - Answer selection:
       [7] [9]
       [1] [3]
       
    Please focus this window to enable them...
"""

coord_map = {"7": (180, 300),
             "9": (480, 300),
             "1": (180, 475),
             "3": (480, 475)}

while 1:
    win32automation.windowFocus("KeySetta")
    ch = getch()
    print "Last key pressed: %s\r" % (ch),
    if ch in ('1','3','7','9'):
        win32automation.windowFocus("The Rosetta Stone")
        x, y = coord_map[ch]
        win32automation.mouseMoveToRelative("The Rosetta Stone", x, y)
        win32automation.mouseClick(button="left")
    elif ch.lower() == 'q':
        print "Quitting!"
        break
    else:
        print "WARNING: Unknown key-macro event '%c'." % (ch)

sys.exit()

Granted the silly "win32automation" module I wrote is a little stupid. It is based on the excellent example provided over at http://del.icio.us/amoebapr/python. Notice for example none of the functions take an opaque handle to an object. Instead, all of the functions inside of the module require some sort of hint (such as a window title) in order to re-find the desired object before executing an operation on it.

Hopefully however sharing this code will spark somebody to develop a better, free Windows automation module for Python.

Download keysetta.zip (md5sum: a4336d883fcb10b11b8b660451e522a3)

Posted by jordanh at 11:30 PM | Comments (2) | TrackBack |

Main > Photoblog

April 1, 2008

Final Shot

00259.jpg
View in Photoblog

This photo was taken by my father and sent to me.

My brother needed some logistical help shooting the final scenes of his movie and so my dad drove up from Los Angeles to the Bay Area in order to help him out. This was supposed to be final location for the movie he has been working on for going on two years.

The salty air ended up doing a number on his old VHS camera and he could not wrap production. The next day he needed to be on an airplane to move to New York City. Now he'll have to come back so he can finish his film.

 

Posted by jordanh at 12:35 PM | Comments (1) | TrackBack |