summaryrefslogtreecommitdiffstats
path: root/Mac/Contrib/AECaptureParser/AECaptureParser.py
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Contrib/AECaptureParser/AECaptureParser.py')
-rw-r--r--Mac/Contrib/AECaptureParser/AECaptureParser.py362
1 files changed, 0 insertions, 362 deletions
diff --git a/Mac/Contrib/AECaptureParser/AECaptureParser.py b/Mac/Contrib/AECaptureParser/AECaptureParser.py
deleted file mode 100644
index 3d74f64..0000000
--- a/Mac/Contrib/AECaptureParser/AECaptureParser.py
+++ /dev/null
@@ -1,362 +0,0 @@
-'''
-AECaptureParser makes a brave attempt to convert the text output
-of the very handy Lasso Capture AE control panel
-into close-enough executable python code.
-
-In a roundabout way AECaptureParser offers the way to write lines of AppleScript
-and convert them to python code. Once Pythonised, the code can be made prettier,
-and it can run without Capture or Script Editor being open.
-
-You need Lasso Capture AE from Blueworld:
-ftp://ftp.blueworld.com/Lasso251/LassoCaptureAE.hqx
-
-Lasso Capture AE prints structured ascii representations in a small window.
-As these transcripts can be very complex, cut and paste to AECaptureParser, it parses and writes
-python code that will, when executed, cause the same events to happen.
-It's been tested with some household variety events, I'm sure there will be tons that
-don't work.
-
-All objects are converted to standard aetypes.ObjectSpecifier instances.
-
-How to use:
- 1. Start the Capture window
- 2. Cause the desired appleevent to happen
- - by writing a line of applescript in Script Editor and running it (!)
- - by recording some action in Script Editor and running it
- 3. Find the events in Capture:
- - make sure you get the appropriate events, cull if necessary
- - sometimes Capture barfs, just quit and start Capture again, run events again
- - AECaptureParser can process multiple events - it will just make more code.
- 4. Copy and paste in this script and execute
- 5. It will print python code that, when executed recreates the events.
-
-Example:
- For instance the following line of AppleScript in Script Editor
- tell application "Finder"
- return application processes
- end tell
- will result in the following transcript:
- [event: target="Finder", class=core, id=getd]
- '----':obj {form:indx, want:type(pcap), seld:abso(«616C6C20»), from:'null'()}
- [/event]
- Feed a string with this (and perhaps more) events to AECaptureParser
-
-Some mysteries:
- * what is '&subj' - it is sent in an activate event: &subj:'null'()
- The activate event works when this is left out. A possibility?
- * needs to deal with embedded aliasses
-
-
-'''
-__version__ = '0.002'
-__author__ = 'evb'
-
-
-import string
-
-opentag = '{'
-closetag = '}'
-
-
-
-import aetools
-import aetypes
-
-class eventtalker(aetools.TalkTo):
- pass
-
-def processes():
- '''Helper function to get the list of current processes and their creators
- This code was mostly written by AECaptureParser! It ain't pretty, but that's not python's fault!'''
- talker = eventtalker('MACS')
- _arguments = {}
- _attributes = {}
- p = []
- names = []
- creators = []
- results = []
- # first get the list of process names
- _arguments['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('pcap'),
- form="indx", seld=aetypes.Unknown('abso', "all "), fr=None)
- _reply, _arguments, _attributes = talker.send('core', 'getd', _arguments, _attributes)
- if _arguments.has_key('errn'):
- raise aetools.Error, aetools.decodeerror(_arguments)
- if _arguments.has_key('----'):
- p = _arguments['----']
- for proc in p:
- names.append(proc.seld)
- # then get the list of process creators
- _arguments = {}
- _attributes = {}
- AEobject_00 = aetypes.ObjectSpecifier(want=aetypes.Type('pcap'), form="indx", seld=aetypes.Unknown('abso', "all "), fr=None)
- AEobject_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('fcrt'), fr=AEobject_00)
- _arguments['----'] = AEobject_01
- _reply, _arguments, _attributes = talker.send('core', 'getd', _arguments, _attributes)
- if _arguments.has_key('errn'):
- raise aetools.Error, aetools.decodeerror(_arguments)
- if _arguments.has_key('----'):
- p = _arguments['----']
- for proc in p:
- creators.append(proc.type)
- # then put the lists together
- for i in range(len(names)):
- results.append((names[i], creators[i]))
- return results
-
-
-class AECaptureParser:
- '''convert a captured appleevent-description into executable python code'''
- def __init__(self, aetext):
- self.aetext = aetext
- self.events = []
- self.arguments = {}
- self.objectindex = 0
- self.varindex = 0
- self.currentevent = {'variables':{}, 'arguments':{}, 'objects':{}}
- self.parse()
-
- def parse(self):
- self.lines = string.split(self.aetext, '\n')
- for l in self.lines:
- if l[:7] == '[event:':
- self.eventheader(l)
- elif l[:7] == '[/event':
- if len(self.currentevent)<>0:
- self.events.append(self.currentevent)
- self.currentevent = {'variables':{}, 'arguments':{}, 'objects':{}}
- self.objectindex = 0
- else:
- self.line(l)
-
- def line(self, value):
- '''interpret literals, variables, lists etc.'''
- # stuff in [ ], l ists
- varstart = string.find(value, '[')
- varstop = string.find(value, ']')
- if varstart <> -1 and varstop <> -1 and varstop>varstart:
- variable = value[varstart:varstop+1]
- name = 'aevar_'+string.zfill(self.varindex, 2)
- self.currentevent['variables'][name] = variable
- value = value[:varstart]+name+value[varstop+1:]
- self.varindex = self.varindex + 1
- # stuff in « »
- # these are 'ordinal' descriptors of 4 letter codes, so translate
- varstart = string.find(value, '«')
- varstop = string.find(value, '»')
- if varstart <> -1 and varstop <> -1 and varstop>varstart:
- variable = value[varstart+1:varstop]
- t = ''
- for i in range(0, len(variable), 2):
- c = eval('0x'+variable[i : i+2])
- t = t + chr(c)
-
- name = 'aevar_'+string.zfill(self.varindex, 2)
- self.currentevent['variables'][name] = '"' + t + '"'
- value = value[:varstart]+name+value[varstop+1:]
- self.varindex = self.varindex + 1
- pos = string.find(value, ':')
- if pos==-1:return
- ok = 1
- while ok <> None:
- value, ok = self.parseobject(value)
- self.currentevent['arguments'].update(self.splitparts(value, ':'))
-
- # remove the &subj argument?
- if self.currentevent['arguments'].has_key('&subj'):
- del self.currentevent['arguments']['&subj']
-
- # check for arguments len(a) < 4, and pad with spaces
- for k in self.currentevent['arguments'].keys():
- if len(k)<4:
- newk = k + (4-len(k))*' '
- self.currentevent['arguments'][newk] = self.currentevent['arguments'][k]
- del self.currentevent['arguments'][k]
-
- def parseobject(self, obj):
- a, b = self.findtag(obj)
- stuff = None
- if a<>None and b<>None:
- stuff = obj[a:b]
- name = 'AEobject_'+string.zfill(self.objectindex, 2)
- self.currentevent['objects'][name] = self.splitparts(stuff, ':')
- obj = obj[:a-5] + name + obj[b+1:]
- self.objectindex = self.objectindex +1
- return obj, stuff
-
- def nextopen(self, pos, text):
- return string.find(text, opentag, pos)
-
- def nextclosed(self, pos, text):
- return string.find(text, closetag, pos)
-
- def nexttag(self, pos, text):
- start = self.nextopen(pos, text)
- stop = self.nextclosed(pos, text)
- if start == -1:
- if stop == -1:
- return -1, -1
- return 0, stop
- if start < stop and start<>-1:
- return 1, start
- else:
- return 0, stop
-
- def findtag(self, text):
- p = -1
- last = None,None
- while 1:
- kind, p = self.nexttag(p+1, text)
- if last[0]==1 and kind==0:
- return last[1]+len(opentag), p
- if (kind, p) == (-1, -1):
- break
- last=kind, p
- return None, None
-
- def splitparts(self, txt, splitter):
- res = {}
- parts = string.split(txt, ', ')
- for p in parts:
- pos = string.find(p, splitter)
- key = string.strip(p[:pos])
- value = string.strip(p[pos+1:])
- res[key] = self.map(value)
- return res
-
- def eventheader(self, hdr):
- self.currentevent['event'] = self.splitparts(hdr[7:-1], '=')
-
- def printobject(self, d):
- '''print one object as python code'''
- t = []
- obj = {}
- obj.update(d)
- t.append("aetypes.ObjectSpecifier(")
- if obj.has_key('want'):
- t.append('want=' + self.map(obj['want']))
- del obj['want']
- t.append(', ')
- if obj.has_key('form'):
- t.append('form=' + addquotes(self.map(obj['form'])))
- del obj['form']
- t.append(', ')
- if obj.has_key('seld'):
- t.append('seld=' + self.map(obj['seld']))
- del obj['seld']
- t.append(', ')
- if obj.has_key('from'):
- t.append('fr=' + self.map(obj['from']))
- del obj['from']
- if len(obj.keys()) > 0:
- print '# ', `obj`
- t.append(")")
- return string.join(t, '')
-
- def map(self, t):
- '''map some Capture syntax to python
- matchstring : [(old, new), ... ]
- '''
- m = {
- 'type(': [('type(', "aetypes.Type('"), (')', "')")],
- "'null'()": [("'null'()", "None")],
- 'abso(': [('abso(', "aetypes.Unknown('abso', ")],
- '–': [('–', '"')],
- '”': [('”', '"')],
- '[': [('[', '('), (', ', ',')],
- ']': [(']', ')')],
- '«': [('«', "«")],
- '»': [('»', "»")],
-
- }
- for k in m.keys():
- if string.find(t, k) <> -1:
- for old, new in m[k]:
- p = string.split(t, old)
- t = string.join(p, new)
- return t
-
- def printevent(self, i):
- '''print the entire captured sequence as python'''
- evt = self.events[i]
- code = []
- code.append('\n# start event ' + `i` + ', talking to ' + evt['event']['target'])
- # get the signature for the target application
- code.append('talker = eventtalker("'+self.gettarget(evt['event']['target'])+'")')
- code.append("_arguments = {}")
- code.append("_attributes = {}")
- # write the variables
- for key, value in evt['variables'].items():
- value = evt['variables'][key]
- code.append(key + ' = ' + value)
- # write the object in the right order
- objkeys = evt['objects'].keys()
- objkeys.sort()
- for key in objkeys:
- value = evt['objects'][key]
- code.append(key + ' = ' + self.printobject(value))
- # then write the arguments
- for key, value in evt['arguments'].items():
- code.append("_arguments[" + addquotes(key) + "] = " + value )
- code.append('_reply, _arguments, _attributes = talker.send("'+
- evt['event']['class']+'", "'+evt['event']['id']+'", _arguments, _attributes)')
- code.append("if _arguments.has_key('errn'):")
- code.append('\traise aetools.Error, aetools.decodeerror(_arguments)')
- code.append("if _arguments.has_key('----'):")
- code.append("\tprint _arguments['----']")
- code.append('# end event ' + `i`)
- return string.join(code, '\n')
-
- def gettarget(self, target):
- '''get the signature for the target application'''
- target = target[1:-1]
- if target == 'Finder':
- return "MACS"
- apps = processes()
- for name, creator in apps:
- if name == target:
- return creator
- return '****'
-
- def makecode(self):
- code = []
- code.append("\n\n")
- code.append("# code generated by AECaptureParser v " + __version__)
- code.append("# imports, definitions for all events")
- code.append("import aetools")
- code.append("import aetypes")
- code.append("class eventtalker(aetools.TalkTo):")
- code.append("\tpass")
- code.append("# the events")
- # print the events
- for i in range(len(self.events)):
- code.append(self.printevent(i))
- code.append("# end code")
- return string.join(code, '\n')
-
-def addquotes(txt):
- quotes = ['"', "'"]
- if not txt[0] in quotes and not txt[-1] in quotes:
- return '"'+txt+'"'
- return txt
-
-
-
-
-
-
-# ------------------------------------------
-# the factory
-# ------------------------------------------
-
-# for instance, this event was captured from the Script Editor asking the Finder for a list of active processes.
-
-eventreceptacle = """
-
-[event: target="Finder", class=core, id=setd]
-'----':obj {form:prop, want:type(prop), seld:type(posn), from:obj {form:name, want:type(cfol), seld:–MoPar:Data:DevDev:Python:Python 1.5.2c1:Extensions”, from:'null'()}}, data:[100, 10]
-[/event]
-
-"""
-
-aet = AECaptureParser(eventreceptacle)
-print aet.makecode()