Jack Jansen | f4f6d48 | 2002-08-02 11:12:15 +0000 | [diff] [blame] | 1 | """argvemulator - create sys.argv from OSA events. Used by applets that |
| 2 | want unix-style arguments. |
| 3 | """ |
| 4 | |
| 5 | import sys |
| 6 | import traceback |
| 7 | from Carbon import AE |
| 8 | from Carbon.AppleEvents import * |
| 9 | from Carbon import Evt |
| 10 | from Carbon.Events import * |
| 11 | import aetools |
| 12 | |
| 13 | class ArgvCollector: |
| 14 | |
| 15 | """A minimal FrameWork.Application-like class""" |
| 16 | |
| 17 | def __init__(self): |
| 18 | self.quitting = 0 |
| 19 | self.ae_handlers = {} |
Jack Jansen | 6e1986b | 2002-08-02 12:56:21 +0000 | [diff] [blame] | 20 | # Remove the funny -psn_xxx_xxx argument |
Jack Jansen | a9454e2 | 2002-08-02 14:54:46 +0000 | [diff] [blame] | 21 | if len(sys.argv) > 1 and sys.argv[1][:4] == '-psn': |
| 22 | del sys.argv[1] |
Jack Jansen | f4f6d48 | 2002-08-02 11:12:15 +0000 | [diff] [blame] | 23 | self.installaehandler('aevt', 'oapp', self.open_app) |
Jack Jansen | 6e1986b | 2002-08-02 12:56:21 +0000 | [diff] [blame] | 24 | self.installaehandler('aevt', 'odoc', self.open_file) |
Jack Jansen | f4f6d48 | 2002-08-02 11:12:15 +0000 | [diff] [blame] | 25 | |
| 26 | def installaehandler(self, classe, type, callback): |
| 27 | AE.AEInstallEventHandler(classe, type, self.callback_wrapper) |
| 28 | self.ae_handlers[(classe, type)] = callback |
| 29 | |
| 30 | def close(self): |
| 31 | for classe, type in self.ae_handlers.keys(): |
| 32 | AE.AERemoveEventHandler(classe, type) |
| 33 | |
| 34 | def mainloop(self, mask = highLevelEventMask, timeout = 1*60): |
| 35 | stoptime = Evt.TickCount() + timeout |
| 36 | while not self.quitting and Evt.TickCount() < stoptime: |
| 37 | self.dooneevent(mask, timeout) |
| 38 | self.close() |
| 39 | |
| 40 | def _quit(self): |
| 41 | self.quitting = 1 |
| 42 | |
| 43 | def dooneevent(self, mask = highLevelEventMask, timeout = 1*60): |
| 44 | got, event = Evt.WaitNextEvent(mask, timeout) |
| 45 | if got: |
| 46 | self.lowlevelhandler(event) |
| 47 | |
| 48 | def lowlevelhandler(self, event): |
| 49 | what, message, when, where, modifiers = event |
| 50 | h, v = where |
| 51 | if what == kHighLevelEvent: |
| 52 | try: |
| 53 | AE.AEProcessAppleEvent(event) |
| 54 | except AE.Error, err: |
| 55 | msg = "High Level Event: %s %s" % \ |
| 56 | (`hex(message)`, `hex(h | (v<<16))`) |
| 57 | print 'AE error: ', err |
| 58 | print 'in', msg |
| 59 | traceback.print_exc() |
| 60 | return |
| 61 | else: |
| 62 | print "Unhandled event:", event |
| 63 | |
| 64 | def callback_wrapper(self, _request, _reply): |
| 65 | _parameters, _attributes = aetools.unpackevent(_request) |
| 66 | _class = _attributes['evcl'].type |
| 67 | _type = _attributes['evid'].type |
| 68 | |
| 69 | if self.ae_handlers.has_key((_class, _type)): |
| 70 | _function = self.ae_handlers[(_class, _type)] |
| 71 | elif self.ae_handlers.has_key((_class, '****')): |
| 72 | _function = self.ae_handlers[(_class, '****')] |
| 73 | elif self.ae_handlers.has_key(('****', '****')): |
| 74 | _function = self.ae_handlers[('****', '****')] |
| 75 | else: |
| 76 | raise 'Cannot happen: AE callback without handler', (_class, _type) |
| 77 | |
| 78 | # XXXX Do key-to-name mapping here |
| 79 | |
| 80 | _parameters['_attributes'] = _attributes |
| 81 | _parameters['_class'] = _class |
| 82 | _parameters['_type'] = _type |
| 83 | if _parameters.has_key('----'): |
| 84 | _object = _parameters['----'] |
| 85 | del _parameters['----'] |
| 86 | # The try/except that used to be here can mask programmer errors. |
| 87 | # Let the program crash, the programmer can always add a **args |
| 88 | # to the formal parameter list. |
| 89 | rv = apply(_function, (_object,), _parameters) |
| 90 | else: |
| 91 | #Same try/except comment as above |
| 92 | rv = apply(_function, (), _parameters) |
| 93 | |
| 94 | if rv == None: |
| 95 | aetools.packevent(_reply, {}) |
| 96 | else: |
| 97 | aetools.packevent(_reply, {'----':rv}) |
| 98 | |
| 99 | def open_app(self, **args): |
| 100 | self._quit() |
| 101 | |
| 102 | def open_file(self, _object=None, **args): |
| 103 | for alias in _object: |
| 104 | fss = alias.Resolve()[0] |
| 105 | pathname = fss.as_pathname() |
| 106 | sys.argv.append(pathname) |
| 107 | self._quit() |
| 108 | |
| 109 | def other(self, _object=None, _class=None, _type=None, **args): |
| 110 | print 'Ignore AppleEvent', (_class, _type), 'for', _object, 'Other args:', args |
| 111 | |
| 112 | if __name__ == '__main__': |
| 113 | ArgvCollector().mainloop() |
| 114 | print "sys.argv=", sys.argv |