| 
									
										
										
										
											2003-04-11 15:35:28 +00:00
										 |  |  | \chapter{MacPython OSA Modules \label{scripting}} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-13 22:50:04 +00:00
										 |  |  | This chapter describes the current implementation of the Open Scripting | 
					
						
							|  |  |  | Architecure (OSA, also commonly referred to as AppleScript) for Python, allowing | 
					
						
							| 
									
										
										
										
											2003-04-11 15:35:28 +00:00
										 |  |  | you to control scriptable applications from your Python program, | 
					
						
							| 
									
										
										
										
											2005-02-13 22:50:04 +00:00
										 |  |  | and with a fairly pythonic interface. Development on this set of modules | 
					
						
							|  |  |  | has stopped, and a replacement is expected for Python 2.5. | 
					
						
							| 
									
										
										
										
											2003-04-11 15:35:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | For a description of the various components of AppleScript and OSA, and | 
					
						
							|  |  |  | to get an understanding of the architecture and terminology, you should | 
					
						
							|  |  |  | read Apple's documentation. The "Applescript Language Guide" explains | 
					
						
							|  |  |  | the conceptual model and the terminology, and documents the standard | 
					
						
							|  |  |  | suite. The "Open Scripting Architecture" document explains how to use | 
					
						
							|  |  |  | OSA from an application programmers point of view. In the Apple Help | 
					
						
							|  |  |  | Viewer these book sare located in the Developer Documentation, Core | 
					
						
							|  |  |  | Technologies section. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | As an example of scripting an application, the following piece of | 
					
						
							|  |  |  | AppleScript will get the name of the frontmost \program{Finder} window | 
					
						
							|  |  |  | and print it: | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							|  |  |  | tell application "Finder" | 
					
						
							|  |  |  |     get name of window 1 | 
					
						
							|  |  |  | end tell | 
					
						
							|  |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Python, the following code fragment will do the same: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							|  |  |  | import Finder | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | f = Finder.Finder() | 
					
						
							| 
									
										
										
										
											2003-06-13 14:59:26 +00:00
										 |  |  | print f.get(f.window(1).name) | 
					
						
							| 
									
										
										
										
											2003-04-11 15:35:28 +00:00
										 |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | As distributed the Python library includes packages that implement the | 
					
						
							|  |  |  | standard suites, plus packages that interface to a small number of | 
					
						
							|  |  |  | common applications. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To send AppleEvents to an application you must first create the Python | 
					
						
							|  |  |  | package interfacing to the terminology of the application (what | 
					
						
							|  |  |  | \program{Script Editor} calls the "Dictionary"). This can be done from | 
					
						
							|  |  |  | within the \program{PythonIDE} or by running the | 
					
						
							|  |  |  | \file{gensuitemodule.py} module as a standalone program from the command | 
					
						
							|  |  |  | line. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The generated output is a package with a number of modules, one for | 
					
						
							|  |  |  | every suite used in the program plus an \module{__init__} module to glue | 
					
						
							|  |  |  | it all together. The Python inheritance graph follows the AppleScript | 
					
						
							|  |  |  | inheritance graph, so if a programs dictionary specifies that it | 
					
						
							|  |  |  | includes support for the Standard Suite, but extends one or two verbs | 
					
						
							|  |  |  | with extra arguments then the output suite will contain a module | 
					
						
							|  |  |  | \module{Standard_Suite} that imports and re-exports everything from | 
					
						
							|  |  |  | \module{StdSuites.Standard_Suite} but overrides the methods that have | 
					
						
							|  |  |  | extra functionality. The output of \module{gensuitemodule} is pretty | 
					
						
							|  |  |  | readable, and contains the documentation that was in the original | 
					
						
							|  |  |  | AppleScript dictionary in Python docstrings, so reading it is a good | 
					
						
							|  |  |  | source of documentation. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The output package implements a main class with the same name as the | 
					
						
							|  |  |  | package which contains all the AppleScript verbs as methods, with the | 
					
						
							|  |  |  | direct object as the first argument and all optional parameters as | 
					
						
							|  |  |  | keyword arguments. AppleScript classes are also implemented as Python | 
					
						
							|  |  |  | classes, as are comparisons and all the other thingies. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-13 14:59:26 +00:00
										 |  |  | The main | 
					
						
							|  |  |  | Python class implementing the verbs also allows access to the properties | 
					
						
							|  |  |  | and elements declared in the AppleScript class "application". In the | 
					
						
							|  |  |  | current release that is as far as the object orientation goes, so | 
					
						
							|  |  |  | in the example above we need to use | 
					
						
							| 
									
										
										
										
											2003-12-14 15:02:54 +00:00
										 |  |  | \code{f.get(f.window(1).name)} instead of the more Pythonic | 
					
						
							| 
									
										
										
										
											2003-04-11 15:35:28 +00:00
										 |  |  | \code{f.window(1).name.get()}. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If an AppleScript identifier is not a Python identifier the name is | 
					
						
							|  |  |  | mangled according to a small number of rules: | 
					
						
							|  |  |  | \begin{itemize} | 
					
						
							|  |  |  |     \item spaces are replaced with underscores | 
					
						
							|  |  |  |     \item other non-alphanumeric characters are replaced with | 
					
						
							|  |  |  |     \code{_xx_} where \code{xx} is the hexadecimal character value | 
					
						
							|  |  |  |     \item any Python reserved word gets an underscore appended | 
					
						
							|  |  |  | \end{itemize} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Python also has support for creating scriptable applications | 
					
						
							|  |  |  | in Python, but | 
					
						
							|  |  |  | The following modules are relevant to MacPython AppleScript support: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \localmoduletable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In addition, support modules have been pre-generated for | 
					
						
							|  |  |  | \module{Finder}, \module{Terminal}, \module{Explorer}, | 
					
						
							|  |  |  | \module{Netscape}, \module{CodeWarrior}, \module{SystemEvents} and | 
					
						
							|  |  |  | \module{StdSuites}. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \input{libgensuitemodule} | 
					
						
							|  |  |  | \input{libaetools} | 
					
						
							|  |  |  | \input{libaepack} | 
					
						
							|  |  |  | \input{libaetypes} | 
					
						
							|  |  |  | \input{libminiae} |