Moved all the scripting stuff to a separate section, added all the
missing bits (well, all the bits I could think of) and updated the rest.
This commit is contained in:
parent
126f2b76b9
commit
bae5c965e8
|
@ -345,10 +345,13 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
|
|||
MACFILES= $(HOWTOSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
|
||||
mac/mac.tex \
|
||||
mac/using.tex \
|
||||
mac/scripting.tex \
|
||||
mac/toolbox.tex \
|
||||
mac/undoc.tex \
|
||||
mac/libcolorpicker.tex \
|
||||
mac/libmac.tex \
|
||||
mac/libgensuitemodule.tex \
|
||||
mac/libaetools.tex \
|
||||
mac/libaepack.tex \
|
||||
mac/libaetypes.tex \
|
||||
mac/libmacfs.tex \
|
||||
|
|
|
@ -45,7 +45,7 @@ the Python string representation of a value (the repr() function)
|
|||
encoded as a text descriptor.
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{unpack}{x}
|
||||
\begin{funcdesc}{unpack}{x\optional{, formodulename}}
|
||||
\var{x} must be an object of type \class{AEDesc}. This function
|
||||
returns a Python object representation of the data in the Apple
|
||||
Event descriptor \var{x}. Simple AppleEvent data types (integer,
|
||||
|
@ -53,16 +53,26 @@ encoded as a text descriptor.
|
|||
Apple Event lists are returned as Python lists, and the list
|
||||
elements are recursively unpacked. Object references
|
||||
(ex. \code{line 3 of document 1}) are returned as instances of
|
||||
\class{aetypes.ObjectSpecifier}. AppleEvent descriptors with
|
||||
\class{aetypes.ObjectSpecifier}, unless \code{formodulename}
|
||||
is specified. AppleEvent descriptors with
|
||||
descriptor type typeFSS are returned as \class{FSSpec}
|
||||
objects. AppleEvent record descriptors are returned as Python
|
||||
dictionaries, with keys of type \class{?} and elements recursively
|
||||
dictionaries, with 4-character string keys and elements recursively
|
||||
unpacked.
|
||||
|
||||
The optional \code{formodulename} argument is used by the stub packages
|
||||
generated by \module{gensuitemodule}, and ensures that the OSA classes
|
||||
for object specifiers are looked up in the correct module. This ensures
|
||||
that if, say, the Finder returns an object specifier for a window
|
||||
you get an instance of \code{Finder.Window} and not a generic
|
||||
\code{aetypes.Window}. The former knows about all the properties
|
||||
and elements a window has in the Finder, while the latter knows
|
||||
no such things.
|
||||
\end{funcdesc}
|
||||
|
||||
|
||||
\begin{seealso}
|
||||
\seemodule{AE}{Built-in access to Apple Event Manager routines.}
|
||||
\seemodule{Carbon.AE}{Built-in access to Apple Event Manager routines.}
|
||||
\seemodule{aetypes}{Python definitions of codes for Apple Event
|
||||
descriptor types.}
|
||||
\seetitle[http://developer.apple.com/techpubs/mac/IAC/IAC-2.html]{
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
\section{\module{aetools} ---
|
||||
OSA client support}
|
||||
|
||||
\declaremodule{standard}{aetools}
|
||||
\platform{Mac}
|
||||
%\moduleauthor{Jack Jansen?}{email}
|
||||
\modulesynopsis{Basic support for sending Apple Events}
|
||||
\sectionauthor{Jack Jansen}{Jack.Jansen@cwi.nl}
|
||||
|
||||
|
||||
The \module{aetools} module contains the basic functionality
|
||||
on which Python AppleScript client support is built. It also
|
||||
imports and re-exports the core functionality of the
|
||||
\module{aetypes} and \module{aepack} modules. The stub packages
|
||||
generated by \module{gensuitemodule} import the relevant
|
||||
portions of \module{aetools}, so usually you do not need to
|
||||
import it yourself. The exception to this is when you
|
||||
cannot use a generated suite package and need lower-level
|
||||
access to scripting.
|
||||
|
||||
The \module{aetools} module itself uses the AppleEvent support
|
||||
provided by the \module{Carbon.AE} module. This has one drawback:
|
||||
you need access to the window manager, see section \ref{osx-gui-scripts}
|
||||
for details. This restriction may be lifted in future releases.
|
||||
|
||||
|
||||
The \module{aetools} module defines the following functions:
|
||||
|
||||
\begin{funcdesc}{packevent}{ae, parameters, attributes}
|
||||
Stores parameters and attributes in a pre-created \code{Carbon.AE.AEDesc}
|
||||
object. \code{parameters} and \code{attributes} are
|
||||
dictionaries mapping 4-character OSA parameter keys to Python objects. The
|
||||
objects are packed using \code{aepack.pack()}.
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{unpackevent}{ae\optional{, formodulename}}
|
||||
Recursively unpacks a \code{Carbon.AE.AEDesc} event to Python objects.
|
||||
The function returns the parameter dictionary and the attribute dictionary.
|
||||
The \code{formodulename} argument is used by generated stub packages to
|
||||
control where AppleScript classes are looked up.
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{keysubst}{arguments, keydict}
|
||||
Converts a Python keyword argument dictionary \code{arguments} to
|
||||
the format required by \code{packevent} by replacing the keys,
|
||||
which are Python identifiers, by the four-character OSA keys according
|
||||
to the mapping specified in \code{keydict}. Used by the generated suite
|
||||
packages.
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{enumsubst}{arguments, key, edict}
|
||||
If the \code{arguments} dictionary contains an entry for \code{key}
|
||||
convert the value for that entry according to dictionary \code{edict}.
|
||||
This converts human-readable Python enumeration names to the OSA 4-character
|
||||
codes.
|
||||
Used by the generated suite
|
||||
packages.
|
||||
\end{funcdesc}
|
||||
|
||||
The \module{aetools} module defines the following class:
|
||||
|
||||
\begin{classdesc}{TalkTo}{\optional{signature=None, start=0, timeout=0}}
|
||||
|
||||
Base class for the proxy used to talk to an application. \code{signature}
|
||||
overrides the class attribute \code{_signature} (which is usually set by subclasses)
|
||||
and is the 4-char creator code defining the application to talk to.
|
||||
\code{start} can be set to true to enable running the application on
|
||||
class instantiation. \code{timeout} can be specified to change the
|
||||
default timeout used while waiting for an AppleEvent reply.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{methoddesc}{_start}{}
|
||||
Test whether the application is running, and attempt to start it if not.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}{send}{code, subcode\optional{, parameters, attributes}}
|
||||
Create the AppleEvent \code{Carbon.AE.AEDesc} for the verb with
|
||||
the OSA designation \code{code, subcode} (which are the usual 4-character
|
||||
strings), pack the \code{parameters} and \code{attributes} into it, send it
|
||||
to the target application, wait for the reply, unpack the reply with
|
||||
\code{unpackevent} and return the reply appleevent, the unpacked return values
|
||||
as a dictionary and the return attributes.
|
||||
\end{methoddesc}
|
|
@ -8,32 +8,128 @@
|
|||
\sectionauthor{Vincent Marchetti}{vincem@en.com}
|
||||
|
||||
|
||||
The \module{aetypes} defines classes used to represent Apple Event
|
||||
object specifiers. An object specifier is essentially an address of an
|
||||
object implemented in a Apple Event server. An Apple Event specifier
|
||||
is used as the direct object for an Apple Event or as the argument of
|
||||
an optional parameter. In AppleScript an object specifier is
|
||||
represented by a phrase such as:
|
||||
\code{character 23 of document "Semprini"}. The classes defined in
|
||||
this module allow this specifier to be represented by a Python object
|
||||
which is initialized as follows:
|
||||
\code{res = Document(1).Character(23)}
|
||||
The \module{aetypes} defines classes used to represent Apple Event data
|
||||
descriptors and Apple Event object specifiers.
|
||||
|
||||
Apple Event data is is contained in descriptors, and these descriptors
|
||||
are typed. For many descriptors the Python representation is simply the
|
||||
corresponding Python type: \code{typeText} in OSA is a Python string,
|
||||
\code{typeFloat} is a float, etc. For OSA types that have no direct
|
||||
Python counterpart this module declares classes. Packing and unpacking
|
||||
instances of these classes is handled automatically by \module{aepack}.
|
||||
|
||||
An object specifier is essentially an address of an object implemented
|
||||
in a Apple Event server. An Apple Event specifier is used as the direct
|
||||
object for an Apple Event or as the argument of an optional parameter.
|
||||
The \module{aetypes} module contains the base classes for OSA classes
|
||||
and properties, which are used by the packages generated by
|
||||
\module{gensuitemodule} to populate the classes and properties in a
|
||||
given suite.
|
||||
|
||||
For reasons of backward compatibility, and for cases where you need to
|
||||
script an application for which you have not generated the stub package
|
||||
this module also contains object specifiers for a number of common OSA
|
||||
classes such as \code{Document}, \code{Window}, \code{Character}, etc.
|
||||
|
||||
|
||||
The \module{AEObjects} module defines the following class:
|
||||
|
||||
\begin{classdesc}{ObjectSpecifier}{want, form, seld, from}
|
||||
This is the base class for representing object specifiers and is
|
||||
generally not constructed directly by the user. Its important
|
||||
functionality is to define an \function{__aepack__()} function,
|
||||
which returns the Apple Event descriptor containing the object
|
||||
specifier. Its data members, set directly from the constructor
|
||||
arguments, are:
|
||||
The \module{AEObjects} module defines the following classes to represent
|
||||
Apple Event descriptor data:
|
||||
|
||||
\begin{classdesc}{Unknown}{type, data}
|
||||
The representation of OSA descriptor data for which the \module{aepack}
|
||||
and \module{aetypes} modules have no support, i.e. anything that is not
|
||||
represented by the other classes here and that is not equivalent to a
|
||||
simple Python value.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Enum}{enum}
|
||||
An enumeration value with the given 4-character string value.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{InsertionLoc}{of, pos}
|
||||
Position \code{pos} in object \code{of}.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Boolean}{bool}
|
||||
A boolean.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{StyledText}{style, text}
|
||||
Text with style information (font, face, etc) included.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{AEText}{script, style, text}
|
||||
Text with script system and style information included.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{IntlText}{script, language, text}
|
||||
Text with script system and language information included.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{IntlWritingCode}{script, language}
|
||||
Script system and language information.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{QDPoint}{v, h}
|
||||
A quickdraw point.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{QDRectangle}{v0, h0, v1, h1}
|
||||
A quickdraw rectangle.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{RGBColor}{r, g, b}
|
||||
A color.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Type}{type}
|
||||
An OSA type value with the given 4-character name.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Keyword}{name}
|
||||
An OSA keyword with the given 4-character name.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Range}{start, stop}
|
||||
A range.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Ordinal}{abso}
|
||||
Non-numeric absolute positions, such as \code{"firs"}, first, or \code{"midd"},
|
||||
middle.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Logical}{logc, term}
|
||||
The logical expression of applying operator \code{logc} to
|
||||
\code{term}.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{Comparison}{obj1, relo, obj2}
|
||||
The comparison \code{relo} of \code{obj1} to \code{obj2}.
|
||||
\end{classdesc}
|
||||
|
||||
The following classes are used as base classes by the generated stub
|
||||
packages to represent AppleScript classes and properties in Python:
|
||||
|
||||
\begin{classdesc}{ComponentItem}{which\optional{, fr}}
|
||||
Abstract baseclass for an OSA class. The subclass should set the class
|
||||
attribute \code{want} to the 4-character OSA class code. Instances of
|
||||
subclasses of this class are equivalent to AppleScript Object
|
||||
Specifiers. Upon instantiation you should pass a selector in
|
||||
\code{which}, and optionally a parent object in \code{fr}.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{NProperty}{fr}
|
||||
Abstract basclass for an OSA property. The subclass should set the class
|
||||
attributes \code{want} and \code{which} to designate which property we
|
||||
are talking about. Instances of subclasses of this class are Object
|
||||
Specifiers.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{classdesc}{ObjectSpecifier}{want, form, seld\optional{, fr}}
|
||||
Base class of \code{ComponentItem} and \code{NProperty}, a general
|
||||
OSA Object Specifier. See the Apple Open Scripting Architecture
|
||||
documentation for the parameters. Note that this class is not abstract.
|
||||
\end{classdesc}
|
||||
|
||||
\begin{memberdesc}{want}
|
||||
A four character string representing the class code of the
|
||||
object. These class codes are specified in Apple Event Suites; for
|
||||
example the standard code for a character object is the 4 bytes
|
||||
\samp{char}.
|
||||
\end{memberdesc}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
\section{\module{gensuitemodule} ---
|
||||
Generate OSA stub packages}
|
||||
|
||||
\declaremodule{standard}{gensuitemodule}
|
||||
\platform{Mac}
|
||||
%\moduleauthor{Jack Jansen?}{email}
|
||||
\modulesynopsis{Create a stub package from an OSA dictionary}
|
||||
\sectionauthor{Jack Jansen}{Jack.Jansen@cwi.nl}
|
||||
|
||||
The \module{gensuitemodule} module creates a Python package implementing
|
||||
stub code for the AppleScript suites that are implemented by a specific
|
||||
application, according to its AppleScript dictionary.
|
||||
|
||||
It is usually invoked by the user through the \program{PythonIDE}, but
|
||||
it can also be run as a script from the command line (pass \code{--help}
|
||||
for help on the options) or imported from Python code. For an example of
|
||||
its use see \file{Mac/scripts/genallsuites.py} in a source distribution,
|
||||
which generates the stub packages that are included in the standard
|
||||
library.
|
||||
|
||||
It defines the following public functions:
|
||||
|
||||
\begin{funcdesc}{is_scriptable}{application}
|
||||
Returns true if \code{application}, which should be passed as a pathname,
|
||||
appears to be scriptable. Take the return value with a grain of salt:
|
||||
\program{Internet Explorer} appears not to be scriptable but definitely is.
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{processfile}{application\optional{, output, basepkgname,
|
||||
edit_modnames, creatorsignature, dump, verbose}}
|
||||
Create a stub package for \code{application}, which should be passed as
|
||||
a full pathname. For a \file{.app} bundle this is the pathname to the
|
||||
bundle, not to the executable inside the bundle; for an unbundled CFM
|
||||
application you pass the filename of the application binary.
|
||||
|
||||
This function asks the application for its OSA terminology resources,
|
||||
decodes these resources and uses the resultant data to create the Python
|
||||
code for the package implementing the client stubs.
|
||||
|
||||
\code{output} is the pathname where the resulting package is stored, if
|
||||
not specified a standard "save file as" dialog is presented to
|
||||
the user. \code{basepkgname} is the base package on which this package
|
||||
will build, and defaults to \module{StdSuites}. Only when generating
|
||||
\module{StdSuites} itself do you need to specify this.
|
||||
\code{edit_modnames} is a dictionary that can be used to change
|
||||
modulenames that are too ugly after name mangling.
|
||||
\code{creator_signature} can be used to override the 4-char creator
|
||||
code, which is normally obtained from the \file{PkgInfo} file in the
|
||||
package or from the CFM file creator signature. When \code{dump} is
|
||||
given it should refer to a file object, and \code{processfile} will stop
|
||||
after decoding the resources and dump the Python representation of the
|
||||
terminology resources to this file. \code{verbose} should also be a file
|
||||
object, and specifying it will cause \code{processfile} to tell you what
|
||||
it is doing.
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{processfile_fromresource}{application\optional{, output,
|
||||
basepkgname, edit_modnames, creatorsignature, dump, verbose}}
|
||||
This function does the same as \code{processfile}, except that it uses a
|
||||
different method to get the terminology resources. It opens \code{application}
|
||||
as a resource file and reads all \code{"aete"} and \code{"aeut"} resources
|
||||
from this file.
|
||||
\end{funcdesc}
|
||||
|
|
@ -57,9 +57,8 @@ documented here:
|
|||
\input{libmacostools}
|
||||
\input{libmacui}
|
||||
\input{libframework}
|
||||
\input{libminiae}
|
||||
\input{libaepack}
|
||||
\input{libaetypes}
|
||||
|
||||
\input{scripting}
|
||||
|
||||
\input{toolbox} % MacOS Toolbox Modules
|
||||
\input{libcolorpicker}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
\chapter{MacPython OSA Modules \label{scripting}}
|
||||
|
||||
Python has a fairly complete implementation of the Open Scripting
|
||||
Architecure (OSA, also commonly referred to as AppleScript), allowing
|
||||
you to control scriptable applications from your Python program,
|
||||
and with a fairly pythonic interface.
|
||||
|
||||
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()
|
||||
print f.get(Finder.window(1).name)
|
||||
\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.
|
||||
|
||||
Note that in the current release there is no coupling between the main
|
||||
Python class implementing the verbs and the Python classes implementing
|
||||
the AppleScript classes. Hence, in the example above we need to use
|
||||
\code{f.get(Finder.window(1).name)} in stead of the more Pythonic
|
||||
\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}
|
|
@ -67,10 +67,7 @@ format only.
|
|||
To run your script from the Terminal window you must make sure that
|
||||
\file{/usr/local/bin} is in your shell search path before \file{/usr/bin},
|
||||
where the Apple-supplied Python lives (which is version 2.2, as of Mac OS X
|
||||
10.2.4). There is one Mac OS X quirk that you need to be aware of: programs
|
||||
that talk to the window manager (in other words, anything that has a GUI)
|
||||
need to be run in a special way. Use \program{pythonw} in stead of \program{python}
|
||||
to start such scripts.
|
||||
10.2.4).
|
||||
|
||||
To run your script from the Finder you have two options:
|
||||
\begin{itemize}
|
||||
|
@ -84,6 +81,13 @@ PythonLauncher has various preferences to control how your script is launched.
|
|||
Option-dragging allows you to change these for one invocation, or use its
|
||||
Preferences menu to change things globally.
|
||||
|
||||
\subsection{Running scripts with a GUI \label{osx-gui-scripts}}
|
||||
|
||||
There is one Mac OS X quirk that you need to be aware of: programs
|
||||
that talk to the Aqua window manager (in other words, anything that has a GUI)
|
||||
need to be run in a special way. Use \program{pythonw} in stead of \program{python}
|
||||
to start such scripts.
|
||||
|
||||
\subsection{configuration}
|
||||
|
||||
MacPython honours all standard unix environment variables such as \envvar{PYTHONPATH},
|
||||
|
|
Loading…
Reference in New Issue