cpython/Mac/Contrib/PythonScript/PythonScript.py

302 lines
7.9 KiB
Python

"""
Python script a module to comunicate with apple events
v 0.1a2
v.0.2 16 april 1998
"""
import sys
import getaete
import baetools
import baetypes
from Carbon import AE
import AppleEvents
import macfs
from types import *
#from aetypes import InstanceType
from aepack import AEDescType
ordinal = {
'every': 'all ',
'first' : 'firs',
'last' : 'last',
'any' : 'any ',
'middle' : 'midd'}
Error = 'PythonScript.Error'
class PsEvents:
pass
class PsClasses:
def __getattr__(self, name):
try:
return DCItem(name, self)
except:
pass
def __repr__(self):
if self.form != 'prop':
t = type(self.seld)
if t == StringType:
self.form = 'name'
elif baetypes.IsRange(self.seld):
self.form = 'rang'
elif baetypes.IsComparison(self.seld) or baetypes.IsLogical(self.seld):
self.form = 'test'
elif t == TupleType:
# Breakout: specify both form and seld in a tuple
# (if you want ID or rele or somesuch)
self.form, self.seld = self.seld
elif t == IntType:
self.form = 'indx'
else:
pass
if self.seld in ordinal.keys():
self.seld = baetypes.Ordinal(ordinal[self.seld])
self.form = 'indx'
s = "baetypes.ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
if `self.fr`:
s = s + ", %s)" % `self.fr`
else:
s = s + ")"
return s
def __str__(self):
return self.want
def template(self, seld=None, fr=None):
self.seld = seld
self.fr = fr
def template1(self, which, fr=None):
self.want = 'prop'
self.form = 'prop'
self.fr = fr
class DCItem:
def __init__(self, comp, fr):
self.compclass = comp
self.fr = fr
def __call__(self, which=None):
if which:
self.compclass = eval('PsClass.%s' % self.compclass)
else:
try:
self.compclass = eval('PsProperties.%s' % self.compclass)
except AttributeError:
self.compclass = eval('PsClass.%s' % self.compclass)
return self.compclass(which, self.fr)
class PsClass:
pass
class PsProperties:
pass
class PsEnumerations:
pass
def PsScript(sig=None, Timeout=0, Ignoring=0):
elements = {}
if sig:
target, sig = Signature(sig)
pyscript = getaete.Getaete(sig)
else:
target, sig = Signature('Pyth')
pyscript = getaete.Getaete()
setattr(PyScript, 'timeout', Timeout)
setattr(PyScript, 'ignoring', Ignoring)
setattr(PyScript, 'target', target)
for key, value in pyscript[0].items():
setattr(PsEvents, key, value)
for key, value in pyscript[1].items():
CreateClass(key, 'PsClasses', value)
for val in value[2]:
CreateProperty(val[0], 'PsClasses', `val[1]`)
if value[3]:
for val in value[3]:
if val[0] not in elements.keys():
elements[val[0]] = val[1]
elif len(val[1]) > len(elements[val[0]]):
elements[val[0]] = val[1]
for key, value in pyscript[2].items():
for val in value:
setattr(PsEnumerations, val[0], val[1])
def CreateClass(newClassName, superClassName, value):
parentDict = PsClass.__dict__
exec "class %s(%s): pass" % (newClassName, superClassName) in \
globals(), parentDict
newClassObj = parentDict[newClassName]
newClassObj.__init__ = template
exec "setattr(newClassObj, 'want', %s)" % `value[0]`
if value[2] and value[2][0][0] == 'every':
exec "setattr(newClassObj, 'plur', 1)"
def CreateProperty(newClassName, superClassName, value):
parentDict = PsProperties.__dict__
exec "class %s(%s): pass" % (newClassName, superClassName) in \
globals(), parentDict
newClassObj = parentDict[newClassName]
if newClassName == 'Every':
value = "baetypes.mkOrdinal('every')"
newClassObj.__init__ = template1
exec "setattr(newClassObj, 'seld', %s)" % value
def Signature(signature):
if type(signature) == AEDescType:
target = signature
elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
target = signature.__aepack__()
elif type(signature) == StringType:
if len(signature) == 4:
target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
target_signature = signature
else:
#This should ready be made persistant, so PythonScript 'remembered' where applications were
fss, ok = macfs.PromptGetFile('Find the aplication %s' % signature, 'APPL')
if ok:
target_signature = fss.GetCreatorType()[0]
target = AE.AECreateDesc(AppleEvents.typeApplSignature, target_signature)
else:
raise TypeError, "signature should be 4-char string or AEDesc"
return target, target_signature
class PyScript(PsEvents):
def __init__(self, name, obj=None, **args):
desc, code, subcode, rply, message, keywds = name
# print 'code', code
# print 'subcode', subcode
# print 'rply', rply
# print 'message', message
# print 'keywds', keywds
# print 'name', name
# print 'obj', obj
# print 'args', args
self.code = code
self.subcode = subcode
self.attributes ={}
self.arguments = {}
if keywds:
self.arguments = self.keyargs(keywds, args)
self.arguments['----'] = self.keyfms(message[0], obj)
##XXXX Eudora needs this XXXX##
if self.arguments['----'] == None:
del self.arguments['----']
# print 'arguments', self.arguments
if self.ignoring or rply[0] == 'null':
self.send_flags = AppleEvents.kAENoReply
else:
self.send_flags = AppleEvents.kAEWaitReply
self.send_priority = AppleEvents.kAENormalPriority
if self.timeout:
self.send_timeout = self.timeout
else:
self.send_timeout = AppleEvents.kAEDefaultTimeout
def keyargs(self, ats, args):
# print 'keyargs', ats, args
output = {}
for arg in args.keys():
for at in ats:
if at[0] == arg:
output[at[1]] = self.keyfms(at[2][0], args[arg])
return output
def keyfms(self, key, value):
# print 'keyfms', 'key', key, `value`
if key == 'obj ' or key == 'insl':
return eval(`value`)
elif key == 'TEXT':
return value
elif key == 'null':
return
elif key == 'bool':
return baetypes.mkboolean(value)
elif key == 'type':
try:
val = eval('PsClass.%s()' % value)
return baetypes.mktype(str(val))
except:
return baetypes.mktype(value)
else:
print "I don't know what to put here -- script.keyargs"
print key, `value`
sys.exit[1]
def newevent(self, code, subcode, parameters = {}, attributes = {}):
"""Create a complete structure for an apple event"""
# print code, subcode, parameters, attributes
event = AE.AECreateAppleEvent(code, subcode, self.target,
AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
baetools.packevent(event, parameters, attributes)
return event
def sendevent(self, event):
"""Send a pre-created appleevent, await the reply and unpack it"""
reply = event.AESend(self.send_flags, self.send_priority,
self.send_timeout)
parameters, attributes = baetools.unpackevent(reply)
return reply, parameters, attributes
def send(self, code, subcode, parameters = {}, attributes = {}):
"""Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
# print code, subcode, parameters, attributes
return self.sendevent(self.newevent(code, subcode, parameters, attributes))
def __str__(self):
_reply, _arguments, _attributes = self.send(self.code, self.subcode, self.arguments, self.attributes)
if _arguments.has_key('errn'):
raise baetools.Error, baetools.decodeerror(_arguments)
# XXXX Optionally decode result
if _arguments.has_key('----'):
return str(_arguments['----'])
else:
return
def test():
Simp = 'Hermit:Applications:SimpleText'
PsScript('MACS', Timeout=60*60*3)
# PsScript('CSOm', Timeout=60*60*3)
# PsScript('', Timeout=60*60*3)
# PyScript('macsoup')
ev = PsEvents
ps = PsClass
# print PsProperties.__dict__
# y = script(ev.Open, File('Hermit:Desktop Folder:Lincolnshire Imp'), using=Application_file(Simp))
# print baetypes.NProperty('prop', 'prop', 'pnam', baetypes.ObjectSpecifier('cdis', 'indx', 1, None))
# y = PyScript(ev.Get, Disk("Hermit").Folder(7).File(1).Name())
# y = PyScript(ev.Get, Disk("Hermit").Size(), As='Integer')
# y = PyScript(ev.Get, ps.Desktopobject(1).Startup_disk())
# y = PyScript(ev.Get, Mailbox(1).File(), as='TEXT')
# print 'y', y, type(y)
if __name__ == '__main__':
test()
# sys.exit(1)