mirror of https://github.com/python/cpython
Detabbed.
This commit is contained in:
parent
058a84f36a
commit
0ae3220736
|
@ -3,119 +3,119 @@ error='Audio_mac.error'
|
||||||
|
|
||||||
class Play_Audio_mac:
|
class Play_Audio_mac:
|
||||||
|
|
||||||
def __init__(self, qsize=QSIZE):
|
def __init__(self, qsize=QSIZE):
|
||||||
self._chan = None
|
self._chan = None
|
||||||
self._qsize = qsize
|
self._qsize = qsize
|
||||||
self._outrate = 22254
|
self._outrate = 22254
|
||||||
self._sampwidth = 1
|
self._sampwidth = 1
|
||||||
self._nchannels = 1
|
self._nchannels = 1
|
||||||
self._gc = []
|
self._gc = []
|
||||||
self._usercallback = None
|
self._usercallback = None
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.stop()
|
self.stop()
|
||||||
self._usercallback = None
|
self._usercallback = None
|
||||||
|
|
||||||
def wait(self):
|
def wait(self):
|
||||||
import time
|
import time
|
||||||
while self.getfilled():
|
while self.getfilled():
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self._chan = None
|
self._chan = None
|
||||||
self._gc = []
|
self._gc = []
|
||||||
|
|
||||||
def stop(self, quietNow = 1):
|
def stop(self, quietNow = 1):
|
||||||
##chan = self._chan
|
##chan = self._chan
|
||||||
self._chan = None
|
self._chan = None
|
||||||
##chan.SndDisposeChannel(1)
|
##chan.SndDisposeChannel(1)
|
||||||
self._gc = []
|
self._gc = []
|
||||||
|
|
||||||
def setoutrate(self, outrate):
|
def setoutrate(self, outrate):
|
||||||
self._outrate = outrate
|
self._outrate = outrate
|
||||||
|
|
||||||
def setsampwidth(self, sampwidth):
|
def setsampwidth(self, sampwidth):
|
||||||
self._sampwidth = sampwidth
|
self._sampwidth = sampwidth
|
||||||
|
|
||||||
def setnchannels(self, nchannels):
|
def setnchannels(self, nchannels):
|
||||||
self._nchannels = nchannels
|
self._nchannels = nchannels
|
||||||
|
|
||||||
def writeframes(self, data):
|
def writeframes(self, data):
|
||||||
import time
|
import time
|
||||||
from Carbon.Sound import bufferCmd, callBackCmd, extSH
|
from Carbon.Sound import bufferCmd, callBackCmd, extSH
|
||||||
import struct
|
import struct
|
||||||
import MacOS
|
import MacOS
|
||||||
if not self._chan:
|
if not self._chan:
|
||||||
from Carbon import Snd
|
from Carbon import Snd
|
||||||
self._chan = Snd.SndNewChannel(5, 0, self._callback)
|
self._chan = Snd.SndNewChannel(5, 0, self._callback)
|
||||||
nframes = len(data) / self._nchannels / self._sampwidth
|
nframes = len(data) / self._nchannels / self._sampwidth
|
||||||
if len(data) != nframes * self._nchannels * self._sampwidth:
|
if len(data) != nframes * self._nchannels * self._sampwidth:
|
||||||
raise error, 'data is not a whole number of frames'
|
raise error, 'data is not a whole number of frames'
|
||||||
while self._gc and \
|
while self._gc and \
|
||||||
self.getfilled() + nframes > \
|
self.getfilled() + nframes > \
|
||||||
self._qsize / self._nchannels / self._sampwidth:
|
self._qsize / self._nchannels / self._sampwidth:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
if self._sampwidth == 1:
|
if self._sampwidth == 1:
|
||||||
import audioop
|
import audioop
|
||||||
data = audioop.add(data, '\x80'*len(data), 1)
|
data = audioop.add(data, '\x80'*len(data), 1)
|
||||||
h1 = struct.pack('llHhllbbl',
|
h1 = struct.pack('llHhllbbl',
|
||||||
id(data)+MacOS.string_id_to_buffer,
|
id(data)+MacOS.string_id_to_buffer,
|
||||||
self._nchannels,
|
self._nchannels,
|
||||||
self._outrate, 0,
|
self._outrate, 0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
extSH,
|
extSH,
|
||||||
60,
|
60,
|
||||||
nframes)
|
nframes)
|
||||||
h2 = 22*'\0'
|
h2 = 22*'\0'
|
||||||
h3 = struct.pack('hhlll',
|
h3 = struct.pack('hhlll',
|
||||||
self._sampwidth*8,
|
self._sampwidth*8,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0)
|
0)
|
||||||
header = h1+h2+h3
|
header = h1+h2+h3
|
||||||
self._gc.append((header, data))
|
self._gc.append((header, data))
|
||||||
self._chan.SndDoCommand((bufferCmd, 0, header), 0)
|
self._chan.SndDoCommand((bufferCmd, 0, header), 0)
|
||||||
self._chan.SndDoCommand((callBackCmd, 0, 0), 0)
|
self._chan.SndDoCommand((callBackCmd, 0, 0), 0)
|
||||||
|
|
||||||
def _callback(self, *args):
|
def _callback(self, *args):
|
||||||
del self._gc[0]
|
del self._gc[0]
|
||||||
if self._usercallback:
|
if self._usercallback:
|
||||||
self._usercallback()
|
self._usercallback()
|
||||||
|
|
||||||
def setcallback(self, callback):
|
def setcallback(self, callback):
|
||||||
self._usercallback = callback
|
self._usercallback = callback
|
||||||
|
|
||||||
def getfilled(self):
|
def getfilled(self):
|
||||||
filled = 0
|
filled = 0
|
||||||
for header, data in self._gc:
|
for header, data in self._gc:
|
||||||
filled = filled + len(data)
|
filled = filled + len(data)
|
||||||
return filled / self._nchannels / self._sampwidth
|
return filled / self._nchannels / self._sampwidth
|
||||||
|
|
||||||
def getfillable(self):
|
def getfillable(self):
|
||||||
return (self._qsize / self._nchannels / self._sampwidth) - self.getfilled()
|
return (self._qsize / self._nchannels / self._sampwidth) - self.getfilled()
|
||||||
|
|
||||||
def ulaw2lin(self, data):
|
def ulaw2lin(self, data):
|
||||||
import audioop
|
import audioop
|
||||||
return audioop.ulaw2lin(data, 2)
|
return audioop.ulaw2lin(data, 2)
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
import aifc
|
import aifc
|
||||||
import EasyDialogs
|
import EasyDialogs
|
||||||
fn = EasyDialogs.AskFileForOpen(message="Select an AIFF soundfile", typeList=("AIFF",))
|
fn = EasyDialogs.AskFileForOpen(message="Select an AIFF soundfile", typeList=("AIFF",))
|
||||||
if not fn: return
|
if not fn: return
|
||||||
af = aifc.open(fn, 'r')
|
af = aifc.open(fn, 'r')
|
||||||
print af.getparams()
|
print af.getparams()
|
||||||
p = Play_Audio_mac()
|
p = Play_Audio_mac()
|
||||||
p.setoutrate(af.getframerate())
|
p.setoutrate(af.getframerate())
|
||||||
p.setsampwidth(af.getsampwidth())
|
p.setsampwidth(af.getsampwidth())
|
||||||
p.setnchannels(af.getnchannels())
|
p.setnchannels(af.getnchannels())
|
||||||
BUFSIZ = 10000
|
BUFSIZ = 10000
|
||||||
while 1:
|
while 1:
|
||||||
data = af.readframes(BUFSIZ)
|
data = af.readframes(BUFSIZ)
|
||||||
if not data: break
|
if not data: break
|
||||||
p.writeframes(data)
|
p.writeframes(data)
|
||||||
print 'wrote', len(data), 'space', p.getfillable()
|
print 'wrote', len(data), 'space', p.getfillable()
|
||||||
p.wait()
|
p.wait()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test()
|
test()
|
||||||
|
|
|
@ -5,53 +5,53 @@ import struct
|
||||||
|
|
||||||
# These needn't go through this module, but are here for completeness
|
# These needn't go through this module, but are here for completeness
|
||||||
def SetControlData_Handle(control, part, selector, data):
|
def SetControlData_Handle(control, part, selector, data):
|
||||||
control.SetControlData_Handle(part, selector, data)
|
control.SetControlData_Handle(part, selector, data)
|
||||||
|
|
||||||
def GetControlData_Handle(control, part, selector):
|
def GetControlData_Handle(control, part, selector):
|
||||||
return control.GetControlData_Handle(part, selector)
|
return control.GetControlData_Handle(part, selector)
|
||||||
|
|
||||||
_accessdict = {
|
_accessdict = {
|
||||||
kControlPopupButtonMenuHandleTag: (SetControlData_Handle, GetControlData_Handle),
|
kControlPopupButtonMenuHandleTag: (SetControlData_Handle, GetControlData_Handle),
|
||||||
}
|
}
|
||||||
|
|
||||||
_codingdict = {
|
_codingdict = {
|
||||||
kControlPushButtonDefaultTag : ("b", None, None),
|
kControlPushButtonDefaultTag : ("b", None, None),
|
||||||
|
|
||||||
kControlEditTextTextTag: (None, None, None),
|
kControlEditTextTextTag: (None, None, None),
|
||||||
kControlEditTextPasswordTag: (None, None, None),
|
kControlEditTextPasswordTag: (None, None, None),
|
||||||
|
|
||||||
kControlPopupButtonMenuIDTag: ("h", None, None),
|
kControlPopupButtonMenuIDTag: ("h", None, None),
|
||||||
|
|
||||||
kControlListBoxDoubleClickTag: ("b", None, None),
|
kControlListBoxDoubleClickTag: ("b", None, None),
|
||||||
}
|
}
|
||||||
|
|
||||||
def SetControlData(control, part, selector, data):
|
def SetControlData(control, part, selector, data):
|
||||||
if _accessdict.has_key(selector):
|
if _accessdict.has_key(selector):
|
||||||
setfunc, getfunc = _accessdict[selector]
|
setfunc, getfunc = _accessdict[selector]
|
||||||
setfunc(control, part, selector, data)
|
setfunc(control, part, selector, data)
|
||||||
return
|
return
|
||||||
if not _codingdict.has_key(selector):
|
if not _codingdict.has_key(selector):
|
||||||
raise KeyError, ('Unknown control selector', selector)
|
raise KeyError, ('Unknown control selector', selector)
|
||||||
structfmt, coder, decoder = _codingdict[selector]
|
structfmt, coder, decoder = _codingdict[selector]
|
||||||
if coder:
|
if coder:
|
||||||
data = coder(data)
|
data = coder(data)
|
||||||
if structfmt:
|
if structfmt:
|
||||||
data = struct.pack(structfmt, data)
|
data = struct.pack(structfmt, data)
|
||||||
control.SetControlData(part, selector, data)
|
control.SetControlData(part, selector, data)
|
||||||
|
|
||||||
def GetControlData(control, part, selector):
|
def GetControlData(control, part, selector):
|
||||||
if _accessdict.has_key(selector):
|
if _accessdict.has_key(selector):
|
||||||
setfunc, getfunc = _accessdict[selector]
|
setfunc, getfunc = _accessdict[selector]
|
||||||
return getfunc(control, part, selector, data)
|
return getfunc(control, part, selector, data)
|
||||||
if not _codingdict.has_key(selector):
|
if not _codingdict.has_key(selector):
|
||||||
raise KeyError, ('Unknown control selector', selector)
|
raise KeyError, ('Unknown control selector', selector)
|
||||||
structfmt, coder, decoder = _codingdict[selector]
|
structfmt, coder, decoder = _codingdict[selector]
|
||||||
data = control.GetControlData(part, selector)
|
data = control.GetControlData(part, selector)
|
||||||
if structfmt:
|
if structfmt:
|
||||||
data = struct.unpack(structfmt, data)
|
data = struct.unpack(structfmt, data)
|
||||||
if decoder:
|
if decoder:
|
||||||
data = decoder(data)
|
data = decoder(data)
|
||||||
if type(data) == type(()) and len(data) == 1:
|
if type(data) == type(()) and len(data) == 1:
|
||||||
data = data[0]
|
data = data[0]
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
try:
|
try:
|
||||||
from OverrideFrom23._Res import *
|
from OverrideFrom23._Res import *
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from _Res import *
|
from _Res import *
|
||||||
|
|
|
@ -14,202 +14,202 @@ import imgformat
|
||||||
|
|
||||||
# PixMap data structure element format (as used with struct)
|
# PixMap data structure element format (as used with struct)
|
||||||
_pmElemFormat = {
|
_pmElemFormat = {
|
||||||
'baseAddr':'l', # address of pixel data
|
'baseAddr':'l', # address of pixel data
|
||||||
'rowBytes':'H', # bytes per row, plus 0x8000
|
'rowBytes':'H', # bytes per row, plus 0x8000
|
||||||
'bounds':'hhhh', # coordinates imposed over pixel data
|
'bounds':'hhhh', # coordinates imposed over pixel data
|
||||||
'top':'h',
|
'top':'h',
|
||||||
'left':'h',
|
'left':'h',
|
||||||
'bottom':'h',
|
'bottom':'h',
|
||||||
'right':'h',
|
'right':'h',
|
||||||
'pmVersion':'h', # flags for Color QuickDraw
|
'pmVersion':'h', # flags for Color QuickDraw
|
||||||
'packType':'h', # format of compression algorithm
|
'packType':'h', # format of compression algorithm
|
||||||
'packSize':'l', # size after compression
|
'packSize':'l', # size after compression
|
||||||
'hRes':'l', # horizontal pixels per inch
|
'hRes':'l', # horizontal pixels per inch
|
||||||
'vRes':'l', # vertical pixels per inch
|
'vRes':'l', # vertical pixels per inch
|
||||||
'pixelType':'h', # pixel format
|
'pixelType':'h', # pixel format
|
||||||
'pixelSize':'h', # bits per pixel
|
'pixelSize':'h', # bits per pixel
|
||||||
'cmpCount':'h', # color components per pixel
|
'cmpCount':'h', # color components per pixel
|
||||||
'cmpSize':'h', # bits per component
|
'cmpSize':'h', # bits per component
|
||||||
'planeBytes':'l', # offset in bytes to next plane
|
'planeBytes':'l', # offset in bytes to next plane
|
||||||
'pmTable':'l', # handle to color table
|
'pmTable':'l', # handle to color table
|
||||||
'pmReserved':'l' # reserved for future use
|
'pmReserved':'l' # reserved for future use
|
||||||
}
|
}
|
||||||
|
|
||||||
# PixMap data structure element offset
|
# PixMap data structure element offset
|
||||||
_pmElemOffset = {
|
_pmElemOffset = {
|
||||||
'baseAddr':0,
|
'baseAddr':0,
|
||||||
'rowBytes':4,
|
'rowBytes':4,
|
||||||
'bounds':6,
|
'bounds':6,
|
||||||
'top':6,
|
'top':6,
|
||||||
'left':8,
|
'left':8,
|
||||||
'bottom':10,
|
'bottom':10,
|
||||||
'right':12,
|
'right':12,
|
||||||
'pmVersion':14,
|
'pmVersion':14,
|
||||||
'packType':16,
|
'packType':16,
|
||||||
'packSize':18,
|
'packSize':18,
|
||||||
'hRes':22,
|
'hRes':22,
|
||||||
'vRes':26,
|
'vRes':26,
|
||||||
'pixelType':30,
|
'pixelType':30,
|
||||||
'pixelSize':32,
|
'pixelSize':32,
|
||||||
'cmpCount':34,
|
'cmpCount':34,
|
||||||
'cmpSize':36,
|
'cmpSize':36,
|
||||||
'planeBytes':38,
|
'planeBytes':38,
|
||||||
'pmTable':42,
|
'pmTable':42,
|
||||||
'pmReserved':46
|
'pmReserved':46
|
||||||
}
|
}
|
||||||
|
|
||||||
class PixMapWrapper:
|
class PixMapWrapper:
|
||||||
"""PixMapWrapper -- wraps the QD PixMap object in a Python class,
|
"""PixMapWrapper -- wraps the QD PixMap object in a Python class,
|
||||||
with methods to easily get/set various pixmap fields. Note: Use the
|
with methods to easily get/set various pixmap fields. Note: Use the
|
||||||
PixMap() method when passing to QD calls."""
|
PixMap() method when passing to QD calls."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__dict__['data'] = ''
|
self.__dict__['data'] = ''
|
||||||
self._header = struct.pack("lhhhhhhhlllhhhhlll",
|
self._header = struct.pack("lhhhhhhhlllhhhhlll",
|
||||||
id(self.data)+MacOS.string_id_to_buffer,
|
id(self.data)+MacOS.string_id_to_buffer,
|
||||||
0, # rowBytes
|
0, # rowBytes
|
||||||
0, 0, 0, 0, # bounds
|
0, 0, 0, 0, # bounds
|
||||||
0, # pmVersion
|
0, # pmVersion
|
||||||
0, 0, # packType, packSize
|
0, 0, # packType, packSize
|
||||||
72<<16, 72<<16, # hRes, vRes
|
72<<16, 72<<16, # hRes, vRes
|
||||||
QuickDraw.RGBDirect, # pixelType
|
QuickDraw.RGBDirect, # pixelType
|
||||||
16, # pixelSize
|
16, # pixelSize
|
||||||
2, 5, # cmpCount, cmpSize,
|
2, 5, # cmpCount, cmpSize,
|
||||||
0, 0, 0) # planeBytes, pmTable, pmReserved
|
0, 0, 0) # planeBytes, pmTable, pmReserved
|
||||||
self.__dict__['_pm'] = Qd.RawBitMap(self._header)
|
self.__dict__['_pm'] = Qd.RawBitMap(self._header)
|
||||||
|
|
||||||
def _stuff(self, element, bytes):
|
def _stuff(self, element, bytes):
|
||||||
offset = _pmElemOffset[element]
|
offset = _pmElemOffset[element]
|
||||||
fmt = _pmElemFormat[element]
|
fmt = _pmElemFormat[element]
|
||||||
self._header = self._header[:offset] \
|
self._header = self._header[:offset] \
|
||||||
+ struct.pack(fmt, bytes) \
|
+ struct.pack(fmt, bytes) \
|
||||||
+ self._header[offset + struct.calcsize(fmt):]
|
+ self._header[offset + struct.calcsize(fmt):]
|
||||||
self.__dict__['_pm'] = None
|
self.__dict__['_pm'] = None
|
||||||
|
|
||||||
def _unstuff(self, element):
|
def _unstuff(self, element):
|
||||||
offset = _pmElemOffset[element]
|
offset = _pmElemOffset[element]
|
||||||
fmt = _pmElemFormat[element]
|
fmt = _pmElemFormat[element]
|
||||||
return struct.unpack(fmt, self._header[offset:offset+struct.calcsize(fmt)])[0]
|
return struct.unpack(fmt, self._header[offset:offset+struct.calcsize(fmt)])[0]
|
||||||
|
|
||||||
def __setattr__(self, attr, val):
|
def __setattr__(self, attr, val):
|
||||||
if attr == 'baseAddr':
|
if attr == 'baseAddr':
|
||||||
raise 'UseErr', "don't assign to .baseAddr -- assign to .data instead"
|
raise 'UseErr', "don't assign to .baseAddr -- assign to .data instead"
|
||||||
elif attr == 'data':
|
elif attr == 'data':
|
||||||
self.__dict__['data'] = val
|
self.__dict__['data'] = val
|
||||||
self._stuff('baseAddr', id(self.data) + MacOS.string_id_to_buffer)
|
self._stuff('baseAddr', id(self.data) + MacOS.string_id_to_buffer)
|
||||||
elif attr == 'rowBytes':
|
elif attr == 'rowBytes':
|
||||||
# high bit is always set for some odd reason
|
# high bit is always set for some odd reason
|
||||||
self._stuff('rowBytes', val | 0x8000)
|
self._stuff('rowBytes', val | 0x8000)
|
||||||
elif attr == 'bounds':
|
elif attr == 'bounds':
|
||||||
# assume val is in official Left, Top, Right, Bottom order!
|
# assume val is in official Left, Top, Right, Bottom order!
|
||||||
self._stuff('left',val[0])
|
self._stuff('left',val[0])
|
||||||
self._stuff('top',val[1])
|
self._stuff('top',val[1])
|
||||||
self._stuff('right',val[2])
|
self._stuff('right',val[2])
|
||||||
self._stuff('bottom',val[3])
|
self._stuff('bottom',val[3])
|
||||||
elif attr == 'hRes' or attr == 'vRes':
|
elif attr == 'hRes' or attr == 'vRes':
|
||||||
# 16.16 fixed format, so just shift 16 bits
|
# 16.16 fixed format, so just shift 16 bits
|
||||||
self._stuff(attr, int(val) << 16)
|
self._stuff(attr, int(val) << 16)
|
||||||
elif attr in _pmElemFormat.keys():
|
elif attr in _pmElemFormat.keys():
|
||||||
# any other pm attribute -- just stuff
|
# any other pm attribute -- just stuff
|
||||||
self._stuff(attr, val)
|
self._stuff(attr, val)
|
||||||
else:
|
else:
|
||||||
self.__dict__[attr] = val
|
self.__dict__[attr] = val
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr == 'rowBytes':
|
if attr == 'rowBytes':
|
||||||
# high bit is always set for some odd reason
|
# high bit is always set for some odd reason
|
||||||
return self._unstuff('rowBytes') & 0x7FFF
|
return self._unstuff('rowBytes') & 0x7FFF
|
||||||
elif attr == 'bounds':
|
elif attr == 'bounds':
|
||||||
# return bounds in official Left, Top, Right, Bottom order!
|
# return bounds in official Left, Top, Right, Bottom order!
|
||||||
return ( \
|
return ( \
|
||||||
self._unstuff('left'),
|
self._unstuff('left'),
|
||||||
self._unstuff('top'),
|
self._unstuff('top'),
|
||||||
self._unstuff('right'),
|
self._unstuff('right'),
|
||||||
self._unstuff('bottom') )
|
self._unstuff('bottom') )
|
||||||
elif attr == 'hRes' or attr == 'vRes':
|
elif attr == 'hRes' or attr == 'vRes':
|
||||||
# 16.16 fixed format, so just shift 16 bits
|
# 16.16 fixed format, so just shift 16 bits
|
||||||
return self._unstuff(attr) >> 16
|
return self._unstuff(attr) >> 16
|
||||||
elif attr in _pmElemFormat.keys():
|
elif attr in _pmElemFormat.keys():
|
||||||
# any other pm attribute -- just unstuff
|
# any other pm attribute -- just unstuff
|
||||||
return self._unstuff(attr)
|
return self._unstuff(attr)
|
||||||
else:
|
else:
|
||||||
return self.__dict__[attr]
|
return self.__dict__[attr]
|
||||||
|
|
||||||
|
|
||||||
def PixMap(self):
|
def PixMap(self):
|
||||||
"Return a QuickDraw PixMap corresponding to this data."
|
"Return a QuickDraw PixMap corresponding to this data."
|
||||||
if not self.__dict__['_pm']:
|
if not self.__dict__['_pm']:
|
||||||
self.__dict__['_pm'] = Qd.RawBitMap(self._header)
|
self.__dict__['_pm'] = Qd.RawBitMap(self._header)
|
||||||
return self.__dict__['_pm']
|
return self.__dict__['_pm']
|
||||||
|
|
||||||
def blit(self, x1=0,y1=0,x2=None,y2=None, port=None):
|
def blit(self, x1=0,y1=0,x2=None,y2=None, port=None):
|
||||||
"""Draw this pixmap into the given (default current) grafport."""
|
"""Draw this pixmap into the given (default current) grafport."""
|
||||||
src = self.bounds
|
src = self.bounds
|
||||||
dest = [x1,y1,x2,y2]
|
dest = [x1,y1,x2,y2]
|
||||||
if x2 == None:
|
if x2 == None:
|
||||||
dest[2] = x1 + src[2]-src[0]
|
dest[2] = x1 + src[2]-src[0]
|
||||||
if y2 == None:
|
if y2 == None:
|
||||||
dest[3] = y1 + src[3]-src[1]
|
dest[3] = y1 + src[3]-src[1]
|
||||||
if not port: port = Qd.GetPort()
|
if not port: port = Qd.GetPort()
|
||||||
Qd.CopyBits(self.PixMap(), port.GetPortBitMapForCopyBits(), src, tuple(dest),
|
Qd.CopyBits(self.PixMap(), port.GetPortBitMapForCopyBits(), src, tuple(dest),
|
||||||
QuickDraw.srcCopy, None)
|
QuickDraw.srcCopy, None)
|
||||||
|
|
||||||
def fromstring(self,s,width,height,format=imgformat.macrgb):
|
def fromstring(self,s,width,height,format=imgformat.macrgb):
|
||||||
"""Stuff this pixmap with raw pixel data from a string.
|
"""Stuff this pixmap with raw pixel data from a string.
|
||||||
Supply width, height, and one of the imgformat specifiers."""
|
Supply width, height, and one of the imgformat specifiers."""
|
||||||
# we only support 16- and 32-bit mac rgb...
|
# we only support 16- and 32-bit mac rgb...
|
||||||
# so convert if necessary
|
# so convert if necessary
|
||||||
if format != imgformat.macrgb and format != imgformat.macrgb16:
|
if format != imgformat.macrgb and format != imgformat.macrgb16:
|
||||||
# (LATER!)
|
# (LATER!)
|
||||||
raise "NotImplementedError", "conversion to macrgb or macrgb16"
|
raise "NotImplementedError", "conversion to macrgb or macrgb16"
|
||||||
self.data = s
|
self.data = s
|
||||||
self.bounds = (0,0,width,height)
|
self.bounds = (0,0,width,height)
|
||||||
self.cmpCount = 3
|
self.cmpCount = 3
|
||||||
self.pixelType = QuickDraw.RGBDirect
|
self.pixelType = QuickDraw.RGBDirect
|
||||||
if format == imgformat.macrgb:
|
if format == imgformat.macrgb:
|
||||||
self.pixelSize = 32
|
self.pixelSize = 32
|
||||||
self.cmpSize = 8
|
self.cmpSize = 8
|
||||||
else:
|
else:
|
||||||
self.pixelSize = 16
|
self.pixelSize = 16
|
||||||
self.cmpSize = 5
|
self.cmpSize = 5
|
||||||
self.rowBytes = width*self.pixelSize/8
|
self.rowBytes = width*self.pixelSize/8
|
||||||
|
|
||||||
def tostring(self, format=imgformat.macrgb):
|
def tostring(self, format=imgformat.macrgb):
|
||||||
"""Return raw data as a string in the specified format."""
|
"""Return raw data as a string in the specified format."""
|
||||||
# is the native format requested? if so, just return data
|
# is the native format requested? if so, just return data
|
||||||
if (format == imgformat.macrgb and self.pixelSize == 32) or \
|
if (format == imgformat.macrgb and self.pixelSize == 32) or \
|
||||||
(format == imgformat.macrgb16 and self.pixelsize == 16):
|
(format == imgformat.macrgb16 and self.pixelsize == 16):
|
||||||
return self.data
|
return self.data
|
||||||
# otherwise, convert to the requested format
|
# otherwise, convert to the requested format
|
||||||
# (LATER!)
|
# (LATER!)
|
||||||
raise "NotImplementedError", "data format conversion"
|
raise "NotImplementedError", "data format conversion"
|
||||||
|
|
||||||
def fromImage(self,im):
|
def fromImage(self,im):
|
||||||
"""Initialize this PixMap from a PIL Image object."""
|
"""Initialize this PixMap from a PIL Image object."""
|
||||||
# We need data in ARGB format; PIL can't currently do that,
|
# We need data in ARGB format; PIL can't currently do that,
|
||||||
# but it can do RGBA, which we can use by inserting one null
|
# but it can do RGBA, which we can use by inserting one null
|
||||||
# up frontpm =
|
# up frontpm =
|
||||||
if im.mode != 'RGBA': im = im.convert('RGBA')
|
if im.mode != 'RGBA': im = im.convert('RGBA')
|
||||||
data = chr(0) + im.tostring()
|
data = chr(0) + im.tostring()
|
||||||
self.fromstring(data, im.size[0], im.size[1])
|
self.fromstring(data, im.size[0], im.size[1])
|
||||||
|
|
||||||
def toImage(self):
|
def toImage(self):
|
||||||
"""Return the contents of this PixMap as a PIL Image object."""
|
"""Return the contents of this PixMap as a PIL Image object."""
|
||||||
import Image
|
import Image
|
||||||
# our tostring() method returns data in ARGB format,
|
# our tostring() method returns data in ARGB format,
|
||||||
# whereas Image uses RGBA; a bit of slicing fixes this...
|
# whereas Image uses RGBA; a bit of slicing fixes this...
|
||||||
data = self.tostring()[1:] + chr(0)
|
data = self.tostring()[1:] + chr(0)
|
||||||
bounds = self.bounds
|
bounds = self.bounds
|
||||||
return Image.fromstring('RGBA',(bounds[2]-bounds[0],bounds[3]-bounds[1]),data)
|
return Image.fromstring('RGBA',(bounds[2]-bounds[0],bounds[3]-bounds[1]),data)
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
import MacOS
|
import MacOS
|
||||||
import EasyDialogs
|
import EasyDialogs
|
||||||
import Image
|
import Image
|
||||||
path = EasyDialogs.AskFileForOpen("Image File:")
|
path = EasyDialogs.AskFileForOpen("Image File:")
|
||||||
if not path: return
|
if not path: return
|
||||||
pm = PixMapWrapper()
|
pm = PixMapWrapper()
|
||||||
pm.fromImage( Image.open(path) )
|
pm.fromImage( Image.open(path) )
|
||||||
pm.blit(20,20)
|
pm.blit(20,20)
|
||||||
return pm
|
return pm
|
||||||
|
|
||||||
|
|
|
@ -44,15 +44,15 @@ import os
|
||||||
# we like better (and which is equivalent)
|
# we like better (and which is equivalent)
|
||||||
#
|
#
|
||||||
unpacker_coercions = {
|
unpacker_coercions = {
|
||||||
typeComp : typeFloat,
|
typeComp : typeFloat,
|
||||||
typeColorTable : typeAEList,
|
typeColorTable : typeAEList,
|
||||||
typeDrawingArea : typeAERecord,
|
typeDrawingArea : typeAERecord,
|
||||||
typeFixed : typeFloat,
|
typeFixed : typeFloat,
|
||||||
typeExtended : typeFloat,
|
typeExtended : typeFloat,
|
||||||
typePixelMap : typeAERecord,
|
typePixelMap : typeAERecord,
|
||||||
typeRotation : typeAERecord,
|
typeRotation : typeAERecord,
|
||||||
typeStyledText : typeAERecord,
|
typeStyledText : typeAERecord,
|
||||||
typeTextStyles : typeAERecord,
|
typeTextStyles : typeAERecord,
|
||||||
};
|
};
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -64,303 +64,303 @@ FSRefType = Carbon.File.FSRefType
|
||||||
AliasType = Carbon.File.AliasType
|
AliasType = Carbon.File.AliasType
|
||||||
|
|
||||||
def packkey(ae, key, value):
|
def packkey(ae, key, value):
|
||||||
if hasattr(key, 'which'):
|
if hasattr(key, 'which'):
|
||||||
keystr = key.which
|
keystr = key.which
|
||||||
elif hasattr(key, 'want'):
|
elif hasattr(key, 'want'):
|
||||||
keystr = key.want
|
keystr = key.want
|
||||||
else:
|
else:
|
||||||
keystr = key
|
keystr = key
|
||||||
ae.AEPutParamDesc(keystr, pack(value))
|
ae.AEPutParamDesc(keystr, pack(value))
|
||||||
|
|
||||||
def pack(x, forcetype = None):
|
def pack(x, forcetype = None):
|
||||||
"""Pack a python object into an AE descriptor"""
|
"""Pack a python object into an AE descriptor"""
|
||||||
|
|
||||||
if forcetype:
|
if forcetype:
|
||||||
if type(x) is StringType:
|
if type(x) is StringType:
|
||||||
return AE.AECreateDesc(forcetype, x)
|
return AE.AECreateDesc(forcetype, x)
|
||||||
else:
|
else:
|
||||||
return pack(x).AECoerceDesc(forcetype)
|
return pack(x).AECoerceDesc(forcetype)
|
||||||
|
|
||||||
if x == None:
|
if x == None:
|
||||||
return AE.AECreateDesc('null', '')
|
return AE.AECreateDesc('null', '')
|
||||||
|
|
||||||
if isinstance(x, AEDescType):
|
if isinstance(x, AEDescType):
|
||||||
return x
|
return x
|
||||||
if isinstance(x, FSSType):
|
if isinstance(x, FSSType):
|
||||||
return AE.AECreateDesc('fss ', x.data)
|
return AE.AECreateDesc('fss ', x.data)
|
||||||
if isinstance(x, FSRefType):
|
if isinstance(x, FSRefType):
|
||||||
return AE.AECreateDesc('fsrf', x.data)
|
return AE.AECreateDesc('fsrf', x.data)
|
||||||
if isinstance(x, AliasType):
|
if isinstance(x, AliasType):
|
||||||
return AE.AECreateDesc('alis', x.data)
|
return AE.AECreateDesc('alis', x.data)
|
||||||
if isinstance(x, IntType):
|
if isinstance(x, IntType):
|
||||||
return AE.AECreateDesc('long', struct.pack('l', x))
|
return AE.AECreateDesc('long', struct.pack('l', x))
|
||||||
if isinstance(x, FloatType):
|
if isinstance(x, FloatType):
|
||||||
return AE.AECreateDesc('doub', struct.pack('d', x))
|
return AE.AECreateDesc('doub', struct.pack('d', x))
|
||||||
if isinstance(x, StringType):
|
if isinstance(x, StringType):
|
||||||
return AE.AECreateDesc('TEXT', x)
|
return AE.AECreateDesc('TEXT', x)
|
||||||
if isinstance(x, UnicodeType):
|
if isinstance(x, UnicodeType):
|
||||||
data = x.encode('utf16')
|
data = x.encode('utf16')
|
||||||
if data[:2] == '\xfe\xff':
|
if data[:2] == '\xfe\xff':
|
||||||
data = data[2:]
|
data = data[2:]
|
||||||
return AE.AECreateDesc('utxt', data)
|
return AE.AECreateDesc('utxt', data)
|
||||||
if isinstance(x, ListType):
|
if isinstance(x, ListType):
|
||||||
list = AE.AECreateList('', 0)
|
list = AE.AECreateList('', 0)
|
||||||
for item in x:
|
for item in x:
|
||||||
list.AEPutDesc(0, pack(item))
|
list.AEPutDesc(0, pack(item))
|
||||||
return list
|
return list
|
||||||
if isinstance(x, DictionaryType):
|
if isinstance(x, DictionaryType):
|
||||||
record = AE.AECreateList('', 1)
|
record = AE.AECreateList('', 1)
|
||||||
for key, value in x.items():
|
for key, value in x.items():
|
||||||
packkey(record, key, value)
|
packkey(record, key, value)
|
||||||
#record.AEPutParamDesc(key, pack(value))
|
#record.AEPutParamDesc(key, pack(value))
|
||||||
return record
|
return record
|
||||||
if type(x) == types.ClassType and issubclass(x, ObjectSpecifier):
|
if type(x) == types.ClassType and issubclass(x, ObjectSpecifier):
|
||||||
# Note: we are getting a class object here, not an instance
|
# Note: we are getting a class object here, not an instance
|
||||||
return AE.AECreateDesc('type', x.want)
|
return AE.AECreateDesc('type', x.want)
|
||||||
if hasattr(x, '__aepack__'):
|
if hasattr(x, '__aepack__'):
|
||||||
return x.__aepack__()
|
return x.__aepack__()
|
||||||
if hasattr(x, 'which'):
|
if hasattr(x, 'which'):
|
||||||
return AE.AECreateDesc('TEXT', x.which)
|
return AE.AECreateDesc('TEXT', x.which)
|
||||||
if hasattr(x, 'want'):
|
if hasattr(x, 'want'):
|
||||||
return AE.AECreateDesc('TEXT', x.want)
|
return AE.AECreateDesc('TEXT', x.want)
|
||||||
return AE.AECreateDesc('TEXT', repr(x)) # Copout
|
return AE.AECreateDesc('TEXT', repr(x)) # Copout
|
||||||
|
|
||||||
def unpack(desc, formodulename=""):
|
def unpack(desc, formodulename=""):
|
||||||
"""Unpack an AE descriptor to a python object"""
|
"""Unpack an AE descriptor to a python object"""
|
||||||
t = desc.type
|
t = desc.type
|
||||||
|
|
||||||
if unpacker_coercions.has_key(t):
|
if unpacker_coercions.has_key(t):
|
||||||
desc = desc.AECoerceDesc(unpacker_coercions[t])
|
desc = desc.AECoerceDesc(unpacker_coercions[t])
|
||||||
t = desc.type # This is a guess by Jack....
|
t = desc.type # This is a guess by Jack....
|
||||||
|
|
||||||
if t == typeAEList:
|
if t == typeAEList:
|
||||||
l = []
|
l = []
|
||||||
for i in range(desc.AECountItems()):
|
for i in range(desc.AECountItems()):
|
||||||
keyword, item = desc.AEGetNthDesc(i+1, '****')
|
keyword, item = desc.AEGetNthDesc(i+1, '****')
|
||||||
l.append(unpack(item, formodulename))
|
l.append(unpack(item, formodulename))
|
||||||
return l
|
return l
|
||||||
if t == typeAERecord:
|
if t == typeAERecord:
|
||||||
d = {}
|
d = {}
|
||||||
for i in range(desc.AECountItems()):
|
for i in range(desc.AECountItems()):
|
||||||
keyword, item = desc.AEGetNthDesc(i+1, '****')
|
keyword, item = desc.AEGetNthDesc(i+1, '****')
|
||||||
d[keyword] = unpack(item, formodulename)
|
d[keyword] = unpack(item, formodulename)
|
||||||
return d
|
return d
|
||||||
if t == typeAEText:
|
if t == typeAEText:
|
||||||
record = desc.AECoerceDesc('reco')
|
record = desc.AECoerceDesc('reco')
|
||||||
return mkaetext(unpack(record, formodulename))
|
return mkaetext(unpack(record, formodulename))
|
||||||
if t == typeAlias:
|
if t == typeAlias:
|
||||||
return Carbon.File.Alias(rawdata=desc.data)
|
return Carbon.File.Alias(rawdata=desc.data)
|
||||||
# typeAppleEvent returned as unknown
|
# typeAppleEvent returned as unknown
|
||||||
if t == typeBoolean:
|
if t == typeBoolean:
|
||||||
return struct.unpack('b', desc.data)[0]
|
return struct.unpack('b', desc.data)[0]
|
||||||
if t == typeChar:
|
if t == typeChar:
|
||||||
return desc.data
|
return desc.data
|
||||||
if t == typeUnicodeText:
|
if t == typeUnicodeText:
|
||||||
return unicode(desc.data, 'utf16')
|
return unicode(desc.data, 'utf16')
|
||||||
# typeColorTable coerced to typeAEList
|
# typeColorTable coerced to typeAEList
|
||||||
# typeComp coerced to extended
|
# typeComp coerced to extended
|
||||||
# typeData returned as unknown
|
# typeData returned as unknown
|
||||||
# typeDrawingArea coerced to typeAERecord
|
# typeDrawingArea coerced to typeAERecord
|
||||||
if t == typeEnumeration:
|
if t == typeEnumeration:
|
||||||
return mkenum(desc.data)
|
return mkenum(desc.data)
|
||||||
# typeEPS returned as unknown
|
# typeEPS returned as unknown
|
||||||
if t == typeFalse:
|
if t == typeFalse:
|
||||||
return 0
|
return 0
|
||||||
if t == typeFloat:
|
if t == typeFloat:
|
||||||
data = desc.data
|
data = desc.data
|
||||||
return struct.unpack('d', data)[0]
|
return struct.unpack('d', data)[0]
|
||||||
if t == typeFSS:
|
if t == typeFSS:
|
||||||
return Carbon.File.FSSpec(rawdata=desc.data)
|
return Carbon.File.FSSpec(rawdata=desc.data)
|
||||||
if t == typeFSRef:
|
if t == typeFSRef:
|
||||||
return Carbon.File.FSRef(rawdata=desc.data)
|
return Carbon.File.FSRef(rawdata=desc.data)
|
||||||
if t == typeInsertionLoc:
|
if t == typeInsertionLoc:
|
||||||
record = desc.AECoerceDesc('reco')
|
record = desc.AECoerceDesc('reco')
|
||||||
return mkinsertionloc(unpack(record, formodulename))
|
return mkinsertionloc(unpack(record, formodulename))
|
||||||
# typeInteger equal to typeLongInteger
|
# typeInteger equal to typeLongInteger
|
||||||
if t == typeIntlText:
|
if t == typeIntlText:
|
||||||
script, language = struct.unpack('hh', desc.data[:4])
|
script, language = struct.unpack('hh', desc.data[:4])
|
||||||
return aetypes.IntlText(script, language, desc.data[4:])
|
return aetypes.IntlText(script, language, desc.data[4:])
|
||||||
if t == typeIntlWritingCode:
|
if t == typeIntlWritingCode:
|
||||||
script, language = struct.unpack('hh', desc.data)
|
script, language = struct.unpack('hh', desc.data)
|
||||||
return aetypes.IntlWritingCode(script, language)
|
return aetypes.IntlWritingCode(script, language)
|
||||||
if t == typeKeyword:
|
if t == typeKeyword:
|
||||||
return mkkeyword(desc.data)
|
return mkkeyword(desc.data)
|
||||||
if t == typeLongInteger:
|
if t == typeLongInteger:
|
||||||
return struct.unpack('l', desc.data)[0]
|
return struct.unpack('l', desc.data)[0]
|
||||||
if t == typeLongDateTime:
|
if t == typeLongDateTime:
|
||||||
a, b = struct.unpack('lL', desc.data)
|
a, b = struct.unpack('lL', desc.data)
|
||||||
return (long(a) << 32) + b
|
return (long(a) << 32) + b
|
||||||
if t == typeNull:
|
if t == typeNull:
|
||||||
return None
|
return None
|
||||||
if t == typeMagnitude:
|
if t == typeMagnitude:
|
||||||
v = struct.unpack('l', desc.data)
|
v = struct.unpack('l', desc.data)
|
||||||
if v < 0:
|
if v < 0:
|
||||||
v = 0x100000000L + v
|
v = 0x100000000L + v
|
||||||
return v
|
return v
|
||||||
if t == typeObjectSpecifier:
|
if t == typeObjectSpecifier:
|
||||||
record = desc.AECoerceDesc('reco')
|
record = desc.AECoerceDesc('reco')
|
||||||
# If we have been told the name of the module we are unpacking aedescs for,
|
# If we have been told the name of the module we are unpacking aedescs for,
|
||||||
# we can attempt to create the right type of python object from that module.
|
# we can attempt to create the right type of python object from that module.
|
||||||
if formodulename:
|
if formodulename:
|
||||||
return mkobjectfrommodule(unpack(record, formodulename), formodulename)
|
return mkobjectfrommodule(unpack(record, formodulename), formodulename)
|
||||||
return mkobject(unpack(record, formodulename))
|
return mkobject(unpack(record, formodulename))
|
||||||
# typePict returned as unknown
|
# typePict returned as unknown
|
||||||
# typePixelMap coerced to typeAERecord
|
# typePixelMap coerced to typeAERecord
|
||||||
# typePixelMapMinus returned as unknown
|
# typePixelMapMinus returned as unknown
|
||||||
# typeProcessSerialNumber returned as unknown
|
# typeProcessSerialNumber returned as unknown
|
||||||
if t == typeQDPoint:
|
if t == typeQDPoint:
|
||||||
v, h = struct.unpack('hh', desc.data)
|
v, h = struct.unpack('hh', desc.data)
|
||||||
return aetypes.QDPoint(v, h)
|
return aetypes.QDPoint(v, h)
|
||||||
if t == typeQDRectangle:
|
if t == typeQDRectangle:
|
||||||
v0, h0, v1, h1 = struct.unpack('hhhh', desc.data)
|
v0, h0, v1, h1 = struct.unpack('hhhh', desc.data)
|
||||||
return aetypes.QDRectangle(v0, h0, v1, h1)
|
return aetypes.QDRectangle(v0, h0, v1, h1)
|
||||||
if t == typeRGBColor:
|
if t == typeRGBColor:
|
||||||
r, g, b = struct.unpack('hhh', desc.data)
|
r, g, b = struct.unpack('hhh', desc.data)
|
||||||
return aetypes.RGBColor(r, g, b)
|
return aetypes.RGBColor(r, g, b)
|
||||||
# typeRotation coerced to typeAERecord
|
# typeRotation coerced to typeAERecord
|
||||||
# typeScrapStyles returned as unknown
|
# typeScrapStyles returned as unknown
|
||||||
# typeSessionID returned as unknown
|
# typeSessionID returned as unknown
|
||||||
if t == typeShortFloat:
|
if t == typeShortFloat:
|
||||||
return struct.unpack('f', desc.data)[0]
|
return struct.unpack('f', desc.data)[0]
|
||||||
if t == typeShortInteger:
|
if t == typeShortInteger:
|
||||||
return struct.unpack('h', desc.data)[0]
|
return struct.unpack('h', desc.data)[0]
|
||||||
# typeSMFloat identical to typeShortFloat
|
# typeSMFloat identical to typeShortFloat
|
||||||
# typeSMInt indetical to typeShortInt
|
# typeSMInt indetical to typeShortInt
|
||||||
# typeStyledText coerced to typeAERecord
|
# typeStyledText coerced to typeAERecord
|
||||||
if t == typeTargetID:
|
if t == typeTargetID:
|
||||||
return mktargetid(desc.data)
|
return mktargetid(desc.data)
|
||||||
# typeTextStyles coerced to typeAERecord
|
# typeTextStyles coerced to typeAERecord
|
||||||
# typeTIFF returned as unknown
|
# typeTIFF returned as unknown
|
||||||
if t == typeTrue:
|
if t == typeTrue:
|
||||||
return 1
|
return 1
|
||||||
if t == typeType:
|
if t == typeType:
|
||||||
return mktype(desc.data, formodulename)
|
return mktype(desc.data, formodulename)
|
||||||
#
|
#
|
||||||
# The following are special
|
# The following are special
|
||||||
#
|
#
|
||||||
if t == 'rang':
|
if t == 'rang':
|
||||||
record = desc.AECoerceDesc('reco')
|
record = desc.AECoerceDesc('reco')
|
||||||
return mkrange(unpack(record, formodulename))
|
return mkrange(unpack(record, formodulename))
|
||||||
if t == 'cmpd':
|
if t == 'cmpd':
|
||||||
record = desc.AECoerceDesc('reco')
|
record = desc.AECoerceDesc('reco')
|
||||||
return mkcomparison(unpack(record, formodulename))
|
return mkcomparison(unpack(record, formodulename))
|
||||||
if t == 'logi':
|
if t == 'logi':
|
||||||
record = desc.AECoerceDesc('reco')
|
record = desc.AECoerceDesc('reco')
|
||||||
return mklogical(unpack(record, formodulename))
|
return mklogical(unpack(record, formodulename))
|
||||||
return mkunknown(desc.type, desc.data)
|
return mkunknown(desc.type, desc.data)
|
||||||
|
|
||||||
def coerce(data, egdata):
|
def coerce(data, egdata):
|
||||||
"""Coerce a python object to another type using the AE coercers"""
|
"""Coerce a python object to another type using the AE coercers"""
|
||||||
pdata = pack(data)
|
pdata = pack(data)
|
||||||
pegdata = pack(egdata)
|
pegdata = pack(egdata)
|
||||||
pdata = pdata.AECoerceDesc(pegdata.type)
|
pdata = pdata.AECoerceDesc(pegdata.type)
|
||||||
return unpack(pdata)
|
return unpack(pdata)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Helper routines for unpack
|
# Helper routines for unpack
|
||||||
#
|
#
|
||||||
def mktargetid(data):
|
def mktargetid(data):
|
||||||
sessionID = getlong(data[:4])
|
sessionID = getlong(data[:4])
|
||||||
name = mkppcportrec(data[4:4+72])
|
name = mkppcportrec(data[4:4+72])
|
||||||
location = mklocationnamerec(data[76:76+36])
|
location = mklocationnamerec(data[76:76+36])
|
||||||
rcvrName = mkppcportrec(data[112:112+72])
|
rcvrName = mkppcportrec(data[112:112+72])
|
||||||
return sessionID, name, location, rcvrName
|
return sessionID, name, location, rcvrName
|
||||||
|
|
||||||
def mkppcportrec(rec):
|
def mkppcportrec(rec):
|
||||||
namescript = getword(rec[:2])
|
namescript = getword(rec[:2])
|
||||||
name = getpstr(rec[2:2+33])
|
name = getpstr(rec[2:2+33])
|
||||||
portkind = getword(rec[36:38])
|
portkind = getword(rec[36:38])
|
||||||
if portkind == 1:
|
if portkind == 1:
|
||||||
ctor = rec[38:42]
|
ctor = rec[38:42]
|
||||||
type = rec[42:46]
|
type = rec[42:46]
|
||||||
identity = (ctor, type)
|
identity = (ctor, type)
|
||||||
else:
|
else:
|
||||||
identity = getpstr(rec[38:38+33])
|
identity = getpstr(rec[38:38+33])
|
||||||
return namescript, name, portkind, identity
|
return namescript, name, portkind, identity
|
||||||
|
|
||||||
def mklocationnamerec(rec):
|
def mklocationnamerec(rec):
|
||||||
kind = getword(rec[:2])
|
kind = getword(rec[:2])
|
||||||
stuff = rec[2:]
|
stuff = rec[2:]
|
||||||
if kind == 0: stuff = None
|
if kind == 0: stuff = None
|
||||||
if kind == 2: stuff = getpstr(stuff)
|
if kind == 2: stuff = getpstr(stuff)
|
||||||
return kind, stuff
|
return kind, stuff
|
||||||
|
|
||||||
def mkunknown(type, data):
|
def mkunknown(type, data):
|
||||||
return aetypes.Unknown(type, data)
|
return aetypes.Unknown(type, data)
|
||||||
|
|
||||||
def getpstr(s):
|
def getpstr(s):
|
||||||
return s[1:1+ord(s[0])]
|
return s[1:1+ord(s[0])]
|
||||||
|
|
||||||
def getlong(s):
|
def getlong(s):
|
||||||
return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
|
return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
|
||||||
|
|
||||||
def getword(s):
|
def getword(s):
|
||||||
return (ord(s[0])<<8) | (ord(s[1])<<0)
|
return (ord(s[0])<<8) | (ord(s[1])<<0)
|
||||||
|
|
||||||
def mkkeyword(keyword):
|
def mkkeyword(keyword):
|
||||||
return aetypes.Keyword(keyword)
|
return aetypes.Keyword(keyword)
|
||||||
|
|
||||||
def mkrange(dict):
|
def mkrange(dict):
|
||||||
return aetypes.Range(dict['star'], dict['stop'])
|
return aetypes.Range(dict['star'], dict['stop'])
|
||||||
|
|
||||||
def mkcomparison(dict):
|
def mkcomparison(dict):
|
||||||
return aetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])
|
return aetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])
|
||||||
|
|
||||||
def mklogical(dict):
|
def mklogical(dict):
|
||||||
return aetypes.Logical(dict['logc'], dict['term'])
|
return aetypes.Logical(dict['logc'], dict['term'])
|
||||||
|
|
||||||
def mkstyledtext(dict):
|
def mkstyledtext(dict):
|
||||||
return aetypes.StyledText(dict['ksty'], dict['ktxt'])
|
return aetypes.StyledText(dict['ksty'], dict['ktxt'])
|
||||||
|
|
||||||
def mkaetext(dict):
|
def mkaetext(dict):
|
||||||
return aetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText])
|
return aetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText])
|
||||||
|
|
||||||
def mkinsertionloc(dict):
|
def mkinsertionloc(dict):
|
||||||
return aetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition])
|
return aetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition])
|
||||||
|
|
||||||
def mkobject(dict):
|
def mkobject(dict):
|
||||||
want = dict['want'].type
|
want = dict['want'].type
|
||||||
form = dict['form'].enum
|
form = dict['form'].enum
|
||||||
seld = dict['seld']
|
seld = dict['seld']
|
||||||
fr = dict['from']
|
fr = dict['from']
|
||||||
if form in ('name', 'indx', 'rang', 'test'):
|
if form in ('name', 'indx', 'rang', 'test'):
|
||||||
if want == 'text': return aetypes.Text(seld, fr)
|
if want == 'text': return aetypes.Text(seld, fr)
|
||||||
if want == 'cha ': return aetypes.Character(seld, fr)
|
if want == 'cha ': return aetypes.Character(seld, fr)
|
||||||
if want == 'cwor': return aetypes.Word(seld, fr)
|
if want == 'cwor': return aetypes.Word(seld, fr)
|
||||||
if want == 'clin': return aetypes.Line(seld, fr)
|
if want == 'clin': return aetypes.Line(seld, fr)
|
||||||
if want == 'cpar': return aetypes.Paragraph(seld, fr)
|
if want == 'cpar': return aetypes.Paragraph(seld, fr)
|
||||||
if want == 'cwin': return aetypes.Window(seld, fr)
|
if want == 'cwin': return aetypes.Window(seld, fr)
|
||||||
if want == 'docu': return aetypes.Document(seld, fr)
|
if want == 'docu': return aetypes.Document(seld, fr)
|
||||||
if want == 'file': return aetypes.File(seld, fr)
|
if want == 'file': return aetypes.File(seld, fr)
|
||||||
if want == 'cins': return aetypes.InsertionPoint(seld, fr)
|
if want == 'cins': return aetypes.InsertionPoint(seld, fr)
|
||||||
if want == 'prop' and form == 'prop' and aetypes.IsType(seld):
|
if want == 'prop' and form == 'prop' and aetypes.IsType(seld):
|
||||||
return aetypes.Property(seld.type, fr)
|
return aetypes.Property(seld.type, fr)
|
||||||
return aetypes.ObjectSpecifier(want, form, seld, fr)
|
return aetypes.ObjectSpecifier(want, form, seld, fr)
|
||||||
|
|
||||||
# Note by Jack: I'm not 100% sure of the following code. This was
|
# Note by Jack: I'm not 100% sure of the following code. This was
|
||||||
# provided by Donovan Preston, but I wonder whether the assignment
|
# provided by Donovan Preston, but I wonder whether the assignment
|
||||||
# to __class__ is safe. Moreover, shouldn't there be a better
|
# to __class__ is safe. Moreover, shouldn't there be a better
|
||||||
# initializer for the classes in the suites?
|
# initializer for the classes in the suites?
|
||||||
def mkobjectfrommodule(dict, modulename):
|
def mkobjectfrommodule(dict, modulename):
|
||||||
if type(dict['want']) == types.ClassType and issubclass(dict['want'], ObjectSpecifier):
|
if type(dict['want']) == types.ClassType and issubclass(dict['want'], ObjectSpecifier):
|
||||||
# The type has already been converted to Python. Convert back:-(
|
# The type has already been converted to Python. Convert back:-(
|
||||||
classtype = dict['want']
|
classtype = dict['want']
|
||||||
dict['want'] = aetypes.mktype(classtype.want)
|
dict['want'] = aetypes.mktype(classtype.want)
|
||||||
want = dict['want'].type
|
want = dict['want'].type
|
||||||
module = __import__(modulename)
|
module = __import__(modulename)
|
||||||
codenamemapper = module._classdeclarations
|
codenamemapper = module._classdeclarations
|
||||||
classtype = codenamemapper.get(want, None)
|
classtype = codenamemapper.get(want, None)
|
||||||
newobj = mkobject(dict)
|
newobj = mkobject(dict)
|
||||||
if classtype:
|
if classtype:
|
||||||
assert issubclass(classtype, ObjectSpecifier)
|
assert issubclass(classtype, ObjectSpecifier)
|
||||||
newobj.__class__ = classtype
|
newobj.__class__ = classtype
|
||||||
return newobj
|
return newobj
|
||||||
|
|
||||||
def mktype(typecode, modulename=None):
|
def mktype(typecode, modulename=None):
|
||||||
if modulename:
|
if modulename:
|
||||||
module = __import__(modulename)
|
module = __import__(modulename)
|
||||||
codenamemapper = module._classdeclarations
|
codenamemapper = module._classdeclarations
|
||||||
classtype = codenamemapper.get(typecode, None)
|
classtype = codenamemapper.get(typecode, None)
|
||||||
if classtype:
|
if classtype:
|
||||||
return classtype
|
return classtype
|
||||||
return aetypes.mktype(typecode)
|
return aetypes.mktype(typecode)
|
||||||
|
|
|
@ -9,11 +9,11 @@ unpackevent(event) returns the parameters and attributes from an AEAppleEvent re
|
||||||
Plus... Lots of classes and routines that help representing AE objects,
|
Plus... Lots of classes and routines that help representing AE objects,
|
||||||
ranges, conditionals, logicals, etc., so you can write, e.g.:
|
ranges, conditionals, logicals, etc., so you can write, e.g.:
|
||||||
|
|
||||||
x = Character(1, Document("foobar"))
|
x = Character(1, Document("foobar"))
|
||||||
|
|
||||||
and pack(x) will create an AE object reference equivalent to AppleScript's
|
and pack(x) will create an AE object reference equivalent to AppleScript's
|
||||||
|
|
||||||
character 1 of document "foobar"
|
character 1 of document "foobar"
|
||||||
|
|
||||||
Some of the stuff that appears to be exported from this module comes from other
|
Some of the stuff that appears to be exported from this module comes from other
|
||||||
files: the pack stuff from aepack, the objects from aetypes.
|
files: the pack stuff from aepack, the objects from aetypes.
|
||||||
|
@ -41,283 +41,283 @@ LAUNCH_MAX_WAIT_TIME=10
|
||||||
# Note by Jack: No??!? If I read the docs correctly it *is*....
|
# Note by Jack: No??!? If I read the docs correctly it *is*....
|
||||||
|
|
||||||
aekeywords = [
|
aekeywords = [
|
||||||
'tran',
|
'tran',
|
||||||
'rtid',
|
'rtid',
|
||||||
'evcl',
|
'evcl',
|
||||||
'evid',
|
'evid',
|
||||||
'addr',
|
'addr',
|
||||||
'optk',
|
'optk',
|
||||||
'timo',
|
'timo',
|
||||||
'inte', # this attribute is read only - will be set in AESend
|
'inte', # this attribute is read only - will be set in AESend
|
||||||
'esrc', # this attribute is read only
|
'esrc', # this attribute is read only
|
||||||
'miss', # this attribute is read only
|
'miss', # this attribute is read only
|
||||||
'from' # new in 1.0.1
|
'from' # new in 1.0.1
|
||||||
]
|
]
|
||||||
|
|
||||||
def missed(ae):
|
def missed(ae):
|
||||||
try:
|
try:
|
||||||
desc = ae.AEGetAttributeDesc('miss', 'keyw')
|
desc = ae.AEGetAttributeDesc('miss', 'keyw')
|
||||||
except AE.Error, msg:
|
except AE.Error, msg:
|
||||||
return None
|
return None
|
||||||
return desc.data
|
return desc.data
|
||||||
|
|
||||||
def unpackevent(ae, formodulename=""):
|
def unpackevent(ae, formodulename=""):
|
||||||
parameters = {}
|
parameters = {}
|
||||||
try:
|
try:
|
||||||
dirobj = ae.AEGetParamDesc('----', '****')
|
dirobj = ae.AEGetParamDesc('----', '****')
|
||||||
except AE.Error:
|
except AE.Error:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
parameters['----'] = unpack(dirobj, formodulename)
|
parameters['----'] = unpack(dirobj, formodulename)
|
||||||
del dirobj
|
del dirobj
|
||||||
# Workaround for what I feel is a bug in OSX 10.2: 'errn' won't show up in missed...
|
# Workaround for what I feel is a bug in OSX 10.2: 'errn' won't show up in missed...
|
||||||
try:
|
try:
|
||||||
dirobj = ae.AEGetParamDesc('errn', '****')
|
dirobj = ae.AEGetParamDesc('errn', '****')
|
||||||
except AE.Error:
|
except AE.Error:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
parameters['errn'] = unpack(dirobj, formodulename)
|
parameters['errn'] = unpack(dirobj, formodulename)
|
||||||
del dirobj
|
del dirobj
|
||||||
while 1:
|
while 1:
|
||||||
key = missed(ae)
|
key = missed(ae)
|
||||||
if not key: break
|
if not key: break
|
||||||
parameters[key] = unpack(ae.AEGetParamDesc(key, '****'), formodulename)
|
parameters[key] = unpack(ae.AEGetParamDesc(key, '****'), formodulename)
|
||||||
attributes = {}
|
attributes = {}
|
||||||
for key in aekeywords:
|
for key in aekeywords:
|
||||||
try:
|
try:
|
||||||
desc = ae.AEGetAttributeDesc(key, '****')
|
desc = ae.AEGetAttributeDesc(key, '****')
|
||||||
except (AE.Error, MacOS.Error), msg:
|
except (AE.Error, MacOS.Error), msg:
|
||||||
if msg[0] != -1701 and msg[0] != -1704:
|
if msg[0] != -1701 and msg[0] != -1704:
|
||||||
raise
|
raise
|
||||||
continue
|
continue
|
||||||
attributes[key] = unpack(desc, formodulename)
|
attributes[key] = unpack(desc, formodulename)
|
||||||
return parameters, attributes
|
return parameters, attributes
|
||||||
|
|
||||||
def packevent(ae, parameters = {}, attributes = {}):
|
def packevent(ae, parameters = {}, attributes = {}):
|
||||||
for key, value in parameters.items():
|
for key, value in parameters.items():
|
||||||
packkey(ae, key, value)
|
packkey(ae, key, value)
|
||||||
for key, value in attributes.items():
|
for key, value in attributes.items():
|
||||||
ae.AEPutAttributeDesc(key, pack(value))
|
ae.AEPutAttributeDesc(key, pack(value))
|
||||||
|
|
||||||
#
|
#
|
||||||
# Support routine for automatically generated Suite interfaces
|
# Support routine for automatically generated Suite interfaces
|
||||||
# These routines are also useable for the reverse function.
|
# These routines are also useable for the reverse function.
|
||||||
#
|
#
|
||||||
def keysubst(arguments, keydict):
|
def keysubst(arguments, keydict):
|
||||||
"""Replace long name keys by their 4-char counterparts, and check"""
|
"""Replace long name keys by their 4-char counterparts, and check"""
|
||||||
ok = keydict.values()
|
ok = keydict.values()
|
||||||
for k in arguments.keys():
|
for k in arguments.keys():
|
||||||
if keydict.has_key(k):
|
if keydict.has_key(k):
|
||||||
v = arguments[k]
|
v = arguments[k]
|
||||||
del arguments[k]
|
del arguments[k]
|
||||||
arguments[keydict[k]] = v
|
arguments[keydict[k]] = v
|
||||||
elif k != '----' and k not in ok:
|
elif k != '----' and k not in ok:
|
||||||
raise TypeError, 'Unknown keyword argument: %s'%k
|
raise TypeError, 'Unknown keyword argument: %s'%k
|
||||||
|
|
||||||
def enumsubst(arguments, key, edict):
|
def enumsubst(arguments, key, edict):
|
||||||
"""Substitute a single enum keyword argument, if it occurs"""
|
"""Substitute a single enum keyword argument, if it occurs"""
|
||||||
if not arguments.has_key(key) or edict is None:
|
if not arguments.has_key(key) or edict is None:
|
||||||
return
|
return
|
||||||
v = arguments[key]
|
v = arguments[key]
|
||||||
ok = edict.values()
|
ok = edict.values()
|
||||||
if edict.has_key(v):
|
if edict.has_key(v):
|
||||||
arguments[key] = Enum(edict[v])
|
arguments[key] = Enum(edict[v])
|
||||||
elif not v in ok:
|
elif not v in ok:
|
||||||
raise TypeError, 'Unknown enumerator: %s'%v
|
raise TypeError, 'Unknown enumerator: %s'%v
|
||||||
|
|
||||||
def decodeerror(arguments):
|
def decodeerror(arguments):
|
||||||
"""Create the 'best' argument for a raise MacOS.Error"""
|
"""Create the 'best' argument for a raise MacOS.Error"""
|
||||||
errn = arguments['errn']
|
errn = arguments['errn']
|
||||||
err_a1 = errn
|
err_a1 = errn
|
||||||
if arguments.has_key('errs'):
|
if arguments.has_key('errs'):
|
||||||
err_a2 = arguments['errs']
|
err_a2 = arguments['errs']
|
||||||
else:
|
else:
|
||||||
err_a2 = MacOS.GetErrorString(errn)
|
err_a2 = MacOS.GetErrorString(errn)
|
||||||
if arguments.has_key('erob'):
|
if arguments.has_key('erob'):
|
||||||
err_a3 = arguments['erob']
|
err_a3 = arguments['erob']
|
||||||
else:
|
else:
|
||||||
err_a3 = None
|
err_a3 = None
|
||||||
|
|
||||||
return (err_a1, err_a2, err_a3)
|
return (err_a1, err_a2, err_a3)
|
||||||
|
|
||||||
class TalkTo:
|
class TalkTo:
|
||||||
"""An AE connection to an application"""
|
"""An AE connection to an application"""
|
||||||
_signature = None # Can be overridden by subclasses
|
_signature = None # Can be overridden by subclasses
|
||||||
_moduleName = None # Can be overridden by subclasses
|
_moduleName = None # Can be overridden by subclasses
|
||||||
|
|
||||||
__eventloop_initialized = 0
|
__eventloop_initialized = 0
|
||||||
def __ensure_WMAvailable(klass):
|
def __ensure_WMAvailable(klass):
|
||||||
if klass.__eventloop_initialized: return 1
|
if klass.__eventloop_initialized: return 1
|
||||||
if not MacOS.WMAvailable(): return 0
|
if not MacOS.WMAvailable(): return 0
|
||||||
# Workaround for a but in MacOSX 10.2: we must have an event
|
# Workaround for a but in MacOSX 10.2: we must have an event
|
||||||
# loop before we can call AESend.
|
# loop before we can call AESend.
|
||||||
Evt.WaitNextEvent(0,0)
|
Evt.WaitNextEvent(0,0)
|
||||||
return 1
|
return 1
|
||||||
__ensure_WMAvailable = classmethod(__ensure_WMAvailable)
|
__ensure_WMAvailable = classmethod(__ensure_WMAvailable)
|
||||||
|
|
||||||
def __init__(self, signature=None, start=0, timeout=0):
|
def __init__(self, signature=None, start=0, timeout=0):
|
||||||
"""Create a communication channel with a particular application.
|
"""Create a communication channel with a particular application.
|
||||||
|
|
||||||
Addressing the application is done by specifying either a
|
Addressing the application is done by specifying either a
|
||||||
4-byte signature, an AEDesc or an object that will __aepack__
|
4-byte signature, an AEDesc or an object that will __aepack__
|
||||||
to an AEDesc.
|
to an AEDesc.
|
||||||
"""
|
"""
|
||||||
self.target_signature = None
|
self.target_signature = None
|
||||||
if signature is None:
|
if signature is None:
|
||||||
signature = self._signature
|
signature = self._signature
|
||||||
if type(signature) == AEDescType:
|
if type(signature) == AEDescType:
|
||||||
self.target = signature
|
self.target = signature
|
||||||
elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
|
elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
|
||||||
self.target = signature.__aepack__()
|
self.target = signature.__aepack__()
|
||||||
elif type(signature) == StringType and len(signature) == 4:
|
elif type(signature) == StringType and len(signature) == 4:
|
||||||
self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
|
self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
|
||||||
self.target_signature = signature
|
self.target_signature = signature
|
||||||
else:
|
else:
|
||||||
raise TypeError, "signature should be 4-char string or AEDesc"
|
raise TypeError, "signature should be 4-char string or AEDesc"
|
||||||
self.send_flags = AppleEvents.kAEWaitReply
|
self.send_flags = AppleEvents.kAEWaitReply
|
||||||
self.send_priority = AppleEvents.kAENormalPriority
|
self.send_priority = AppleEvents.kAENormalPriority
|
||||||
if timeout:
|
if timeout:
|
||||||
self.send_timeout = timeout
|
self.send_timeout = timeout
|
||||||
else:
|
else:
|
||||||
self.send_timeout = AppleEvents.kAEDefaultTimeout
|
self.send_timeout = AppleEvents.kAEDefaultTimeout
|
||||||
if start:
|
if start:
|
||||||
self._start()
|
self._start()
|
||||||
|
|
||||||
def _start(self):
|
def _start(self):
|
||||||
"""Start the application, if it is not running yet"""
|
"""Start the application, if it is not running yet"""
|
||||||
try:
|
try:
|
||||||
self.send('ascr', 'noop')
|
self.send('ascr', 'noop')
|
||||||
except AE.Error:
|
except AE.Error:
|
||||||
_launch(self.target_signature)
|
_launch(self.target_signature)
|
||||||
for i in range(LAUNCH_MAX_WAIT_TIME):
|
for i in range(LAUNCH_MAX_WAIT_TIME):
|
||||||
try:
|
try:
|
||||||
self.send('ascr', 'noop')
|
self.send('ascr', 'noop')
|
||||||
except AE.Error:
|
except AE.Error:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Deprecated, used _start()"""
|
"""Deprecated, used _start()"""
|
||||||
self._start()
|
self._start()
|
||||||
|
|
||||||
def newevent(self, code, subcode, parameters = {}, attributes = {}):
|
def newevent(self, code, subcode, parameters = {}, attributes = {}):
|
||||||
"""Create a complete structure for an apple event"""
|
"""Create a complete structure for an apple event"""
|
||||||
|
|
||||||
event = AE.AECreateAppleEvent(code, subcode, self.target,
|
event = AE.AECreateAppleEvent(code, subcode, self.target,
|
||||||
AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
|
AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
|
||||||
packevent(event, parameters, attributes)
|
packevent(event, parameters, attributes)
|
||||||
return event
|
return event
|
||||||
|
|
||||||
def sendevent(self, event):
|
def sendevent(self, event):
|
||||||
"""Send a pre-created appleevent, await the reply and unpack it"""
|
"""Send a pre-created appleevent, await the reply and unpack it"""
|
||||||
if not self.__ensure_WMAvailable():
|
if not self.__ensure_WMAvailable():
|
||||||
raise RuntimeError, "No window manager access, cannot send AppleEvent"
|
raise RuntimeError, "No window manager access, cannot send AppleEvent"
|
||||||
reply = event.AESend(self.send_flags, self.send_priority,
|
reply = event.AESend(self.send_flags, self.send_priority,
|
||||||
self.send_timeout)
|
self.send_timeout)
|
||||||
parameters, attributes = unpackevent(reply, self._moduleName)
|
parameters, attributes = unpackevent(reply, self._moduleName)
|
||||||
return reply, parameters, attributes
|
return reply, parameters, attributes
|
||||||
|
|
||||||
def send(self, code, subcode, parameters = {}, attributes = {}):
|
def send(self, code, subcode, parameters = {}, attributes = {}):
|
||||||
"""Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
|
"""Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
|
||||||
return self.sendevent(self.newevent(code, subcode, parameters, attributes))
|
return self.sendevent(self.newevent(code, subcode, parameters, attributes))
|
||||||
|
|
||||||
#
|
#
|
||||||
# The following events are somehow "standard" and don't seem to appear in any
|
# The following events are somehow "standard" and don't seem to appear in any
|
||||||
# suite...
|
# suite...
|
||||||
#
|
#
|
||||||
def activate(self):
|
def activate(self):
|
||||||
"""Send 'activate' command"""
|
"""Send 'activate' command"""
|
||||||
self.send('misc', 'actv')
|
self.send('misc', 'actv')
|
||||||
|
|
||||||
def _get(self, _object, as=None, _attributes={}):
|
def _get(self, _object, as=None, _attributes={}):
|
||||||
"""_get: get data from an object
|
"""_get: get data from an object
|
||||||
Required argument: the object
|
Required argument: the object
|
||||||
Keyword argument _attributes: AppleEvent attribute dictionary
|
Keyword argument _attributes: AppleEvent attribute dictionary
|
||||||
Returns: the data
|
Returns: the data
|
||||||
"""
|
"""
|
||||||
_code = 'core'
|
_code = 'core'
|
||||||
_subcode = 'getd'
|
_subcode = 'getd'
|
||||||
|
|
||||||
_arguments = {'----':_object}
|
_arguments = {'----':_object}
|
||||||
if as:
|
if as:
|
||||||
_arguments['rtyp'] = mktype(as)
|
_arguments['rtyp'] = mktype(as)
|
||||||
|
|
||||||
_reply, _arguments, _attributes = self.send(_code, _subcode,
|
_reply, _arguments, _attributes = self.send(_code, _subcode,
|
||||||
_arguments, _attributes)
|
_arguments, _attributes)
|
||||||
if _arguments.has_key('errn'):
|
if _arguments.has_key('errn'):
|
||||||
raise Error, decodeerror(_arguments)
|
raise Error, decodeerror(_arguments)
|
||||||
|
|
||||||
if _arguments.has_key('----'):
|
if _arguments.has_key('----'):
|
||||||
return _arguments['----']
|
return _arguments['----']
|
||||||
if as:
|
if as:
|
||||||
item.__class__ = as
|
item.__class__ = as
|
||||||
return item
|
return item
|
||||||
|
|
||||||
get = _get
|
get = _get
|
||||||
|
|
||||||
_argmap_set = {
|
_argmap_set = {
|
||||||
'to' : 'data',
|
'to' : 'data',
|
||||||
}
|
}
|
||||||
|
|
||||||
def _set(self, _object, _attributes={}, **_arguments):
|
def _set(self, _object, _attributes={}, **_arguments):
|
||||||
"""set: Set an object's data.
|
"""set: Set an object's data.
|
||||||
Required argument: the object for the command
|
Required argument: the object for the command
|
||||||
Keyword argument to: The new value.
|
Keyword argument to: The new value.
|
||||||
Keyword argument _attributes: AppleEvent attribute dictionary
|
Keyword argument _attributes: AppleEvent attribute dictionary
|
||||||
"""
|
"""
|
||||||
_code = 'core'
|
_code = 'core'
|
||||||
_subcode = 'setd'
|
_subcode = 'setd'
|
||||||
|
|
||||||
keysubst(_arguments, self._argmap_set)
|
keysubst(_arguments, self._argmap_set)
|
||||||
_arguments['----'] = _object
|
_arguments['----'] = _object
|
||||||
|
|
||||||
|
|
||||||
_reply, _arguments, _attributes = self.send(_code, _subcode,
|
_reply, _arguments, _attributes = self.send(_code, _subcode,
|
||||||
_arguments, _attributes)
|
_arguments, _attributes)
|
||||||
if _arguments.get('errn', 0):
|
if _arguments.get('errn', 0):
|
||||||
raise Error, decodeerror(_arguments)
|
raise Error, decodeerror(_arguments)
|
||||||
# XXXX Optionally decode result
|
# XXXX Optionally decode result
|
||||||
if _arguments.has_key('----'):
|
if _arguments.has_key('----'):
|
||||||
return _arguments['----']
|
return _arguments['----']
|
||||||
|
|
||||||
set = _set
|
set = _set
|
||||||
|
|
||||||
# Tiny Finder class, for local use only
|
# Tiny Finder class, for local use only
|
||||||
|
|
||||||
class _miniFinder(TalkTo):
|
class _miniFinder(TalkTo):
|
||||||
def open(self, _object, _attributes={}, **_arguments):
|
def open(self, _object, _attributes={}, **_arguments):
|
||||||
"""open: Open the specified object(s)
|
"""open: Open the specified object(s)
|
||||||
Required argument: list of objects to open
|
Required argument: list of objects to open
|
||||||
Keyword argument _attributes: AppleEvent attribute dictionary
|
Keyword argument _attributes: AppleEvent attribute dictionary
|
||||||
"""
|
"""
|
||||||
_code = 'aevt'
|
_code = 'aevt'
|
||||||
_subcode = 'odoc'
|
_subcode = 'odoc'
|
||||||
|
|
||||||
if _arguments: raise TypeError, 'No optional args expected'
|
if _arguments: raise TypeError, 'No optional args expected'
|
||||||
_arguments['----'] = _object
|
_arguments['----'] = _object
|
||||||
|
|
||||||
|
|
||||||
_reply, _arguments, _attributes = self.send(_code, _subcode,
|
_reply, _arguments, _attributes = self.send(_code, _subcode,
|
||||||
_arguments, _attributes)
|
_arguments, _attributes)
|
||||||
if _arguments.has_key('errn'):
|
if _arguments.has_key('errn'):
|
||||||
raise Error, decodeerror(_arguments)
|
raise Error, decodeerror(_arguments)
|
||||||
# XXXX Optionally decode result
|
# XXXX Optionally decode result
|
||||||
if _arguments.has_key('----'):
|
if _arguments.has_key('----'):
|
||||||
return _arguments['----']
|
return _arguments['----']
|
||||||
#pass
|
#pass
|
||||||
|
|
||||||
_finder = _miniFinder('MACS')
|
_finder = _miniFinder('MACS')
|
||||||
|
|
||||||
def _launch(appfile):
|
def _launch(appfile):
|
||||||
"""Open a file thru the finder. Specify file by name or fsspec"""
|
"""Open a file thru the finder. Specify file by name or fsspec"""
|
||||||
_finder.open(_application_file(('ID ', appfile)))
|
_finder.open(_application_file(('ID ', appfile)))
|
||||||
|
|
||||||
|
|
||||||
class _application_file(ComponentItem):
|
class _application_file(ComponentItem):
|
||||||
"""application file - An application's file on disk"""
|
"""application file - An application's file on disk"""
|
||||||
want = 'appf'
|
want = 'appf'
|
||||||
|
|
||||||
_application_file._propdict = {
|
_application_file._propdict = {
|
||||||
}
|
}
|
||||||
|
@ -328,19 +328,19 @@ _application_file._elemdict = {
|
||||||
# XXXX Should test more, really...
|
# XXXX Should test more, really...
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
target = AE.AECreateDesc('sign', 'quil')
|
target = AE.AECreateDesc('sign', 'quil')
|
||||||
ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0)
|
ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0)
|
||||||
print unpackevent(ae)
|
print unpackevent(ae)
|
||||||
raw_input(":")
|
raw_input(":")
|
||||||
ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0)
|
ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0)
|
||||||
obj = Character(2, Word(1, Document(1)))
|
obj = Character(2, Word(1, Document(1)))
|
||||||
print obj
|
print obj
|
||||||
print repr(obj)
|
print repr(obj)
|
||||||
packevent(ae, {'----': obj})
|
packevent(ae, {'----': obj})
|
||||||
params, attrs = unpackevent(ae)
|
params, attrs = unpackevent(ae)
|
||||||
print params['----']
|
print params['----']
|
||||||
raw_input(":")
|
raw_input(":")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test()
|
test()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -10,549 +10,549 @@ import string
|
||||||
# aetools_convert.
|
# aetools_convert.
|
||||||
#
|
#
|
||||||
def pack(*args, **kwargs):
|
def pack(*args, **kwargs):
|
||||||
from aepack import pack
|
from aepack import pack
|
||||||
return pack( *args, **kwargs)
|
return pack( *args, **kwargs)
|
||||||
|
|
||||||
def nice(s):
|
def nice(s):
|
||||||
"""'nice' representation of an object"""
|
"""'nice' representation of an object"""
|
||||||
if type(s) is StringType: return repr(s)
|
if type(s) is StringType: return repr(s)
|
||||||
else: return str(s)
|
else: return str(s)
|
||||||
|
|
||||||
class Unknown:
|
class Unknown:
|
||||||
"""An uninterpreted AE object"""
|
"""An uninterpreted AE object"""
|
||||||
|
|
||||||
def __init__(self, type, data):
|
def __init__(self, type, data):
|
||||||
self.type = type
|
self.type = type
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Unknown(%s, %s)" % (`self.type`, `self.data`)
|
return "Unknown(%s, %s)" % (`self.type`, `self.data`)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(self.data, self.type)
|
return pack(self.data, self.type)
|
||||||
|
|
||||||
class Enum:
|
class Enum:
|
||||||
"""An AE enumeration value"""
|
"""An AE enumeration value"""
|
||||||
|
|
||||||
def __init__(self, enum):
|
def __init__(self, enum):
|
||||||
self.enum = "%-4.4s" % str(enum)
|
self.enum = "%-4.4s" % str(enum)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Enum(%s)" % `self.enum`
|
return "Enum(%s)" % `self.enum`
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return string.strip(self.enum)
|
return string.strip(self.enum)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(self.enum, typeEnumeration)
|
return pack(self.enum, typeEnumeration)
|
||||||
|
|
||||||
def IsEnum(x):
|
def IsEnum(x):
|
||||||
return isinstance(x, Enum)
|
return isinstance(x, Enum)
|
||||||
|
|
||||||
def mkenum(enum):
|
def mkenum(enum):
|
||||||
if IsEnum(enum): return enum
|
if IsEnum(enum): return enum
|
||||||
return Enum(enum)
|
return Enum(enum)
|
||||||
|
|
||||||
# Jack changed the way this is done
|
# Jack changed the way this is done
|
||||||
class InsertionLoc:
|
class InsertionLoc:
|
||||||
def __init__(self, of, pos):
|
def __init__(self, of, pos):
|
||||||
self.of = of
|
self.of = of
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "InsertionLoc(%s, %s)" % (`self.of`, `self.pos`)
|
return "InsertionLoc(%s, %s)" % (`self.of`, `self.pos`)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
rec = {'kobj': self.of, 'kpos': self.pos}
|
rec = {'kobj': self.of, 'kpos': self.pos}
|
||||||
return pack(rec, forcetype='insl')
|
return pack(rec, forcetype='insl')
|
||||||
|
|
||||||
# Convenience functions for dsp:
|
# Convenience functions for dsp:
|
||||||
def beginning(of):
|
def beginning(of):
|
||||||
return InsertionLoc(of, Enum('bgng'))
|
return InsertionLoc(of, Enum('bgng'))
|
||||||
|
|
||||||
def end(of):
|
def end(of):
|
||||||
return InsertionLoc(of, Enum('end '))
|
return InsertionLoc(of, Enum('end '))
|
||||||
|
|
||||||
class Boolean:
|
class Boolean:
|
||||||
"""An AE boolean value"""
|
"""An AE boolean value"""
|
||||||
|
|
||||||
def __init__(self, bool):
|
def __init__(self, bool):
|
||||||
self.bool = (not not bool)
|
self.bool = (not not bool)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Boolean(%s)" % `self.bool`
|
return "Boolean(%s)" % `self.bool`
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.bool:
|
if self.bool:
|
||||||
return "True"
|
return "True"
|
||||||
else:
|
else:
|
||||||
return "False"
|
return "False"
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(struct.pack('b', self.bool), 'bool')
|
return pack(struct.pack('b', self.bool), 'bool')
|
||||||
|
|
||||||
def IsBoolean(x):
|
def IsBoolean(x):
|
||||||
return isinstance(x, Boolean)
|
return isinstance(x, Boolean)
|
||||||
|
|
||||||
def mkboolean(bool):
|
def mkboolean(bool):
|
||||||
if IsBoolean(bool): return bool
|
if IsBoolean(bool): return bool
|
||||||
return Boolean(bool)
|
return Boolean(bool)
|
||||||
|
|
||||||
class Type:
|
class Type:
|
||||||
"""An AE 4-char typename object"""
|
"""An AE 4-char typename object"""
|
||||||
|
|
||||||
def __init__(self, type):
|
def __init__(self, type):
|
||||||
self.type = "%-4.4s" % str(type)
|
self.type = "%-4.4s" % str(type)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Type(%s)" % `self.type`
|
return "Type(%s)" % `self.type`
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return string.strip(self.type)
|
return string.strip(self.type)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(self.type, typeType)
|
return pack(self.type, typeType)
|
||||||
|
|
||||||
def IsType(x):
|
def IsType(x):
|
||||||
return isinstance(x, Type)
|
return isinstance(x, Type)
|
||||||
|
|
||||||
def mktype(type):
|
def mktype(type):
|
||||||
if IsType(type): return type
|
if IsType(type): return type
|
||||||
return Type(type)
|
return Type(type)
|
||||||
|
|
||||||
|
|
||||||
class Keyword:
|
class Keyword:
|
||||||
"""An AE 4-char keyword object"""
|
"""An AE 4-char keyword object"""
|
||||||
|
|
||||||
def __init__(self, keyword):
|
def __init__(self, keyword):
|
||||||
self.keyword = "%-4.4s" % str(keyword)
|
self.keyword = "%-4.4s" % str(keyword)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Keyword(%s)" % `self.keyword`
|
return "Keyword(%s)" % `self.keyword`
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return string.strip(self.keyword)
|
return string.strip(self.keyword)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(self.keyword, typeKeyword)
|
return pack(self.keyword, typeKeyword)
|
||||||
|
|
||||||
def IsKeyword(x):
|
def IsKeyword(x):
|
||||||
return isinstance(x, Keyword)
|
return isinstance(x, Keyword)
|
||||||
|
|
||||||
class Range:
|
class Range:
|
||||||
"""An AE range object"""
|
"""An AE range object"""
|
||||||
|
|
||||||
def __init__(self, start, stop):
|
def __init__(self, start, stop):
|
||||||
self.start = start
|
self.start = start
|
||||||
self.stop = stop
|
self.stop = stop
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Range(%s, %s)" % (`self.start`, `self.stop`)
|
return "Range(%s, %s)" % (`self.start`, `self.stop`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s thru %s" % (nice(self.start), nice(self.stop))
|
return "%s thru %s" % (nice(self.start), nice(self.stop))
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack({'star': self.start, 'stop': self.stop}, 'rang')
|
return pack({'star': self.start, 'stop': self.stop}, 'rang')
|
||||||
|
|
||||||
def IsRange(x):
|
def IsRange(x):
|
||||||
return isinstance(x, Range)
|
return isinstance(x, Range)
|
||||||
|
|
||||||
class Comparison:
|
class Comparison:
|
||||||
"""An AE Comparison"""
|
"""An AE Comparison"""
|
||||||
|
|
||||||
def __init__(self, obj1, relo, obj2):
|
def __init__(self, obj1, relo, obj2):
|
||||||
self.obj1 = obj1
|
self.obj1 = obj1
|
||||||
self.relo = "%-4.4s" % str(relo)
|
self.relo = "%-4.4s" % str(relo)
|
||||||
self.obj2 = obj2
|
self.obj2 = obj2
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`)
|
return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
|
return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack({'obj1': self.obj1,
|
return pack({'obj1': self.obj1,
|
||||||
'relo': mkenum(self.relo),
|
'relo': mkenum(self.relo),
|
||||||
'obj2': self.obj2},
|
'obj2': self.obj2},
|
||||||
'cmpd')
|
'cmpd')
|
||||||
|
|
||||||
def IsComparison(x):
|
def IsComparison(x):
|
||||||
return isinstance(x, Comparison)
|
return isinstance(x, Comparison)
|
||||||
|
|
||||||
class NComparison(Comparison):
|
class NComparison(Comparison):
|
||||||
# The class attribute 'relo' must be set in a subclass
|
# The class attribute 'relo' must be set in a subclass
|
||||||
|
|
||||||
def __init__(self, obj1, obj2):
|
def __init__(self, obj1, obj2):
|
||||||
Comparison.__init__(obj1, self.relo, obj2)
|
Comparison.__init__(obj1, self.relo, obj2)
|
||||||
|
|
||||||
class Ordinal:
|
class Ordinal:
|
||||||
"""An AE Ordinal"""
|
"""An AE Ordinal"""
|
||||||
|
|
||||||
def __init__(self, abso):
|
def __init__(self, abso):
|
||||||
# self.obj1 = obj1
|
# self.obj1 = obj1
|
||||||
self.abso = "%-4.4s" % str(abso)
|
self.abso = "%-4.4s" % str(abso)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Ordinal(%s)" % (`self.abso`)
|
return "Ordinal(%s)" % (`self.abso`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s" % (string.strip(self.abso))
|
return "%s" % (string.strip(self.abso))
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(self.abso, 'abso')
|
return pack(self.abso, 'abso')
|
||||||
|
|
||||||
def IsOrdinal(x):
|
def IsOrdinal(x):
|
||||||
return isinstance(x, Ordinal)
|
return isinstance(x, Ordinal)
|
||||||
|
|
||||||
class NOrdinal(Ordinal):
|
class NOrdinal(Ordinal):
|
||||||
# The class attribute 'abso' must be set in a subclass
|
# The class attribute 'abso' must be set in a subclass
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Ordinal.__init__(self, self.abso)
|
Ordinal.__init__(self, self.abso)
|
||||||
|
|
||||||
class Logical:
|
class Logical:
|
||||||
"""An AE logical expression object"""
|
"""An AE logical expression object"""
|
||||||
|
|
||||||
def __init__(self, logc, term):
|
def __init__(self, logc, term):
|
||||||
self.logc = "%-4.4s" % str(logc)
|
self.logc = "%-4.4s" % str(logc)
|
||||||
self.term = term
|
self.term = term
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Logical(%s, %s)" % (`self.logc`, `self.term`)
|
return "Logical(%s, %s)" % (`self.logc`, `self.term`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if type(self.term) == ListType and len(self.term) == 2:
|
if type(self.term) == ListType and len(self.term) == 2:
|
||||||
return "%s %s %s" % (nice(self.term[0]),
|
return "%s %s %s" % (nice(self.term[0]),
|
||||||
string.strip(self.logc),
|
string.strip(self.logc),
|
||||||
nice(self.term[1]))
|
nice(self.term[1]))
|
||||||
else:
|
else:
|
||||||
return "%s(%s)" % (string.strip(self.logc), nice(self.term))
|
return "%s(%s)" % (string.strip(self.logc), nice(self.term))
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
|
return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
|
||||||
|
|
||||||
def IsLogical(x):
|
def IsLogical(x):
|
||||||
return isinstance(x, Logical)
|
return isinstance(x, Logical)
|
||||||
|
|
||||||
class StyledText:
|
class StyledText:
|
||||||
"""An AE object respresenting text in a certain style"""
|
"""An AE object respresenting text in a certain style"""
|
||||||
|
|
||||||
def __init__(self, style, text):
|
def __init__(self, style, text):
|
||||||
self.style = style
|
self.style = style
|
||||||
self.text = text
|
self.text = text
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "StyledText(%s, %s)" % (`self.style`, `self.text`)
|
return "StyledText(%s, %s)" % (`self.style`, `self.text`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.text
|
return self.text
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
|
return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
|
||||||
|
|
||||||
def IsStyledText(x):
|
def IsStyledText(x):
|
||||||
return isinstance(x, StyledText)
|
return isinstance(x, StyledText)
|
||||||
|
|
||||||
class AEText:
|
class AEText:
|
||||||
"""An AE text object with style, script and language specified"""
|
"""An AE text object with style, script and language specified"""
|
||||||
|
|
||||||
def __init__(self, script, style, text):
|
def __init__(self, script, style, text):
|
||||||
self.script = script
|
self.script = script
|
||||||
self.style = style
|
self.style = style
|
||||||
self.text = text
|
self.text = text
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`)
|
return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.text
|
return self.text
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
|
return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
|
||||||
keyAEText: self.text}, typeAEText)
|
keyAEText: self.text}, typeAEText)
|
||||||
|
|
||||||
def IsAEText(x):
|
def IsAEText(x):
|
||||||
return isinstance(x, AEText)
|
return isinstance(x, AEText)
|
||||||
|
|
||||||
class IntlText:
|
class IntlText:
|
||||||
"""A text object with script and language specified"""
|
"""A text object with script and language specified"""
|
||||||
|
|
||||||
def __init__(self, script, language, text):
|
def __init__(self, script, language, text):
|
||||||
self.script = script
|
self.script = script
|
||||||
self.language = language
|
self.language = language
|
||||||
self.text = text
|
self.text = text
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`)
|
return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.text
|
return self.text
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(struct.pack('hh', self.script, self.language)+self.text,
|
return pack(struct.pack('hh', self.script, self.language)+self.text,
|
||||||
typeIntlText)
|
typeIntlText)
|
||||||
|
|
||||||
def IsIntlText(x):
|
def IsIntlText(x):
|
||||||
return isinstance(x, IntlText)
|
return isinstance(x, IntlText)
|
||||||
|
|
||||||
class IntlWritingCode:
|
class IntlWritingCode:
|
||||||
"""An object representing script and language"""
|
"""An object representing script and language"""
|
||||||
|
|
||||||
def __init__(self, script, language):
|
def __init__(self, script, language):
|
||||||
self.script = script
|
self.script = script
|
||||||
self.language = language
|
self.language = language
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`)
|
return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "script system %d, language %d"%(self.script, self.language)
|
return "script system %d, language %d"%(self.script, self.language)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(struct.pack('hh', self.script, self.language),
|
return pack(struct.pack('hh', self.script, self.language),
|
||||||
typeIntlWritingCode)
|
typeIntlWritingCode)
|
||||||
|
|
||||||
def IsIntlWritingCode(x):
|
def IsIntlWritingCode(x):
|
||||||
return isinstance(x, IntlWritingCode)
|
return isinstance(x, IntlWritingCode)
|
||||||
|
|
||||||
class QDPoint:
|
class QDPoint:
|
||||||
"""A point"""
|
"""A point"""
|
||||||
|
|
||||||
def __init__(self, v, h):
|
def __init__(self, v, h):
|
||||||
self.v = v
|
self.v = v
|
||||||
self.h = h
|
self.h = h
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "QDPoint(%s, %s)" % (`self.v`, `self.h`)
|
return "QDPoint(%s, %s)" % (`self.v`, `self.h`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "(%d, %d)"%(self.v, self.h)
|
return "(%d, %d)"%(self.v, self.h)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(struct.pack('hh', self.v, self.h),
|
return pack(struct.pack('hh', self.v, self.h),
|
||||||
typeQDPoint)
|
typeQDPoint)
|
||||||
|
|
||||||
def IsQDPoint(x):
|
def IsQDPoint(x):
|
||||||
return isinstance(x, QDPoint)
|
return isinstance(x, QDPoint)
|
||||||
|
|
||||||
class QDRectangle:
|
class QDRectangle:
|
||||||
"""A rectangle"""
|
"""A rectangle"""
|
||||||
|
|
||||||
def __init__(self, v0, h0, v1, h1):
|
def __init__(self, v0, h0, v1, h1):
|
||||||
self.v0 = v0
|
self.v0 = v0
|
||||||
self.h0 = h0
|
self.h0 = h0
|
||||||
self.v1 = v1
|
self.v1 = v1
|
||||||
self.h1 = h1
|
self.h1 = h1
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`,
|
return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`,
|
||||||
`self.v1`, `self.h1`)
|
`self.v1`, `self.h1`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
|
return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
|
return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
|
||||||
typeQDRectangle)
|
typeQDRectangle)
|
||||||
|
|
||||||
def IsQDRectangle(x):
|
def IsQDRectangle(x):
|
||||||
return isinstance(x, QDRectangle)
|
return isinstance(x, QDRectangle)
|
||||||
|
|
||||||
class RGBColor:
|
class RGBColor:
|
||||||
"""An RGB color"""
|
"""An RGB color"""
|
||||||
|
|
||||||
def __init__(self, r, g, b):
|
def __init__(self, r, g, b):
|
||||||
self.r = r
|
self.r = r
|
||||||
self.g = g
|
self.g = g
|
||||||
self.b = b
|
self.b = b
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`)
|
return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
|
return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack(struct.pack('hhh', self.r, self.g, self.b),
|
return pack(struct.pack('hhh', self.r, self.g, self.b),
|
||||||
typeRGBColor)
|
typeRGBColor)
|
||||||
|
|
||||||
def IsRGBColor(x):
|
def IsRGBColor(x):
|
||||||
return isinstance(x, RGBColor)
|
return isinstance(x, RGBColor)
|
||||||
|
|
||||||
class ObjectSpecifier:
|
class ObjectSpecifier:
|
||||||
|
|
||||||
"""A class for constructing and manipulation AE object specifiers in python.
|
"""A class for constructing and manipulation AE object specifiers in python.
|
||||||
|
|
||||||
An object specifier is actually a record with four fields:
|
An object specifier is actually a record with four fields:
|
||||||
|
|
||||||
key type description
|
key type description
|
||||||
--- ---- -----------
|
--- ---- -----------
|
||||||
|
|
||||||
'want' type 4-char class code of thing we want,
|
'want' type 4-char class code of thing we want,
|
||||||
e.g. word, paragraph or property
|
e.g. word, paragraph or property
|
||||||
|
|
||||||
'form' enum how we specify which 'want' thing(s) we want,
|
'form' enum how we specify which 'want' thing(s) we want,
|
||||||
e.g. by index, by range, by name, or by property specifier
|
e.g. by index, by range, by name, or by property specifier
|
||||||
|
|
||||||
'seld' any which thing(s) we want,
|
'seld' any which thing(s) we want,
|
||||||
e.g. its index, its name, or its property specifier
|
e.g. its index, its name, or its property specifier
|
||||||
|
|
||||||
'from' object the object in which it is contained,
|
'from' object the object in which it is contained,
|
||||||
or null, meaning look for it in the application
|
or null, meaning look for it in the application
|
||||||
|
|
||||||
Note that we don't call this class plain "Object", since that name
|
Note that we don't call this class plain "Object", since that name
|
||||||
is likely to be used by the application.
|
is likely to be used by the application.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, want, form, seld, fr = None):
|
def __init__(self, want, form, seld, fr = None):
|
||||||
self.want = want
|
self.want = want
|
||||||
self.form = form
|
self.form = form
|
||||||
self.seld = seld
|
self.seld = seld
|
||||||
self.fr = fr
|
self.fr = fr
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
|
s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
|
||||||
if self.fr:
|
if self.fr:
|
||||||
s = s + ", %s)" % `self.fr`
|
s = s + ", %s)" % `self.fr`
|
||||||
else:
|
else:
|
||||||
s = s + ")"
|
s = s + ")"
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def __aepack__(self):
|
def __aepack__(self):
|
||||||
return pack({'want': mktype(self.want),
|
return pack({'want': mktype(self.want),
|
||||||
'form': mkenum(self.form),
|
'form': mkenum(self.form),
|
||||||
'seld': self.seld,
|
'seld': self.seld,
|
||||||
'from': self.fr},
|
'from': self.fr},
|
||||||
'obj ')
|
'obj ')
|
||||||
|
|
||||||
def IsObjectSpecifier(x):
|
def IsObjectSpecifier(x):
|
||||||
return isinstance(x, ObjectSpecifier)
|
return isinstance(x, ObjectSpecifier)
|
||||||
|
|
||||||
|
|
||||||
# Backwards compatability, sigh...
|
# Backwards compatability, sigh...
|
||||||
class Property(ObjectSpecifier):
|
class Property(ObjectSpecifier):
|
||||||
|
|
||||||
def __init__(self, which, fr = None, want='prop'):
|
def __init__(self, which, fr = None, want='prop'):
|
||||||
ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr)
|
ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.fr:
|
if self.fr:
|
||||||
return "Property(%s, %s)" % (`self.seld.type`, `self.fr`)
|
return "Property(%s, %s)" % (`self.seld.type`, `self.fr`)
|
||||||
else:
|
else:
|
||||||
return "Property(%s)" % `self.seld.type`
|
return "Property(%s)" % `self.seld.type`
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.fr:
|
if self.fr:
|
||||||
return "Property %s of %s" % (str(self.seld), str(self.fr))
|
return "Property %s of %s" % (str(self.seld), str(self.fr))
|
||||||
else:
|
else:
|
||||||
return "Property %s" % str(self.seld)
|
return "Property %s" % str(self.seld)
|
||||||
|
|
||||||
|
|
||||||
class NProperty(ObjectSpecifier):
|
class NProperty(ObjectSpecifier):
|
||||||
# Subclasses *must* self baseclass attributes:
|
# Subclasses *must* self baseclass attributes:
|
||||||
# want is the type of this property
|
# want is the type of this property
|
||||||
# which is the property name of this property
|
# which is the property name of this property
|
||||||
|
|
||||||
def __init__(self, fr = None):
|
def __init__(self, fr = None):
|
||||||
#try:
|
#try:
|
||||||
# dummy = self.want
|
# dummy = self.want
|
||||||
#except:
|
#except:
|
||||||
# self.want = 'prop'
|
# self.want = 'prop'
|
||||||
self.want = 'prop'
|
self.want = 'prop'
|
||||||
ObjectSpecifier.__init__(self, self.want, 'prop',
|
ObjectSpecifier.__init__(self, self.want, 'prop',
|
||||||
mktype(self.which), fr)
|
mktype(self.which), fr)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
rv = "Property(%s"%`self.seld.type`
|
rv = "Property(%s"%`self.seld.type`
|
||||||
if self.fr:
|
if self.fr:
|
||||||
rv = rv + ", fr=%s" % `self.fr`
|
rv = rv + ", fr=%s" % `self.fr`
|
||||||
if self.want != 'prop':
|
if self.want != 'prop':
|
||||||
rv = rv + ", want=%s" % `self.want`
|
rv = rv + ", want=%s" % `self.want`
|
||||||
return rv + ")"
|
return rv + ")"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.fr:
|
if self.fr:
|
||||||
return "Property %s of %s" % (str(self.seld), str(self.fr))
|
return "Property %s of %s" % (str(self.seld), str(self.fr))
|
||||||
else:
|
else:
|
||||||
return "Property %s" % str(self.seld)
|
return "Property %s" % str(self.seld)
|
||||||
|
|
||||||
|
|
||||||
class SelectableItem(ObjectSpecifier):
|
class SelectableItem(ObjectSpecifier):
|
||||||
|
|
||||||
def __init__(self, want, seld, fr = None):
|
def __init__(self, want, seld, fr = None):
|
||||||
t = type(seld)
|
t = type(seld)
|
||||||
if t == StringType:
|
if t == StringType:
|
||||||
form = 'name'
|
form = 'name'
|
||||||
elif IsRange(seld):
|
elif IsRange(seld):
|
||||||
form = 'rang'
|
form = 'rang'
|
||||||
elif IsComparison(seld) or IsLogical(seld):
|
elif IsComparison(seld) or IsLogical(seld):
|
||||||
form = 'test'
|
form = 'test'
|
||||||
elif t == TupleType:
|
elif t == TupleType:
|
||||||
# Breakout: specify both form and seld in a tuple
|
# Breakout: specify both form and seld in a tuple
|
||||||
# (if you want ID or rele or somesuch)
|
# (if you want ID or rele or somesuch)
|
||||||
form, seld = seld
|
form, seld = seld
|
||||||
else:
|
else:
|
||||||
form = 'indx'
|
form = 'indx'
|
||||||
ObjectSpecifier.__init__(self, want, form, seld, fr)
|
ObjectSpecifier.__init__(self, want, form, seld, fr)
|
||||||
|
|
||||||
|
|
||||||
class ComponentItem(SelectableItem):
|
class ComponentItem(SelectableItem):
|
||||||
# Derived classes *must* set the *class attribute* 'want' to some constant
|
# Derived classes *must* set the *class attribute* 'want' to some constant
|
||||||
# Also, dictionaries _propdict and _elemdict must be set to map property
|
# Also, dictionaries _propdict and _elemdict must be set to map property
|
||||||
# and element names to the correct classes
|
# and element names to the correct classes
|
||||||
|
|
||||||
_propdict = {}
|
_propdict = {}
|
||||||
_elemdict = {}
|
_elemdict = {}
|
||||||
def __init__(self, which, fr = None):
|
def __init__(self, which, fr = None):
|
||||||
SelectableItem.__init__(self, self.want, which, fr)
|
SelectableItem.__init__(self, self.want, which, fr)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if not self.fr:
|
if not self.fr:
|
||||||
return "%s(%s)" % (self.__class__.__name__, `self.seld`)
|
return "%s(%s)" % (self.__class__.__name__, `self.seld`)
|
||||||
return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`)
|
return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
seld = self.seld
|
seld = self.seld
|
||||||
if type(seld) == StringType:
|
if type(seld) == StringType:
|
||||||
ss = repr(seld)
|
ss = repr(seld)
|
||||||
elif IsRange(seld):
|
elif IsRange(seld):
|
||||||
start, stop = seld.start, seld.stop
|
start, stop = seld.start, seld.stop
|
||||||
if type(start) == InstanceType == type(stop) and \
|
if type(start) == InstanceType == type(stop) and \
|
||||||
start.__class__ == self.__class__ == stop.__class__:
|
start.__class__ == self.__class__ == stop.__class__:
|
||||||
ss = str(start.seld) + " thru " + str(stop.seld)
|
ss = str(start.seld) + " thru " + str(stop.seld)
|
||||||
else:
|
else:
|
||||||
ss = str(seld)
|
ss = str(seld)
|
||||||
else:
|
else:
|
||||||
ss = str(seld)
|
ss = str(seld)
|
||||||
s = "%s %s" % (self.__class__.__name__, ss)
|
s = "%s %s" % (self.__class__.__name__, ss)
|
||||||
if self.fr: s = s + " of %s" % str(self.fr)
|
if self.fr: s = s + " of %s" % str(self.fr)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if self._elemdict.has_key(name):
|
if self._elemdict.has_key(name):
|
||||||
cls = self._elemdict[name]
|
cls = self._elemdict[name]
|
||||||
return DelayedComponentItem(cls, self)
|
return DelayedComponentItem(cls, self)
|
||||||
if self._propdict.has_key(name):
|
if self._propdict.has_key(name):
|
||||||
cls = self._propdict[name]
|
cls = self._propdict[name]
|
||||||
return cls(self)
|
return cls(self)
|
||||||
raise AttributeError, name
|
raise AttributeError, name
|
||||||
|
|
||||||
|
|
||||||
class DelayedComponentItem:
|
class DelayedComponentItem:
|
||||||
def __init__(self, compclass, fr):
|
def __init__(self, compclass, fr):
|
||||||
self.compclass = compclass
|
self.compclass = compclass
|
||||||
self.fr = fr
|
self.fr = fr
|
||||||
|
|
||||||
def __call__(self, which):
|
def __call__(self, which):
|
||||||
return self.compclass(which, self.fr)
|
return self.compclass(which, self.fr)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(???, %s)" % (self.__class__.__name__, `self.fr`)
|
return "%s(???, %s)" % (self.__class__.__name__, `self.fr`)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr))
|
return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr))
|
||||||
|
|
||||||
template = """
|
template = """
|
||||||
class %s(ComponentItem): want = '%s'
|
class %s(ComponentItem): want = '%s'
|
||||||
|
|
|
@ -24,77 +24,77 @@ AS_RESOURCEFORK=2
|
||||||
AS_IGNORE=(3,4,5,6,8,9,10,11,12,13,14,15)
|
AS_IGNORE=(3,4,5,6,8,9,10,11,12,13,14,15)
|
||||||
|
|
||||||
def decode(input, output, resonly=0):
|
def decode(input, output, resonly=0):
|
||||||
if type(input) == type(''):
|
if type(input) == type(''):
|
||||||
input = open(input, 'rb')
|
input = open(input, 'rb')
|
||||||
# Should we also test for FSSpecs or FSRefs?
|
# Should we also test for FSSpecs or FSRefs?
|
||||||
header = input.read(AS_HEADER_LENGTH)
|
header = input.read(AS_HEADER_LENGTH)
|
||||||
try:
|
try:
|
||||||
magic, version, dummy, nentry = struct.unpack(AS_HEADER_FORMAT, header)
|
magic, version, dummy, nentry = struct.unpack(AS_HEADER_FORMAT, header)
|
||||||
except ValueError, arg:
|
except ValueError, arg:
|
||||||
raise Error, "Unpack header error: %s"%arg
|
raise Error, "Unpack header error: %s"%arg
|
||||||
if verbose:
|
if verbose:
|
||||||
print 'Magic: 0x%8.8x'%magic
|
print 'Magic: 0x%8.8x'%magic
|
||||||
print 'Version: 0x%8.8x'%version
|
print 'Version: 0x%8.8x'%version
|
||||||
print 'Entries: %d'%nentry
|
print 'Entries: %d'%nentry
|
||||||
if magic != AS_MAGIC:
|
if magic != AS_MAGIC:
|
||||||
raise Error, 'Unknown AppleSingle magic number 0x%8.8x'%magic
|
raise Error, 'Unknown AppleSingle magic number 0x%8.8x'%magic
|
||||||
if version != AS_VERSION:
|
if version != AS_VERSION:
|
||||||
raise Error, 'Unknown AppleSingle version number 0x%8.8x'%version
|
raise Error, 'Unknown AppleSingle version number 0x%8.8x'%version
|
||||||
if nentry <= 0:
|
if nentry <= 0:
|
||||||
raise Error, "AppleSingle file contains no forks"
|
raise Error, "AppleSingle file contains no forks"
|
||||||
headers = [input.read(AS_ENTRY_LENGTH) for i in range(nentry)]
|
headers = [input.read(AS_ENTRY_LENGTH) for i in range(nentry)]
|
||||||
didwork = 0
|
didwork = 0
|
||||||
for hdr in headers:
|
for hdr in headers:
|
||||||
try:
|
try:
|
||||||
id, offset, length = struct.unpack(AS_ENTRY_FORMAT, hdr)
|
id, offset, length = struct.unpack(AS_ENTRY_FORMAT, hdr)
|
||||||
except ValueError, arg:
|
except ValueError, arg:
|
||||||
raise Error, "Unpack entry error: %s"%arg
|
raise Error, "Unpack entry error: %s"%arg
|
||||||
if verbose:
|
if verbose:
|
||||||
print 'Fork %d, offset %d, length %d'%(id, offset, length)
|
print 'Fork %d, offset %d, length %d'%(id, offset, length)
|
||||||
input.seek(offset)
|
input.seek(offset)
|
||||||
if length == 0:
|
if length == 0:
|
||||||
data = ''
|
data = ''
|
||||||
else:
|
else:
|
||||||
data = input.read(length)
|
data = input.read(length)
|
||||||
if len(data) != length:
|
if len(data) != length:
|
||||||
raise Error, 'Short read: expected %d bytes got %d'%(length, len(data))
|
raise Error, 'Short read: expected %d bytes got %d'%(length, len(data))
|
||||||
if id == AS_DATAFORK:
|
if id == AS_DATAFORK:
|
||||||
if verbose:
|
if verbose:
|
||||||
print ' (data fork)'
|
print ' (data fork)'
|
||||||
if not resonly:
|
if not resonly:
|
||||||
didwork = 1
|
didwork = 1
|
||||||
fp = open(output, 'wb')
|
fp = open(output, 'wb')
|
||||||
fp.write(data)
|
fp.write(data)
|
||||||
fp.close()
|
fp.close()
|
||||||
elif id == AS_RESOURCEFORK:
|
elif id == AS_RESOURCEFORK:
|
||||||
didwork = 1
|
didwork = 1
|
||||||
if verbose:
|
if verbose:
|
||||||
print ' (resource fork)'
|
print ' (resource fork)'
|
||||||
if resonly:
|
if resonly:
|
||||||
fp = open(output, 'wb')
|
fp = open(output, 'wb')
|
||||||
else:
|
else:
|
||||||
fp = MacOS.openrf(output, 'wb')
|
fp = MacOS.openrf(output, 'wb')
|
||||||
fp.write(data)
|
fp.write(data)
|
||||||
fp.close()
|
fp.close()
|
||||||
elif id in AS_IGNORE:
|
elif id in AS_IGNORE:
|
||||||
if verbose:
|
if verbose:
|
||||||
print ' (ignored)'
|
print ' (ignored)'
|
||||||
else:
|
else:
|
||||||
raise Error, 'Unknown fork type %d'%id
|
raise Error, 'Unknown fork type %d'%id
|
||||||
if not didwork:
|
if not didwork:
|
||||||
raise Error, 'No useful forks found'
|
raise Error, 'No useful forks found'
|
||||||
|
|
||||||
def _test():
|
def _test():
|
||||||
if len(sys.argv) < 3 or sys.argv[1] == '-r' and len(sys.argv) != 4:
|
if len(sys.argv) < 3 or sys.argv[1] == '-r' and len(sys.argv) != 4:
|
||||||
print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
|
print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if sys.argv[1] == '-r':
|
if sys.argv[1] == '-r':
|
||||||
resonly = 1
|
resonly = 1
|
||||||
del sys.argv[1]
|
del sys.argv[1]
|
||||||
else:
|
else:
|
||||||
resonly = 0
|
resonly = 0
|
||||||
decode(sys.argv[1], sys.argv[2], resonly=resonly)
|
decode(sys.argv[1], sys.argv[2], resonly=resonly)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
_test()
|
_test()
|
||||||
|
|
|
@ -14,13 +14,13 @@ import marshal
|
||||||
# directory.
|
# directory.
|
||||||
#
|
#
|
||||||
if not sys.argv or sys.argv[0][:1] == '-':
|
if not sys.argv or sys.argv[0][:1] == '-':
|
||||||
# Insert our (guessed) name.
|
# Insert our (guessed) name.
|
||||||
_dir = os.path.split(sys.executable)[0] # removes "python"
|
_dir = os.path.split(sys.executable)[0] # removes "python"
|
||||||
_dir = os.path.split(_dir)[0] # Removes "MacOS"
|
_dir = os.path.split(_dir)[0] # Removes "MacOS"
|
||||||
_dir = os.path.join(_dir, 'Resources')
|
_dir = os.path.join(_dir, 'Resources')
|
||||||
sys.argv.insert(0, '__rawmain__')
|
sys.argv.insert(0, '__rawmain__')
|
||||||
else:
|
else:
|
||||||
_dir = os.path.split(sys.argv[0])[0]
|
_dir = os.path.split(sys.argv[0])[0]
|
||||||
#
|
#
|
||||||
# Add the Resources directory to the path. This is where files installed
|
# Add the Resources directory to the path. This is where files installed
|
||||||
# by BuildApplet.py with the --extra option show up, and if those files are
|
# by BuildApplet.py with the --extra option show up, and if those files are
|
||||||
|
@ -36,28 +36,28 @@ argvemulator.ArgvCollector().mainloop()
|
||||||
#
|
#
|
||||||
__file__ = os.path.join(_dir, '__main__.py')
|
__file__ = os.path.join(_dir, '__main__.py')
|
||||||
if os.path.exists(__file__):
|
if os.path.exists(__file__):
|
||||||
#
|
#
|
||||||
# Setup something resembling a normal environment and go.
|
# Setup something resembling a normal environment and go.
|
||||||
#
|
#
|
||||||
sys.argv[0] = __file__
|
sys.argv[0] = __file__
|
||||||
del argvemulator, os, sys, _dir
|
del argvemulator, os, sys, _dir
|
||||||
execfile(__file__)
|
execfile(__file__)
|
||||||
else:
|
else:
|
||||||
__file__ = os.path.join(_dir, '__main__.pyc')
|
__file__ = os.path.join(_dir, '__main__.pyc')
|
||||||
if os.path.exists(__file__):
|
if os.path.exists(__file__):
|
||||||
#
|
#
|
||||||
# If we have only a .pyc file we read the code object from that
|
# If we have only a .pyc file we read the code object from that
|
||||||
#
|
#
|
||||||
sys.argv[0] = __file__
|
sys.argv[0] = __file__
|
||||||
_fp = open(__file__, 'rb')
|
_fp = open(__file__, 'rb')
|
||||||
_fp.read(8)
|
_fp.read(8)
|
||||||
__code__ = marshal.load(_fp)
|
__code__ = marshal.load(_fp)
|
||||||
#
|
#
|
||||||
# Again, we create an almost-normal environment (only __code__ is
|
# Again, we create an almost-normal environment (only __code__ is
|
||||||
# funny) and go.
|
# funny) and go.
|
||||||
#
|
#
|
||||||
del argvemulator, os, sys, marshal, _dir, _fp
|
del argvemulator, os, sys, marshal, _dir, _fp
|
||||||
exec __code__
|
exec __code__
|
||||||
else:
|
else:
|
||||||
sys.stderr.write("%s: neither __main__.py nor __main__.pyc found\n"%sys.argv[0])
|
sys.stderr.write("%s: neither __main__.py nor __main__.pyc found\n"%sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
for name in ["__rawmain__.py", "__rawmain__.pyc", "__main__.py", "__main__.pyc"]:
|
for name in ["__rawmain__.py", "__rawmain__.pyc", "__main__.py", "__main__.pyc"]:
|
||||||
realmain = os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])),
|
realmain = os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])),
|
||||||
"Resources", name)
|
"Resources", name)
|
||||||
if os.path.exists(realmain):
|
if os.path.exists(realmain):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
sys.stderr.write("%s: cannot find applet main program\n" % sys.argv[0])
|
sys.stderr.write("%s: cannot find applet main program\n" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
sys.argv.insert(1, realmain)
|
sys.argv.insert(1, realmain)
|
||||||
os.execve(sys.executable, sys.argv, os.environ)
|
os.execve(sys.executable, sys.argv, os.environ)
|
||||||
|
|
|
@ -12,12 +12,12 @@ Error = "bgenlocations.Error"
|
||||||
# Where bgen is. For unix-Python bgen isn't installed, so you have to refer to
|
# Where bgen is. For unix-Python bgen isn't installed, so you have to refer to
|
||||||
# the source tree here.
|
# the source tree here.
|
||||||
if sys.platform == 'mac':
|
if sys.platform == 'mac':
|
||||||
# For MacPython we know where it is
|
# For MacPython we know where it is
|
||||||
def _pardir(p): return os.path.split(p)[0]
|
def _pardir(p): return os.path.split(p)[0]
|
||||||
BGENDIR=os.path.join(sys.prefix, "Tools", "bgen", "bgen")
|
BGENDIR=os.path.join(sys.prefix, "Tools", "bgen", "bgen")
|
||||||
else:
|
else:
|
||||||
# for unix-Python we don't know, please set it yourself.
|
# for unix-Python we don't know, please set it yourself.
|
||||||
BGENDIR="/Users/jack/src/python/Tools/bgen/bgen"
|
BGENDIR="/Users/jack/src/python/Tools/bgen/bgen"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Where to find the Universal Header include files. If you have CodeWarrior
|
# Where to find the Universal Header include files. If you have CodeWarrior
|
||||||
|
@ -26,9 +26,9 @@ else:
|
||||||
# end of lines, so don't worry about that.
|
# end of lines, so don't worry about that.
|
||||||
#
|
#
|
||||||
if sys.platform == 'mac':
|
if sys.platform == 'mac':
|
||||||
_MWERKSDIR="Sap:Applications (Mac OS 9):Metrowerks CodeWarrior 7.0:Metrowerks CodeWarrior"
|
_MWERKSDIR="Sap:Applications (Mac OS 9):Metrowerks CodeWarrior 7.0:Metrowerks CodeWarrior"
|
||||||
else:
|
else:
|
||||||
_MWERKSDIR="/Volumes/Sap/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/"
|
_MWERKSDIR="/Volumes/Sap/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/"
|
||||||
INCLUDEDIR=os.path.join(_MWERKSDIR, "MacOS Support", "Universal", "Interfaces", "CIncludes")
|
INCLUDEDIR=os.path.join(_MWERKSDIR, "MacOS Support", "Universal", "Interfaces", "CIncludes")
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -37,25 +37,25 @@ INCLUDEDIR=os.path.join(_MWERKSDIR, "MacOS Support", "Universal", "Interfaces",
|
||||||
# your source directory, not your installed directory.
|
# your source directory, not your installed directory.
|
||||||
#
|
#
|
||||||
if sys.platform == 'mac':
|
if sys.platform == 'mac':
|
||||||
TOOLBOXDIR=os.path.join(sys.prefix, "Lib", "plat-mac", "Carbon")
|
TOOLBOXDIR=os.path.join(sys.prefix, "Lib", "plat-mac", "Carbon")
|
||||||
else:
|
else:
|
||||||
TOOLBOXDIR="/Users/jack/src/python/Lib/plat-mac/Carbon"
|
TOOLBOXDIR="/Users/jack/src/python/Lib/plat-mac/Carbon"
|
||||||
|
|
||||||
# Creator for C files:
|
# Creator for C files:
|
||||||
CREATOR="CWIE"
|
CREATOR="CWIE"
|
||||||
|
|
||||||
if not os.path.exists(BGENDIR):
|
if not os.path.exists(BGENDIR):
|
||||||
raise Error, "Please fix bgenlocations.py, BGENDIR does not exist: %s" % BGENDIR
|
raise Error, "Please fix bgenlocations.py, BGENDIR does not exist: %s" % BGENDIR
|
||||||
if not os.path.exists(INCLUDEDIR):
|
if not os.path.exists(INCLUDEDIR):
|
||||||
raise Error, "Please fix bgenlocations.py, INCLUDEDIR does not exist: %s" % INCLUDEDIR
|
raise Error, "Please fix bgenlocations.py, INCLUDEDIR does not exist: %s" % INCLUDEDIR
|
||||||
if not os.path.exists(TOOLBOXDIR):
|
if not os.path.exists(TOOLBOXDIR):
|
||||||
raise Error, "Please fix bgenlocations.py, TOOLBOXDIR does not exist: %s" % TOOLBOXDIR
|
raise Error, "Please fix bgenlocations.py, TOOLBOXDIR does not exist: %s" % TOOLBOXDIR
|
||||||
|
|
||||||
# Sigh, due to the way these are used make sure they end with : or /.
|
# Sigh, due to the way these are used make sure they end with : or /.
|
||||||
if BGENDIR[-1] != os.sep:
|
if BGENDIR[-1] != os.sep:
|
||||||
BGENDIR = BGENDIR + os.sep
|
BGENDIR = BGENDIR + os.sep
|
||||||
if INCLUDEDIR[-1] != os.sep:
|
if INCLUDEDIR[-1] != os.sep:
|
||||||
INCLUDEDIR = INCLUDEDIR + os.sep
|
INCLUDEDIR = INCLUDEDIR + os.sep
|
||||||
if TOOLBOXDIR[-1] != os.sep:
|
if TOOLBOXDIR[-1] != os.sep:
|
||||||
TOOLBOXDIR = TOOLBOXDIR + os.sep
|
TOOLBOXDIR = TOOLBOXDIR + os.sep
|
||||||
|
|
||||||
|
|
|
@ -42,375 +42,375 @@ WRITE = 2
|
||||||
RESOURCE_FORK_NAME=Carbon.File.FSGetResourceForkName()
|
RESOURCE_FORK_NAME=Carbon.File.FSGetResourceForkName()
|
||||||
|
|
||||||
def findtemplate(template=None):
|
def findtemplate(template=None):
|
||||||
"""Locate the applet template along sys.path"""
|
"""Locate the applet template along sys.path"""
|
||||||
if MacOS.runtimemodel == 'macho':
|
if MacOS.runtimemodel == 'macho':
|
||||||
return None
|
return None
|
||||||
if not template:
|
if not template:
|
||||||
template=TEMPLATE
|
template=TEMPLATE
|
||||||
for p in sys.path:
|
for p in sys.path:
|
||||||
file = os.path.join(p, template)
|
file = os.path.join(p, template)
|
||||||
try:
|
try:
|
||||||
file, d1, d2 = Carbon.File.FSResolveAliasFile(file, 1)
|
file, d1, d2 = Carbon.File.FSResolveAliasFile(file, 1)
|
||||||
break
|
break
|
||||||
except (Carbon.File.Error, ValueError):
|
except (Carbon.File.Error, ValueError):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise BuildError, "Template %s not found on sys.path" % `template`
|
raise BuildError, "Template %s not found on sys.path" % `template`
|
||||||
file = file.as_pathname()
|
file = file.as_pathname()
|
||||||
return file
|
return file
|
||||||
|
|
||||||
def process(template, filename, destname, copy_codefragment=0,
|
def process(template, filename, destname, copy_codefragment=0,
|
||||||
rsrcname=None, others=[], raw=0, progress="default"):
|
rsrcname=None, others=[], raw=0, progress="default"):
|
||||||
|
|
||||||
if progress == "default":
|
if progress == "default":
|
||||||
progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120)
|
progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120)
|
||||||
progress.label("Compiling...")
|
progress.label("Compiling...")
|
||||||
progress.inc(0)
|
progress.inc(0)
|
||||||
# check for the script name being longer than 32 chars. This may trigger a bug
|
# check for the script name being longer than 32 chars. This may trigger a bug
|
||||||
# on OSX that can destroy your sourcefile.
|
# on OSX that can destroy your sourcefile.
|
||||||
if '#' in os.path.split(filename)[1]:
|
if '#' in os.path.split(filename)[1]:
|
||||||
raise BuildError, "BuildApplet could destroy your sourcefile on OSX, please rename: %s" % filename
|
raise BuildError, "BuildApplet could destroy your sourcefile on OSX, please rename: %s" % filename
|
||||||
# Read the source and compile it
|
# Read the source and compile it
|
||||||
# (there's no point overwriting the destination if it has a syntax error)
|
# (there's no point overwriting the destination if it has a syntax error)
|
||||||
|
|
||||||
fp = open(filename, 'rU')
|
fp = open(filename, 'rU')
|
||||||
text = fp.read()
|
text = fp.read()
|
||||||
fp.close()
|
fp.close()
|
||||||
try:
|
try:
|
||||||
code = compile(text + '\n', filename, "exec")
|
code = compile(text + '\n', filename, "exec")
|
||||||
except SyntaxError, arg:
|
except SyntaxError, arg:
|
||||||
raise BuildError, "Syntax error in script %s: %s" % (filename, arg)
|
raise BuildError, "Syntax error in script %s: %s" % (filename, arg)
|
||||||
except EOFError:
|
except EOFError:
|
||||||
raise BuildError, "End-of-file in script %s" % (filename,)
|
raise BuildError, "End-of-file in script %s" % (filename,)
|
||||||
|
|
||||||
# Set the destination file name. Note that basename
|
# Set the destination file name. Note that basename
|
||||||
# does contain the whole filepath, only a .py is stripped.
|
# does contain the whole filepath, only a .py is stripped.
|
||||||
|
|
||||||
if string.lower(filename[-3:]) == ".py":
|
if string.lower(filename[-3:]) == ".py":
|
||||||
basename = filename[:-3]
|
basename = filename[:-3]
|
||||||
if MacOS.runtimemodel != 'macho' and not destname:
|
if MacOS.runtimemodel != 'macho' and not destname:
|
||||||
destname = basename
|
destname = basename
|
||||||
else:
|
else:
|
||||||
basename = filename
|
basename = filename
|
||||||
|
|
||||||
if not destname:
|
if not destname:
|
||||||
if MacOS.runtimemodel == 'macho':
|
if MacOS.runtimemodel == 'macho':
|
||||||
destname = basename + '.app'
|
destname = basename + '.app'
|
||||||
else:
|
else:
|
||||||
destname = basename + '.applet'
|
destname = basename + '.applet'
|
||||||
if not rsrcname:
|
if not rsrcname:
|
||||||
rsrcname = basename + '.rsrc'
|
rsrcname = basename + '.rsrc'
|
||||||
|
|
||||||
# Try removing the output file. This fails in MachO, but it should
|
# Try removing the output file. This fails in MachO, but it should
|
||||||
# do any harm.
|
# do any harm.
|
||||||
try:
|
try:
|
||||||
os.remove(destname)
|
os.remove(destname)
|
||||||
except os.error:
|
except os.error:
|
||||||
pass
|
pass
|
||||||
process_common(template, progress, code, rsrcname, destname, 0,
|
process_common(template, progress, code, rsrcname, destname, 0,
|
||||||
copy_codefragment, raw, others, filename)
|
copy_codefragment, raw, others, filename)
|
||||||
|
|
||||||
|
|
||||||
def update(template, filename, output):
|
def update(template, filename, output):
|
||||||
if MacOS.runtimemodel == 'macho':
|
if MacOS.runtimemodel == 'macho':
|
||||||
raise BuildError, "No updating yet for MachO applets"
|
raise BuildError, "No updating yet for MachO applets"
|
||||||
if progress:
|
if progress:
|
||||||
progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120)
|
progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120)
|
||||||
else:
|
else:
|
||||||
progress = None
|
progress = None
|
||||||
if not output:
|
if not output:
|
||||||
output = filename + ' (updated)'
|
output = filename + ' (updated)'
|
||||||
|
|
||||||
# Try removing the output file
|
# Try removing the output file
|
||||||
try:
|
try:
|
||||||
os.remove(output)
|
os.remove(output)
|
||||||
except os.error:
|
except os.error:
|
||||||
pass
|
pass
|
||||||
process_common(template, progress, None, filename, output, 1, 1)
|
process_common(template, progress, None, filename, output, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
def process_common(template, progress, code, rsrcname, destname, is_update,
|
def process_common(template, progress, code, rsrcname, destname, is_update,
|
||||||
copy_codefragment, raw=0, others=[], filename=None):
|
copy_codefragment, raw=0, others=[], filename=None):
|
||||||
if MacOS.runtimemodel == 'macho':
|
if MacOS.runtimemodel == 'macho':
|
||||||
return process_common_macho(template, progress, code, rsrcname, destname,
|
return process_common_macho(template, progress, code, rsrcname, destname,
|
||||||
is_update, raw, others, filename)
|
is_update, raw, others, filename)
|
||||||
if others:
|
if others:
|
||||||
raise BuildError, "Extra files only allowed for MachoPython applets"
|
raise BuildError, "Extra files only allowed for MachoPython applets"
|
||||||
# Create FSSpecs for the various files
|
# Create FSSpecs for the various files
|
||||||
template_fsr, d1, d2 = Carbon.File.FSResolveAliasFile(template, 1)
|
template_fsr, d1, d2 = Carbon.File.FSResolveAliasFile(template, 1)
|
||||||
template = template_fsr.as_pathname()
|
template = template_fsr.as_pathname()
|
||||||
|
|
||||||
# Copy data (not resources, yet) from the template
|
# Copy data (not resources, yet) from the template
|
||||||
if progress:
|
if progress:
|
||||||
progress.label("Copy data fork...")
|
progress.label("Copy data fork...")
|
||||||
progress.set(10)
|
progress.set(10)
|
||||||
|
|
||||||
if copy_codefragment:
|
if copy_codefragment:
|
||||||
tmpl = open(template, "rb")
|
tmpl = open(template, "rb")
|
||||||
dest = open(destname, "wb")
|
dest = open(destname, "wb")
|
||||||
data = tmpl.read()
|
data = tmpl.read()
|
||||||
if data:
|
if data:
|
||||||
dest.write(data)
|
dest.write(data)
|
||||||
dest.close()
|
dest.close()
|
||||||
tmpl.close()
|
tmpl.close()
|
||||||
del dest
|
del dest
|
||||||
del tmpl
|
del tmpl
|
||||||
|
|
||||||
# Open the output resource fork
|
# Open the output resource fork
|
||||||
|
|
||||||
if progress:
|
if progress:
|
||||||
progress.label("Copy resources...")
|
progress.label("Copy resources...")
|
||||||
progress.set(20)
|
progress.set(20)
|
||||||
try:
|
try:
|
||||||
output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)
|
output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)
|
||||||
except MacOS.Error:
|
except MacOS.Error:
|
||||||
destdir, destfile = os.path.split(destname)
|
destdir, destfile = os.path.split(destname)
|
||||||
Res.FSCreateResourceFile(destdir, unicode(destfile), RESOURCE_FORK_NAME)
|
Res.FSCreateResourceFile(destdir, unicode(destfile), RESOURCE_FORK_NAME)
|
||||||
output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)
|
output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)
|
||||||
|
|
||||||
# Copy the resources from the target specific resource template, if any
|
# Copy the resources from the target specific resource template, if any
|
||||||
typesfound, ownertype = [], None
|
typesfound, ownertype = [], None
|
||||||
try:
|
try:
|
||||||
input = Res.FSOpenResourceFile(rsrcname, RESOURCE_FORK_NAME, READ)
|
input = Res.FSOpenResourceFile(rsrcname, RESOURCE_FORK_NAME, READ)
|
||||||
except (MacOS.Error, ValueError):
|
except (MacOS.Error, ValueError):
|
||||||
pass
|
pass
|
||||||
if progress:
|
if progress:
|
||||||
progress.inc(50)
|
progress.inc(50)
|
||||||
else:
|
else:
|
||||||
if is_update:
|
if is_update:
|
||||||
skip_oldfile = ['cfrg']
|
skip_oldfile = ['cfrg']
|
||||||
else:
|
else:
|
||||||
skip_oldfile = []
|
skip_oldfile = []
|
||||||
typesfound, ownertype = copyres(input, output, skip_oldfile, 0, progress)
|
typesfound, ownertype = copyres(input, output, skip_oldfile, 0, progress)
|
||||||
Res.CloseResFile(input)
|
Res.CloseResFile(input)
|
||||||
|
|
||||||
# Check which resource-types we should not copy from the template
|
# Check which resource-types we should not copy from the template
|
||||||
skiptypes = []
|
skiptypes = []
|
||||||
if 'vers' in typesfound: skiptypes.append('vers')
|
if 'vers' in typesfound: skiptypes.append('vers')
|
||||||
if 'SIZE' in typesfound: skiptypes.append('SIZE')
|
if 'SIZE' in typesfound: skiptypes.append('SIZE')
|
||||||
if 'BNDL' in typesfound: skiptypes = skiptypes + ['BNDL', 'FREF', 'icl4',
|
if 'BNDL' in typesfound: skiptypes = skiptypes + ['BNDL', 'FREF', 'icl4',
|
||||||
'icl8', 'ics4', 'ics8', 'ICN#', 'ics#']
|
'icl8', 'ics4', 'ics8', 'ICN#', 'ics#']
|
||||||
if not copy_codefragment:
|
if not copy_codefragment:
|
||||||
skiptypes.append('cfrg')
|
skiptypes.append('cfrg')
|
||||||
## skipowner = (ownertype <> None)
|
## skipowner = (ownertype <> None)
|
||||||
|
|
||||||
# Copy the resources from the template
|
# Copy the resources from the template
|
||||||
|
|
||||||
input = Res.FSOpenResourceFile(template, RESOURCE_FORK_NAME, READ)
|
input = Res.FSOpenResourceFile(template, RESOURCE_FORK_NAME, READ)
|
||||||
dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)
|
dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)
|
||||||
|
|
||||||
Res.CloseResFile(input)
|
Res.CloseResFile(input)
|
||||||
## if ownertype == None:
|
## if ownertype == None:
|
||||||
## raise BuildError, "No owner resource found in either resource file or template"
|
## raise BuildError, "No owner resource found in either resource file or template"
|
||||||
# Make sure we're manipulating the output resource file now
|
# Make sure we're manipulating the output resource file now
|
||||||
|
|
||||||
Res.UseResFile(output)
|
Res.UseResFile(output)
|
||||||
|
|
||||||
if ownertype == None:
|
if ownertype == None:
|
||||||
# No owner resource in the template. We have skipped the
|
# No owner resource in the template. We have skipped the
|
||||||
# Python owner resource, so we have to add our own. The relevant
|
# Python owner resource, so we have to add our own. The relevant
|
||||||
# bundle stuff is already included in the interpret/applet template.
|
# bundle stuff is already included in the interpret/applet template.
|
||||||
newres = Res.Resource('\0')
|
newres = Res.Resource('\0')
|
||||||
newres.AddResource(DEFAULT_APPLET_CREATOR, 0, "Owner resource")
|
newres.AddResource(DEFAULT_APPLET_CREATOR, 0, "Owner resource")
|
||||||
ownertype = DEFAULT_APPLET_CREATOR
|
ownertype = DEFAULT_APPLET_CREATOR
|
||||||
|
|
||||||
if code:
|
if code:
|
||||||
# Delete any existing 'PYC ' resource named __main__
|
# Delete any existing 'PYC ' resource named __main__
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = Res.Get1NamedResource(RESTYPE, RESNAME)
|
res = Res.Get1NamedResource(RESTYPE, RESNAME)
|
||||||
res.RemoveResource()
|
res.RemoveResource()
|
||||||
except Res.Error:
|
except Res.Error:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Create the raw data for the resource from the code object
|
# Create the raw data for the resource from the code object
|
||||||
if progress:
|
if progress:
|
||||||
progress.label("Write PYC resource...")
|
progress.label("Write PYC resource...")
|
||||||
progress.set(120)
|
progress.set(120)
|
||||||
|
|
||||||
data = marshal.dumps(code)
|
data = marshal.dumps(code)
|
||||||
del code
|
del code
|
||||||
data = (MAGIC + '\0\0\0\0') + data
|
data = (MAGIC + '\0\0\0\0') + data
|
||||||
|
|
||||||
# Create the resource and write it
|
# Create the resource and write it
|
||||||
|
|
||||||
id = 0
|
id = 0
|
||||||
while id < 128:
|
while id < 128:
|
||||||
id = Res.Unique1ID(RESTYPE)
|
id = Res.Unique1ID(RESTYPE)
|
||||||
res = Res.Resource(data)
|
res = Res.Resource(data)
|
||||||
res.AddResource(RESTYPE, id, RESNAME)
|
res.AddResource(RESTYPE, id, RESNAME)
|
||||||
attrs = res.GetResAttrs()
|
attrs = res.GetResAttrs()
|
||||||
attrs = attrs | 0x04 # set preload
|
attrs = attrs | 0x04 # set preload
|
||||||
res.SetResAttrs(attrs)
|
res.SetResAttrs(attrs)
|
||||||
res.WriteResource()
|
res.WriteResource()
|
||||||
res.ReleaseResource()
|
res.ReleaseResource()
|
||||||
|
|
||||||
# Close the output file
|
# Close the output file
|
||||||
|
|
||||||
Res.CloseResFile(output)
|
Res.CloseResFile(output)
|
||||||
|
|
||||||
# Now set the creator, type and bundle bit of the destination.
|
# Now set the creator, type and bundle bit of the destination.
|
||||||
# Done with FSSpec's, FSRef FInfo isn't good enough yet (2.3a1+)
|
# Done with FSSpec's, FSRef FInfo isn't good enough yet (2.3a1+)
|
||||||
dest_fss = Carbon.File.FSSpec(destname)
|
dest_fss = Carbon.File.FSSpec(destname)
|
||||||
dest_finfo = dest_fss.FSpGetFInfo()
|
dest_finfo = dest_fss.FSpGetFInfo()
|
||||||
dest_finfo.Creator = ownertype
|
dest_finfo.Creator = ownertype
|
||||||
dest_finfo.Type = 'APPL'
|
dest_finfo.Type = 'APPL'
|
||||||
dest_finfo.Flags = dest_finfo.Flags | Carbon.Files.kHasBundle | Carbon.Files.kIsShared
|
dest_finfo.Flags = dest_finfo.Flags | Carbon.Files.kHasBundle | Carbon.Files.kIsShared
|
||||||
dest_finfo.Flags = dest_finfo.Flags & ~Carbon.Files.kHasBeenInited
|
dest_finfo.Flags = dest_finfo.Flags & ~Carbon.Files.kHasBeenInited
|
||||||
dest_fss.FSpSetFInfo(dest_finfo)
|
dest_fss.FSpSetFInfo(dest_finfo)
|
||||||
|
|
||||||
macostools.touched(destname)
|
macostools.touched(destname)
|
||||||
if progress:
|
if progress:
|
||||||
progress.label("Done.")
|
progress.label("Done.")
|
||||||
progress.inc(0)
|
progress.inc(0)
|
||||||
|
|
||||||
def process_common_macho(template, progress, code, rsrcname, destname, is_update,
|
def process_common_macho(template, progress, code, rsrcname, destname, is_update,
|
||||||
raw=0, others=[], filename=None):
|
raw=0, others=[], filename=None):
|
||||||
# Check that we have a filename
|
# Check that we have a filename
|
||||||
if filename is None:
|
if filename is None:
|
||||||
raise BuildError, "Need source filename on MacOSX"
|
raise BuildError, "Need source filename on MacOSX"
|
||||||
# First make sure the name ends in ".app"
|
# First make sure the name ends in ".app"
|
||||||
if destname[-4:] != '.app':
|
if destname[-4:] != '.app':
|
||||||
destname = destname + '.app'
|
destname = destname + '.app'
|
||||||
# Now deduce the short name
|
# Now deduce the short name
|
||||||
destdir, shortname = os.path.split(destname)
|
destdir, shortname = os.path.split(destname)
|
||||||
if shortname[-4:] == '.app':
|
if shortname[-4:] == '.app':
|
||||||
# Strip the .app suffix
|
# Strip the .app suffix
|
||||||
shortname = shortname[:-4]
|
shortname = shortname[:-4]
|
||||||
# And deduce the .plist and .icns names
|
# And deduce the .plist and .icns names
|
||||||
plistname = None
|
plistname = None
|
||||||
icnsname = None
|
icnsname = None
|
||||||
if rsrcname and rsrcname[-5:] == '.rsrc':
|
if rsrcname and rsrcname[-5:] == '.rsrc':
|
||||||
tmp = rsrcname[:-5]
|
tmp = rsrcname[:-5]
|
||||||
plistname = tmp + '.plist'
|
plistname = tmp + '.plist'
|
||||||
if os.path.exists(plistname):
|
if os.path.exists(plistname):
|
||||||
icnsname = tmp + '.icns'
|
icnsname = tmp + '.icns'
|
||||||
if not os.path.exists(icnsname):
|
if not os.path.exists(icnsname):
|
||||||
icnsname = None
|
icnsname = None
|
||||||
else:
|
else:
|
||||||
plistname = None
|
plistname = None
|
||||||
if not os.path.exists(rsrcname):
|
if not os.path.exists(rsrcname):
|
||||||
rsrcname = None
|
rsrcname = None
|
||||||
if progress:
|
if progress:
|
||||||
progress.label('Creating bundle...')
|
progress.label('Creating bundle...')
|
||||||
import bundlebuilder
|
import bundlebuilder
|
||||||
builder = bundlebuilder.AppBuilder(verbosity=0)
|
builder = bundlebuilder.AppBuilder(verbosity=0)
|
||||||
builder.mainprogram = filename
|
builder.mainprogram = filename
|
||||||
builder.builddir = destdir
|
builder.builddir = destdir
|
||||||
builder.name = shortname
|
builder.name = shortname
|
||||||
if rsrcname:
|
if rsrcname:
|
||||||
realrsrcname = macresource.resource_pathname(rsrcname)
|
realrsrcname = macresource.resource_pathname(rsrcname)
|
||||||
builder.files.append((realrsrcname,
|
builder.files.append((realrsrcname,
|
||||||
os.path.join('Contents/Resources', os.path.basename(rsrcname))))
|
os.path.join('Contents/Resources', os.path.basename(rsrcname))))
|
||||||
for o in others:
|
for o in others:
|
||||||
if type(o) == str:
|
if type(o) == str:
|
||||||
builder.resources.append(o)
|
builder.resources.append(o)
|
||||||
else:
|
else:
|
||||||
builder.files.append(o)
|
builder.files.append(o)
|
||||||
if plistname:
|
if plistname:
|
||||||
import plistlib
|
import plistlib
|
||||||
builder.plist = plistlib.Plist.fromFile(plistname)
|
builder.plist = plistlib.Plist.fromFile(plistname)
|
||||||
if icnsname:
|
if icnsname:
|
||||||
builder.iconfile = icnsname
|
builder.iconfile = icnsname
|
||||||
if not raw:
|
if not raw:
|
||||||
builder.argv_emulation = 1
|
builder.argv_emulation = 1
|
||||||
builder.setup()
|
builder.setup()
|
||||||
builder.build()
|
builder.build()
|
||||||
if progress:
|
if progress:
|
||||||
progress.label('Done.')
|
progress.label('Done.')
|
||||||
progress.inc(0)
|
progress.inc(0)
|
||||||
|
|
||||||
## macostools.touched(dest_fss)
|
## macostools.touched(dest_fss)
|
||||||
|
|
||||||
# Copy resources between two resource file descriptors.
|
# Copy resources between two resource file descriptors.
|
||||||
# skip a resource named '__main__' or (if skipowner is set) with ID zero.
|
# skip a resource named '__main__' or (if skipowner is set) with ID zero.
|
||||||
# Also skip resources with a type listed in skiptypes.
|
# Also skip resources with a type listed in skiptypes.
|
||||||
#
|
#
|
||||||
def copyres(input, output, skiptypes, skipowner, progress=None):
|
def copyres(input, output, skiptypes, skipowner, progress=None):
|
||||||
ctor = None
|
ctor = None
|
||||||
alltypes = []
|
alltypes = []
|
||||||
Res.UseResFile(input)
|
Res.UseResFile(input)
|
||||||
ntypes = Res.Count1Types()
|
ntypes = Res.Count1Types()
|
||||||
progress_type_inc = 50/ntypes
|
progress_type_inc = 50/ntypes
|
||||||
for itype in range(1, 1+ntypes):
|
for itype in range(1, 1+ntypes):
|
||||||
type = Res.Get1IndType(itype)
|
type = Res.Get1IndType(itype)
|
||||||
if type in skiptypes:
|
if type in skiptypes:
|
||||||
continue
|
continue
|
||||||
alltypes.append(type)
|
alltypes.append(type)
|
||||||
nresources = Res.Count1Resources(type)
|
nresources = Res.Count1Resources(type)
|
||||||
progress_cur_inc = progress_type_inc/nresources
|
progress_cur_inc = progress_type_inc/nresources
|
||||||
for ires in range(1, 1+nresources):
|
for ires in range(1, 1+nresources):
|
||||||
res = Res.Get1IndResource(type, ires)
|
res = Res.Get1IndResource(type, ires)
|
||||||
id, type, name = res.GetResInfo()
|
id, type, name = res.GetResInfo()
|
||||||
lcname = string.lower(name)
|
lcname = string.lower(name)
|
||||||
|
|
||||||
if lcname == OWNERNAME and id == 0:
|
if lcname == OWNERNAME and id == 0:
|
||||||
if skipowner:
|
if skipowner:
|
||||||
continue # Skip this one
|
continue # Skip this one
|
||||||
else:
|
else:
|
||||||
ctor = type
|
ctor = type
|
||||||
size = res.size
|
size = res.size
|
||||||
attrs = res.GetResAttrs()
|
attrs = res.GetResAttrs()
|
||||||
if progress:
|
if progress:
|
||||||
progress.label("Copy %s %d %s"%(type, id, name))
|
progress.label("Copy %s %d %s"%(type, id, name))
|
||||||
progress.inc(progress_cur_inc)
|
progress.inc(progress_cur_inc)
|
||||||
res.LoadResource()
|
res.LoadResource()
|
||||||
res.DetachResource()
|
res.DetachResource()
|
||||||
Res.UseResFile(output)
|
Res.UseResFile(output)
|
||||||
try:
|
try:
|
||||||
res2 = Res.Get1Resource(type, id)
|
res2 = Res.Get1Resource(type, id)
|
||||||
except MacOS.Error:
|
except MacOS.Error:
|
||||||
res2 = None
|
res2 = None
|
||||||
if res2:
|
if res2:
|
||||||
if progress:
|
if progress:
|
||||||
progress.label("Overwrite %s %d %s"%(type, id, name))
|
progress.label("Overwrite %s %d %s"%(type, id, name))
|
||||||
progress.inc(0)
|
progress.inc(0)
|
||||||
res2.RemoveResource()
|
res2.RemoveResource()
|
||||||
res.AddResource(type, id, name)
|
res.AddResource(type, id, name)
|
||||||
res.WriteResource()
|
res.WriteResource()
|
||||||
attrs = attrs | res.GetResAttrs()
|
attrs = attrs | res.GetResAttrs()
|
||||||
res.SetResAttrs(attrs)
|
res.SetResAttrs(attrs)
|
||||||
Res.UseResFile(input)
|
Res.UseResFile(input)
|
||||||
return alltypes, ctor
|
return alltypes, ctor
|
||||||
|
|
||||||
def copyapptree(srctree, dsttree, exceptlist=[], progress=None):
|
def copyapptree(srctree, dsttree, exceptlist=[], progress=None):
|
||||||
names = []
|
names = []
|
||||||
if os.path.exists(dsttree):
|
if os.path.exists(dsttree):
|
||||||
shutil.rmtree(dsttree)
|
shutil.rmtree(dsttree)
|
||||||
os.mkdir(dsttree)
|
os.mkdir(dsttree)
|
||||||
todo = os.listdir(srctree)
|
todo = os.listdir(srctree)
|
||||||
while todo:
|
while todo:
|
||||||
this, todo = todo[0], todo[1:]
|
this, todo = todo[0], todo[1:]
|
||||||
if this in exceptlist:
|
if this in exceptlist:
|
||||||
continue
|
continue
|
||||||
thispath = os.path.join(srctree, this)
|
thispath = os.path.join(srctree, this)
|
||||||
if os.path.isdir(thispath):
|
if os.path.isdir(thispath):
|
||||||
thiscontent = os.listdir(thispath)
|
thiscontent = os.listdir(thispath)
|
||||||
for t in thiscontent:
|
for t in thiscontent:
|
||||||
todo.append(os.path.join(this, t))
|
todo.append(os.path.join(this, t))
|
||||||
names.append(this)
|
names.append(this)
|
||||||
for this in names:
|
for this in names:
|
||||||
srcpath = os.path.join(srctree, this)
|
srcpath = os.path.join(srctree, this)
|
||||||
dstpath = os.path.join(dsttree, this)
|
dstpath = os.path.join(dsttree, this)
|
||||||
if os.path.isdir(srcpath):
|
if os.path.isdir(srcpath):
|
||||||
os.mkdir(dstpath)
|
os.mkdir(dstpath)
|
||||||
elif os.path.islink(srcpath):
|
elif os.path.islink(srcpath):
|
||||||
endpoint = os.readlink(srcpath)
|
endpoint = os.readlink(srcpath)
|
||||||
os.symlink(endpoint, dstpath)
|
os.symlink(endpoint, dstpath)
|
||||||
else:
|
else:
|
||||||
if progress:
|
if progress:
|
||||||
progress.label('Copy '+this)
|
progress.label('Copy '+this)
|
||||||
progress.inc(0)
|
progress.inc(0)
|
||||||
shutil.copy2(srcpath, dstpath)
|
shutil.copy2(srcpath, dstpath)
|
||||||
|
|
||||||
def writepycfile(codeobject, cfile):
|
def writepycfile(codeobject, cfile):
|
||||||
import marshal
|
import marshal
|
||||||
fc = open(cfile, 'wb')
|
fc = open(cfile, 'wb')
|
||||||
fc.write('\0\0\0\0') # MAGIC placeholder, written later
|
fc.write('\0\0\0\0') # MAGIC placeholder, written later
|
||||||
fc.write('\0\0\0\0') # Timestap placeholder, not needed
|
fc.write('\0\0\0\0') # Timestap placeholder, not needed
|
||||||
marshal.dump(codeobject, fc)
|
marshal.dump(codeobject, fc)
|
||||||
fc.flush()
|
fc.flush()
|
||||||
fc.seek(0, 0)
|
fc.seek(0, 0)
|
||||||
fc.write(MAGIC)
|
fc.write(MAGIC)
|
||||||
fc.close()
|
fc.close()
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,167 +18,167 @@ error = "cfm.error"
|
||||||
BUFSIZE = 0x80000
|
BUFSIZE = 0x80000
|
||||||
|
|
||||||
def mergecfmfiles(srclist, dst, architecture = 'fat'):
|
def mergecfmfiles(srclist, dst, architecture = 'fat'):
|
||||||
"""Merge all files in srclist into a new file dst.
|
"""Merge all files in srclist into a new file dst.
|
||||||
|
|
||||||
If architecture is given, only code fragments of that type will be used:
|
If architecture is given, only code fragments of that type will be used:
|
||||||
"pwpc" for PPC, "m68k" for cfm68k. This does not work for "classic"
|
"pwpc" for PPC, "m68k" for cfm68k. This does not work for "classic"
|
||||||
68k code, since it does not use code fragments to begin with.
|
68k code, since it does not use code fragments to begin with.
|
||||||
If architecture is None, all fragments will be used, enabling FAT binaries.
|
If architecture is None, all fragments will be used, enabling FAT binaries.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
srclist = list(srclist)
|
srclist = list(srclist)
|
||||||
for i in range(len(srclist)):
|
for i in range(len(srclist)):
|
||||||
srclist[i] = Carbon.File.pathname(srclist[i])
|
srclist[i] = Carbon.File.pathname(srclist[i])
|
||||||
dst = Carbon.File.pathname(dst)
|
dst = Carbon.File.pathname(dst)
|
||||||
|
|
||||||
dstfile = open(dst, "wb")
|
dstfile = open(dst, "wb")
|
||||||
rf = Res.FSpOpenResFile(dst, 3)
|
rf = Res.FSpOpenResFile(dst, 3)
|
||||||
try:
|
try:
|
||||||
dstcfrg = CfrgResource()
|
dstcfrg = CfrgResource()
|
||||||
for src in srclist:
|
for src in srclist:
|
||||||
srccfrg = CfrgResource(src)
|
srccfrg = CfrgResource(src)
|
||||||
for frag in srccfrg.fragments:
|
for frag in srccfrg.fragments:
|
||||||
if frag.architecture == 'pwpc' and architecture == 'm68k':
|
if frag.architecture == 'pwpc' and architecture == 'm68k':
|
||||||
continue
|
continue
|
||||||
if frag.architecture == 'm68k' and architecture == 'pwpc':
|
if frag.architecture == 'm68k' and architecture == 'pwpc':
|
||||||
continue
|
continue
|
||||||
dstcfrg.append(frag)
|
dstcfrg.append(frag)
|
||||||
|
|
||||||
frag.copydata(dstfile)
|
frag.copydata(dstfile)
|
||||||
|
|
||||||
cfrgres = Res.Resource(dstcfrg.build())
|
cfrgres = Res.Resource(dstcfrg.build())
|
||||||
Res.UseResFile(rf)
|
Res.UseResFile(rf)
|
||||||
cfrgres.AddResource('cfrg', 0, "")
|
cfrgres.AddResource('cfrg', 0, "")
|
||||||
finally:
|
finally:
|
||||||
dstfile.close()
|
dstfile.close()
|
||||||
rf = Res.CloseResFile(rf)
|
rf = Res.CloseResFile(rf)
|
||||||
|
|
||||||
|
|
||||||
class CfrgResource:
|
class CfrgResource:
|
||||||
|
|
||||||
def __init__(self, path = None):
|
def __init__(self, path = None):
|
||||||
self.version = 1
|
self.version = 1
|
||||||
self.fragments = []
|
self.fragments = []
|
||||||
self.path = path
|
self.path = path
|
||||||
if path is not None and os.path.exists(path):
|
if path is not None and os.path.exists(path):
|
||||||
currentresref = Res.CurResFile()
|
currentresref = Res.CurResFile()
|
||||||
resref = Res.FSpOpenResFile(path, 1)
|
resref = Res.FSpOpenResFile(path, 1)
|
||||||
Res.UseResFile(resref)
|
Res.UseResFile(resref)
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
data = Res.Get1Resource('cfrg', 0).data
|
data = Res.Get1Resource('cfrg', 0).data
|
||||||
except Res.Error:
|
except Res.Error:
|
||||||
raise Res.Error, "no 'cfrg' resource found", sys.exc_traceback
|
raise Res.Error, "no 'cfrg' resource found", sys.exc_traceback
|
||||||
finally:
|
finally:
|
||||||
Res.CloseResFile(resref)
|
Res.CloseResFile(resref)
|
||||||
Res.UseResFile(currentresref)
|
Res.UseResFile(currentresref)
|
||||||
self.parse(data)
|
self.parse(data)
|
||||||
if self.version <> 1:
|
if self.version <> 1:
|
||||||
raise error, "unknown 'cfrg' resource format"
|
raise error, "unknown 'cfrg' resource format"
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
(res1, res2, self.version,
|
(res1, res2, self.version,
|
||||||
res3, res4, res5, res6,
|
res3, res4, res5, res6,
|
||||||
self.memberCount) = struct.unpack("8l", data[:32])
|
self.memberCount) = struct.unpack("8l", data[:32])
|
||||||
data = data[32:]
|
data = data[32:]
|
||||||
while data:
|
while data:
|
||||||
frag = FragmentDescriptor(self.path, data)
|
frag = FragmentDescriptor(self.path, data)
|
||||||
data = data[frag.memberSize:]
|
data = data[frag.memberSize:]
|
||||||
self.fragments.append(frag)
|
self.fragments.append(frag)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.memberCount = len(self.fragments)
|
self.memberCount = len(self.fragments)
|
||||||
data = struct.pack("8l", 0, 0, self.version, 0, 0, 0, 0, self.memberCount)
|
data = struct.pack("8l", 0, 0, self.version, 0, 0, 0, 0, self.memberCount)
|
||||||
for frag in self.fragments:
|
for frag in self.fragments:
|
||||||
data = data + frag.build()
|
data = data + frag.build()
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def append(self, frag):
|
def append(self, frag):
|
||||||
self.fragments.append(frag)
|
self.fragments.append(frag)
|
||||||
|
|
||||||
|
|
||||||
class FragmentDescriptor:
|
class FragmentDescriptor:
|
||||||
|
|
||||||
def __init__(self, path, data = None):
|
def __init__(self, path, data = None):
|
||||||
self.path = path
|
self.path = path
|
||||||
if data is not None:
|
if data is not None:
|
||||||
self.parse(data)
|
self.parse(data)
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
self.architecture = data[:4]
|
self.architecture = data[:4]
|
||||||
( self.updatelevel,
|
( self.updatelevel,
|
||||||
self.currentVersion,
|
self.currentVersion,
|
||||||
self.oldDefVersion,
|
self.oldDefVersion,
|
||||||
self.stacksize,
|
self.stacksize,
|
||||||
self.applibdir,
|
self.applibdir,
|
||||||
self.fragtype,
|
self.fragtype,
|
||||||
self.where,
|
self.where,
|
||||||
self.offset,
|
self.offset,
|
||||||
self.length,
|
self.length,
|
||||||
self.res1, self.res2,
|
self.res1, self.res2,
|
||||||
self.memberSize,) = struct.unpack("4lhBB4lh", data[4:42])
|
self.memberSize,) = struct.unpack("4lhBB4lh", data[4:42])
|
||||||
pname = data[42:self.memberSize]
|
pname = data[42:self.memberSize]
|
||||||
self.name = pname[1:1+ord(pname[0])]
|
self.name = pname[1:1+ord(pname[0])]
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
data = self.architecture
|
data = self.architecture
|
||||||
data = data + struct.pack("4lhBB4l",
|
data = data + struct.pack("4lhBB4l",
|
||||||
self.updatelevel,
|
self.updatelevel,
|
||||||
self.currentVersion,
|
self.currentVersion,
|
||||||
self.oldDefVersion,
|
self.oldDefVersion,
|
||||||
self.stacksize,
|
self.stacksize,
|
||||||
self.applibdir,
|
self.applibdir,
|
||||||
self.fragtype,
|
self.fragtype,
|
||||||
self.where,
|
self.where,
|
||||||
self.offset,
|
self.offset,
|
||||||
self.length,
|
self.length,
|
||||||
self.res1, self.res2)
|
self.res1, self.res2)
|
||||||
self.memberSize = len(data) + 2 + 1 + len(self.name)
|
self.memberSize = len(data) + 2 + 1 + len(self.name)
|
||||||
# pad to 4 byte boundaries
|
# pad to 4 byte boundaries
|
||||||
if self.memberSize % 4:
|
if self.memberSize % 4:
|
||||||
self.memberSize = self.memberSize + 4 - (self.memberSize % 4)
|
self.memberSize = self.memberSize + 4 - (self.memberSize % 4)
|
||||||
data = data + struct.pack("hb", self.memberSize, len(self.name))
|
data = data + struct.pack("hb", self.memberSize, len(self.name))
|
||||||
data = data + self.name
|
data = data + self.name
|
||||||
data = data + '\000' * (self.memberSize - len(data))
|
data = data + '\000' * (self.memberSize - len(data))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def getfragment(self):
|
def getfragment(self):
|
||||||
if self.where <> 1:
|
if self.where <> 1:
|
||||||
raise error, "can't read fragment, unsupported location"
|
raise error, "can't read fragment, unsupported location"
|
||||||
f = open(self.path, "rb")
|
f = open(self.path, "rb")
|
||||||
f.seek(self.offset)
|
f.seek(self.offset)
|
||||||
if self.length:
|
if self.length:
|
||||||
frag = f.read(self.length)
|
frag = f.read(self.length)
|
||||||
else:
|
else:
|
||||||
frag = f.read()
|
frag = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
return frag
|
return frag
|
||||||
|
|
||||||
def copydata(self, outfile):
|
def copydata(self, outfile):
|
||||||
if self.where <> 1:
|
if self.where <> 1:
|
||||||
raise error, "can't read fragment, unsupported location"
|
raise error, "can't read fragment, unsupported location"
|
||||||
infile = open(self.path, "rb")
|
infile = open(self.path, "rb")
|
||||||
if self.length == 0:
|
if self.length == 0:
|
||||||
infile.seek(0, 2)
|
infile.seek(0, 2)
|
||||||
self.length = infile.tell()
|
self.length = infile.tell()
|
||||||
|
|
||||||
# Position input file and record new offset from output file
|
# Position input file and record new offset from output file
|
||||||
infile.seek(self.offset)
|
infile.seek(self.offset)
|
||||||
|
|
||||||
# pad to 16 byte boundaries
|
# pad to 16 byte boundaries
|
||||||
offset = outfile.tell()
|
offset = outfile.tell()
|
||||||
if offset % 16:
|
if offset % 16:
|
||||||
offset = offset + 16 - (offset % 16)
|
offset = offset + 16 - (offset % 16)
|
||||||
outfile.seek(offset)
|
outfile.seek(offset)
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
l = self.length
|
l = self.length
|
||||||
while l:
|
while l:
|
||||||
if l > BUFSIZE:
|
if l > BUFSIZE:
|
||||||
outfile.write(infile.read(BUFSIZE))
|
outfile.write(infile.read(BUFSIZE))
|
||||||
l = l - BUFSIZE
|
l = l - BUFSIZE
|
||||||
else:
|
else:
|
||||||
outfile.write(infile.read(l))
|
outfile.write(infile.read(l))
|
||||||
l = 0
|
l = 0
|
||||||
infile.close()
|
infile.close()
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -11,16 +11,16 @@ import macostools
|
||||||
error=icglue.error
|
error=icglue.error
|
||||||
|
|
||||||
# From ictypes.h:
|
# From ictypes.h:
|
||||||
icPrefNotFoundErr = -666 # preference not found (duh!)
|
icPrefNotFoundErr = -666 # preference not found (duh!)
|
||||||
icPermErr = -667 # cannot set preference
|
icPermErr = -667 # cannot set preference
|
||||||
icPrefDataErr = -668 # problem with preference data
|
icPrefDataErr = -668 # problem with preference data
|
||||||
icInternalErr = -669 # hmm, this is not good
|
icInternalErr = -669 # hmm, this is not good
|
||||||
icTruncatedErr = -670 # more data was present than was returned
|
icTruncatedErr = -670 # more data was present than was returned
|
||||||
icNoMoreWritersErr = -671 # you cannot begin a write session because someone else is already doing it */
|
icNoMoreWritersErr = -671 # you cannot begin a write session because someone else is already doing it */
|
||||||
icNothingToOverrideErr = -672 # no component for the override component to capture
|
icNothingToOverrideErr = -672 # no component for the override component to capture
|
||||||
icNoURLErr = -673 # no URL found
|
icNoURLErr = -673 # no URL found
|
||||||
icConfigNotFoundErr = -674 # no configuration was found
|
icConfigNotFoundErr = -674 # no configuration was found
|
||||||
icConfigInappropriateErr = -675 # incorrect manufacturer code
|
icConfigInappropriateErr = -675 # incorrect manufacturer code
|
||||||
|
|
||||||
ICattr_no_change = -1
|
ICattr_no_change = -1
|
||||||
|
|
||||||
|
@ -30,240 +30,240 @@ icReadWritePerm = 2
|
||||||
# End of ictypes.h
|
# End of ictypes.h
|
||||||
|
|
||||||
class ICOpaqueData:
|
class ICOpaqueData:
|
||||||
"""An unparseable IC entry"""
|
"""An unparseable IC entry"""
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "ICOpaqueData(%s)"%`self.data`
|
return "ICOpaqueData(%s)"%`self.data`
|
||||||
|
|
||||||
_ICOpaqueDataType=type(ICOpaqueData(''))
|
_ICOpaqueDataType=type(ICOpaqueData(''))
|
||||||
|
|
||||||
def _decode_default(data, key):
|
def _decode_default(data, key):
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
return data
|
return data
|
||||||
if ord(data[0]) == len(data)-1:
|
if ord(data[0]) == len(data)-1:
|
||||||
# Assume Pstring
|
# Assume Pstring
|
||||||
return data[1:]
|
return data[1:]
|
||||||
return ICOpaqueData(data)
|
return ICOpaqueData(data)
|
||||||
|
|
||||||
|
|
||||||
def _decode_multistr(data, key):
|
def _decode_multistr(data, key):
|
||||||
numstr = ord(data[0]) << 8 | ord(data[1])
|
numstr = ord(data[0]) << 8 | ord(data[1])
|
||||||
rv = []
|
rv = []
|
||||||
ptr = 2
|
ptr = 2
|
||||||
for i in range(numstr):
|
for i in range(numstr):
|
||||||
strlen = ord(data[ptr])
|
strlen = ord(data[ptr])
|
||||||
str = data[ptr+1:ptr+strlen+1]
|
str = data[ptr+1:ptr+strlen+1]
|
||||||
rv.append(str)
|
rv.append(str)
|
||||||
ptr = ptr + strlen + 1
|
ptr = ptr + strlen + 1
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def _decode_fontrecord(data, key):
|
def _decode_fontrecord(data, key):
|
||||||
size = ord(data[0]) << 8 | ord(data[1])
|
size = ord(data[0]) << 8 | ord(data[1])
|
||||||
face = ord(data[2])
|
face = ord(data[2])
|
||||||
namelen = ord(data[4])
|
namelen = ord(data[4])
|
||||||
return size, face, data[5:5+namelen]
|
return size, face, data[5:5+namelen]
|
||||||
|
|
||||||
def _decode_boolean(data, key):
|
def _decode_boolean(data, key):
|
||||||
return ord(data[0])
|
return ord(data[0])
|
||||||
|
|
||||||
def _decode_text(data, key):
|
def _decode_text(data, key):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _decode_charset(data, key):
|
def _decode_charset(data, key):
|
||||||
return data[:256], data[256:]
|
return data[:256], data[256:]
|
||||||
|
|
||||||
def _decode_appspec(data, key):
|
def _decode_appspec(data, key):
|
||||||
namelen = ord(data[4])
|
namelen = ord(data[4])
|
||||||
return data[0:4], data[5:5+namelen]
|
return data[0:4], data[5:5+namelen]
|
||||||
|
|
||||||
def _code_default(data, key):
|
def _code_default(data, key):
|
||||||
return chr(len(data)) + data
|
return chr(len(data)) + data
|
||||||
|
|
||||||
def _code_multistr(data, key):
|
def _code_multistr(data, key):
|
||||||
numstr = len(data)
|
numstr = len(data)
|
||||||
rv = chr((numstr>>8) & 0xff) + chr(numstr & 0xff)
|
rv = chr((numstr>>8) & 0xff) + chr(numstr & 0xff)
|
||||||
for i in data:
|
for i in data:
|
||||||
rv = rv + _code_default(i)
|
rv = rv + _code_default(i)
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def _code_fontrecord(data, key):
|
def _code_fontrecord(data, key):
|
||||||
size, face, name = data
|
size, face, name = data
|
||||||
return chr((size>>8) & 0xff) + chr(size & 0xff) + chr(face & 0xff) + \
|
return chr((size>>8) & 0xff) + chr(size & 0xff) + chr(face & 0xff) + \
|
||||||
chr(0) + _code_default(name)
|
chr(0) + _code_default(name)
|
||||||
|
|
||||||
def _code_boolean(data, key):
|
def _code_boolean(data, key):
|
||||||
print 'XXXX boolean:', `data`
|
print 'XXXX boolean:', `data`
|
||||||
return chr(data)
|
return chr(data)
|
||||||
|
|
||||||
def _code_text(data, key):
|
def _code_text(data, key):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _code_charset(data, key):
|
def _code_charset(data, key):
|
||||||
return data[0] + data[1]
|
return data[0] + data[1]
|
||||||
|
|
||||||
def _code_appspec(data, key):
|
def _code_appspec(data, key):
|
||||||
return data[0] + _code_default(data[1])
|
return data[0] + _code_default(data[1])
|
||||||
|
|
||||||
_decoder_table = {
|
_decoder_table = {
|
||||||
"ArchieAll" : (_decode_multistr , _code_multistr),
|
"ArchieAll" : (_decode_multistr , _code_multistr),
|
||||||
"UMichAll" : (_decode_multistr , _code_multistr),
|
"UMichAll" : (_decode_multistr , _code_multistr),
|
||||||
"InfoMacAll" : (_decode_multistr , _code_multistr),
|
"InfoMacAll" : (_decode_multistr , _code_multistr),
|
||||||
"ListFont" : (_decode_fontrecord , _code_fontrecord),
|
"ListFont" : (_decode_fontrecord , _code_fontrecord),
|
||||||
"ScreenFont" : (_decode_fontrecord , _code_fontrecord),
|
"ScreenFont" : (_decode_fontrecord , _code_fontrecord),
|
||||||
"PrinterFont" : (_decode_fontrecord , _code_fontrecord),
|
"PrinterFont" : (_decode_fontrecord , _code_fontrecord),
|
||||||
# "DownloadFolder" : (_decode_filespec , _code_filespec),
|
# "DownloadFolder" : (_decode_filespec , _code_filespec),
|
||||||
"Signature": (_decode_text , _code_text),
|
"Signature": (_decode_text , _code_text),
|
||||||
"Plan" : (_decode_text , _code_text),
|
"Plan" : (_decode_text , _code_text),
|
||||||
"MailHeaders" : (_decode_text , _code_text),
|
"MailHeaders" : (_decode_text , _code_text),
|
||||||
"NewsHeaders" : (_decode_text , _code_text),
|
"NewsHeaders" : (_decode_text , _code_text),
|
||||||
# "Mapping"
|
# "Mapping"
|
||||||
"CharacterSet" : (_decode_charset , _code_charset),
|
"CharacterSet" : (_decode_charset , _code_charset),
|
||||||
"Helper\245" : (_decode_appspec , _code_appspec),
|
"Helper\245" : (_decode_appspec , _code_appspec),
|
||||||
# "Services" : (_decode_services, ????),
|
# "Services" : (_decode_services, ????),
|
||||||
"NewMailFlashIcon" : (_decode_boolean , _code_boolean),
|
"NewMailFlashIcon" : (_decode_boolean , _code_boolean),
|
||||||
"NewMailDialog" : (_decode_boolean , _code_boolean),
|
"NewMailDialog" : (_decode_boolean , _code_boolean),
|
||||||
"NewMailPlaySound" : (_decode_boolean , _code_boolean),
|
"NewMailPlaySound" : (_decode_boolean , _code_boolean),
|
||||||
# "WebBackgroundColor" : _decode_color,
|
# "WebBackgroundColor" : _decode_color,
|
||||||
"NoProxyDomains" : (_decode_multistr , _code_multistr),
|
"NoProxyDomains" : (_decode_multistr , _code_multistr),
|
||||||
"UseHTTPProxy" : (_decode_boolean , _code_boolean),
|
"UseHTTPProxy" : (_decode_boolean , _code_boolean),
|
||||||
"UseGopherProxy": (_decode_boolean , _code_boolean),
|
"UseGopherProxy": (_decode_boolean , _code_boolean),
|
||||||
"UseFTPProxy" : (_decode_boolean , _code_boolean),
|
"UseFTPProxy" : (_decode_boolean , _code_boolean),
|
||||||
"UsePassiveFTP" : (_decode_boolean , _code_boolean),
|
"UsePassiveFTP" : (_decode_boolean , _code_boolean),
|
||||||
}
|
}
|
||||||
|
|
||||||
def _decode(data, key):
|
def _decode(data, key):
|
||||||
if '\245' in key:
|
if '\245' in key:
|
||||||
key2 = key[:string.index(key, '\245')+1]
|
key2 = key[:string.index(key, '\245')+1]
|
||||||
else:
|
else:
|
||||||
key2 = key
|
key2 = key
|
||||||
if _decoder_table.has_key(key2):
|
if _decoder_table.has_key(key2):
|
||||||
decoder = _decoder_table[key2][0]
|
decoder = _decoder_table[key2][0]
|
||||||
else:
|
else:
|
||||||
decoder = _decode_default
|
decoder = _decode_default
|
||||||
return decoder(data, key)
|
return decoder(data, key)
|
||||||
|
|
||||||
def _code(data, key):
|
def _code(data, key):
|
||||||
if type(data) == _ICOpaqueDataType:
|
if type(data) == _ICOpaqueDataType:
|
||||||
return data.data
|
return data.data
|
||||||
if '\245' in key:
|
if '\245' in key:
|
||||||
key2 = key[:string.index(key, '\245')+1]
|
key2 = key[:string.index(key, '\245')+1]
|
||||||
else:
|
else:
|
||||||
key2 = key
|
key2 = key
|
||||||
if _decoder_table.has_key(key2):
|
if _decoder_table.has_key(key2):
|
||||||
coder = _decoder_table[key2][1]
|
coder = _decoder_table[key2][1]
|
||||||
else:
|
else:
|
||||||
coder = _code_default
|
coder = _code_default
|
||||||
return coder(data, key)
|
return coder(data, key)
|
||||||
|
|
||||||
class IC:
|
class IC:
|
||||||
def __init__(self, signature='Pyth', ic=None):
|
def __init__(self, signature='Pyth', ic=None):
|
||||||
if ic:
|
if ic:
|
||||||
self.ic = ic
|
self.ic = ic
|
||||||
else:
|
else:
|
||||||
self.ic = icglue.ICStart(signature)
|
self.ic = icglue.ICStart(signature)
|
||||||
if hasattr(self.ic, 'ICFindConfigFile'):
|
if hasattr(self.ic, 'ICFindConfigFile'):
|
||||||
self.ic.ICFindConfigFile()
|
self.ic.ICFindConfigFile()
|
||||||
self.h = Res.Resource('')
|
self.h = Res.Resource('')
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
rv = []
|
rv = []
|
||||||
self.ic.ICBegin(icReadOnlyPerm)
|
self.ic.ICBegin(icReadOnlyPerm)
|
||||||
num = self.ic.ICCountPref()
|
num = self.ic.ICCountPref()
|
||||||
for i in range(num):
|
for i in range(num):
|
||||||
rv.append(self.ic.ICGetIndPref(i+1))
|
rv.append(self.ic.ICGetIndPref(i+1))
|
||||||
self.ic.ICEnd()
|
self.ic.ICEnd()
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def has_key(self, key):
|
def has_key(self, key):
|
||||||
return self.__contains__(key)
|
return self.__contains__(key)
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
try:
|
try:
|
||||||
dummy = self.ic.ICFindPrefHandle(key, self.h)
|
dummy = self.ic.ICFindPrefHandle(key, self.h)
|
||||||
except icglue.error:
|
except icglue.error:
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
attr = self.ic.ICFindPrefHandle(key, self.h)
|
attr = self.ic.ICFindPrefHandle(key, self.h)
|
||||||
return _decode(self.h.data, key)
|
return _decode(self.h.data, key)
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
value = _code(value, key)
|
value = _code(value, key)
|
||||||
self.ic.ICSetPref(key, ICattr_no_change, value)
|
self.ic.ICSetPref(key, ICattr_no_change, value)
|
||||||
|
|
||||||
def launchurl(self, url, hint=""):
|
def launchurl(self, url, hint=""):
|
||||||
# Work around a bug in ICLaunchURL: file:/foo does
|
# Work around a bug in ICLaunchURL: file:/foo does
|
||||||
# not work but file:///foo does.
|
# not work but file:///foo does.
|
||||||
if url[:6] == 'file:/' and url[6] != '/':
|
if url[:6] == 'file:/' and url[6] != '/':
|
||||||
url = 'file:///' + url[6:]
|
url = 'file:///' + url[6:]
|
||||||
self.ic.ICLaunchURL(hint, url, 0, len(url))
|
self.ic.ICLaunchURL(hint, url, 0, len(url))
|
||||||
|
|
||||||
def parseurl(self, data, start=None, end=None, hint=""):
|
def parseurl(self, data, start=None, end=None, hint=""):
|
||||||
if start == None:
|
if start == None:
|
||||||
selStart = 0
|
selStart = 0
|
||||||
selEnd = len(data)
|
selEnd = len(data)
|
||||||
else:
|
else:
|
||||||
selStart = selEnd = start
|
selStart = selEnd = start
|
||||||
if end != None:
|
if end != None:
|
||||||
selEnd = end
|
selEnd = end
|
||||||
selStart, selEnd = self.ic.ICParseURL(hint, data, selStart, selEnd, self.h)
|
selStart, selEnd = self.ic.ICParseURL(hint, data, selStart, selEnd, self.h)
|
||||||
return self.h.data, selStart, selEnd
|
return self.h.data, selStart, selEnd
|
||||||
|
|
||||||
def mapfile(self, file):
|
def mapfile(self, file):
|
||||||
if type(file) != type(''):
|
if type(file) != type(''):
|
||||||
file = file.as_tuple()[2]
|
file = file.as_tuple()[2]
|
||||||
return self.ic.ICMapFilename(file)
|
return self.ic.ICMapFilename(file)
|
||||||
|
|
||||||
def maptypecreator(self, type, creator, filename=""):
|
def maptypecreator(self, type, creator, filename=""):
|
||||||
return self.ic.ICMapTypeCreator(type, creator, filename)
|
return self.ic.ICMapTypeCreator(type, creator, filename)
|
||||||
|
|
||||||
def settypecreator(self, file):
|
def settypecreator(self, file):
|
||||||
file = Carbon.File.pathname(file)
|
file = Carbon.File.pathname(file)
|
||||||
record = self.mapfile(os.path.split(file)[1])
|
record = self.mapfile(os.path.split(file)[1])
|
||||||
MacOS.SetCreatorAndType(file, record[2], record[1])
|
MacOS.SetCreatorAndType(file, record[2], record[1])
|
||||||
macostools.touched(fss)
|
macostools.touched(fss)
|
||||||
|
|
||||||
# Convenience routines
|
# Convenience routines
|
||||||
_dft_ic = None
|
_dft_ic = None
|
||||||
|
|
||||||
def launchurl(url, hint=""):
|
def launchurl(url, hint=""):
|
||||||
global _dft_ic
|
global _dft_ic
|
||||||
if _dft_ic == None: _dft_ic = IC()
|
if _dft_ic == None: _dft_ic = IC()
|
||||||
return _dft_ic.launchurl(url, hint)
|
return _dft_ic.launchurl(url, hint)
|
||||||
|
|
||||||
def parseurl(data, start=None, end=None, hint=""):
|
def parseurl(data, start=None, end=None, hint=""):
|
||||||
global _dft_ic
|
global _dft_ic
|
||||||
if _dft_ic == None: _dft_ic = IC()
|
if _dft_ic == None: _dft_ic = IC()
|
||||||
return _dft_ic.parseurl(data, start, end, hint)
|
return _dft_ic.parseurl(data, start, end, hint)
|
||||||
|
|
||||||
def mapfile(filename):
|
def mapfile(filename):
|
||||||
global _dft_ic
|
global _dft_ic
|
||||||
if _dft_ic == None: _dft_ic = IC()
|
if _dft_ic == None: _dft_ic = IC()
|
||||||
return _dft_ic.mapfile(filename)
|
return _dft_ic.mapfile(filename)
|
||||||
|
|
||||||
def maptypecreator(type, creator, filename=""):
|
def maptypecreator(type, creator, filename=""):
|
||||||
global _dft_ic
|
global _dft_ic
|
||||||
if _dft_ic == None: _dft_ic = IC()
|
if _dft_ic == None: _dft_ic = IC()
|
||||||
return _dft_ic.maptypecreator(type, creator, filename)
|
return _dft_ic.maptypecreator(type, creator, filename)
|
||||||
|
|
||||||
def settypecreator(file):
|
def settypecreator(file):
|
||||||
global _dft_ic
|
global _dft_ic
|
||||||
if _dft_ic == None: _dft_ic = IC()
|
if _dft_ic == None: _dft_ic = IC()
|
||||||
return _dft_ic.settypecreator(file)
|
return _dft_ic.settypecreator(file)
|
||||||
|
|
||||||
def _test():
|
def _test():
|
||||||
ic = IC()
|
ic = IC()
|
||||||
for k in ic.keys():
|
for k in ic.keys():
|
||||||
try:
|
try:
|
||||||
v = ic[k]
|
v = ic[k]
|
||||||
except error:
|
except error:
|
||||||
v = '????'
|
v = '????'
|
||||||
print k, '\t', v
|
print k, '\t', v
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
_test()
|
_test()
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,25 +28,25 @@ smAllScripts = -3
|
||||||
# Find the epoch conversion for file dates in a way that works on OS9 and OSX
|
# Find the epoch conversion for file dates in a way that works on OS9 and OSX
|
||||||
import time
|
import time
|
||||||
if time.gmtime(0)[0] == 1970:
|
if time.gmtime(0)[0] == 1970:
|
||||||
_EPOCHCONVERT = -((1970-1904)*365 + 17) * (24*60*60) + 0x100000000L
|
_EPOCHCONVERT = -((1970-1904)*365 + 17) * (24*60*60) + 0x100000000L
|
||||||
def _utc2time(utc):
|
def _utc2time(utc):
|
||||||
t = utc[1] + _EPOCHCONVERT
|
t = utc[1] + _EPOCHCONVERT
|
||||||
return int(t)
|
return int(t)
|
||||||
def _time2utc(t):
|
def _time2utc(t):
|
||||||
t = int(t) - _EPOCHCONVERT
|
t = int(t) - _EPOCHCONVERT
|
||||||
if t < -0x7fffffff:
|
if t < -0x7fffffff:
|
||||||
t = t + 0x10000000L
|
t = t + 0x10000000L
|
||||||
return (0, int(t), 0)
|
return (0, int(t), 0)
|
||||||
else:
|
else:
|
||||||
def _utc2time(utc):
|
def _utc2time(utc):
|
||||||
t = utc[1]
|
t = utc[1]
|
||||||
if t < 0:
|
if t < 0:
|
||||||
t = t + 0x100000000L
|
t = t + 0x100000000L
|
||||||
return t
|
return t
|
||||||
def _time2utc(t):
|
def _time2utc(t):
|
||||||
if t > 0x7fffffff:
|
if t > 0x7fffffff:
|
||||||
t = t - 0x100000000L
|
t = t - 0x100000000L
|
||||||
return (0, int(t), 0)
|
return (0, int(t), 0)
|
||||||
|
|
||||||
# The old name of the error object:
|
# The old name of the error object:
|
||||||
error = Carbon.File.Error
|
error = Carbon.File.Error
|
||||||
|
@ -56,59 +56,59 @@ error = Carbon.File.Error
|
||||||
# of the method names are subtly different.
|
# of the method names are subtly different.
|
||||||
#
|
#
|
||||||
class FSSpec(Carbon.File.FSSpec):
|
class FSSpec(Carbon.File.FSSpec):
|
||||||
def as_fsref(self):
|
def as_fsref(self):
|
||||||
return FSRef(self)
|
return FSRef(self)
|
||||||
|
|
||||||
def NewAlias(self, src=None):
|
def NewAlias(self, src=None):
|
||||||
return Alias(Carbon.File.NewAlias(src, self))
|
return Alias(Carbon.File.NewAlias(src, self))
|
||||||
|
|
||||||
def GetCreatorType(self):
|
def GetCreatorType(self):
|
||||||
finfo = self.FSpGetFInfo()
|
finfo = self.FSpGetFInfo()
|
||||||
return finfo.Creator, finfo.Type
|
return finfo.Creator, finfo.Type
|
||||||
|
|
||||||
def SetCreatorType(self, ctor, tp):
|
def SetCreatorType(self, ctor, tp):
|
||||||
finfo = self.FSpGetFInfo()
|
finfo = self.FSpGetFInfo()
|
||||||
finfo.Creator = ctor
|
finfo.Creator = ctor
|
||||||
finfo.Type = tp
|
finfo.Type = tp
|
||||||
self.FSpSetFInfo(finfo)
|
self.FSpSetFInfo(finfo)
|
||||||
|
|
||||||
def GetFInfo(self):
|
def GetFInfo(self):
|
||||||
return self.FSpGetFInfo()
|
return self.FSpGetFInfo()
|
||||||
|
|
||||||
def SetFInfo(self, info):
|
def SetFInfo(self, info):
|
||||||
return self.FSpSetFInfo(info)
|
return self.FSpSetFInfo(info)
|
||||||
|
|
||||||
def GetDates(self):
|
def GetDates(self):
|
||||||
catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate
|
catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate
|
||||||
catinfo, d1, d2, d3 = FSRef(self).FSGetCatalogInfo(catInfoFlags)
|
catinfo, d1, d2, d3 = FSRef(self).FSGetCatalogInfo(catInfoFlags)
|
||||||
cdate = catinfo.createDate
|
cdate = catinfo.createDate
|
||||||
mdate = catinfo.contentModDate
|
mdate = catinfo.contentModDate
|
||||||
bdate = catinfo.backupDate
|
bdate = catinfo.backupDate
|
||||||
return _utc2time(cdate), _utc2time(mdate), _utc2time(bdate)
|
return _utc2time(cdate), _utc2time(mdate), _utc2time(bdate)
|
||||||
|
|
||||||
def SetDates(self, cdate, mdate, bdate):
|
def SetDates(self, cdate, mdate, bdate):
|
||||||
catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate
|
catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate
|
||||||
catinfo = Carbon.File.FSCatalogInfo(
|
catinfo = Carbon.File.FSCatalogInfo(
|
||||||
createDate = _time2utc(cdate),
|
createDate = _time2utc(cdate),
|
||||||
contentModDate = _time2utc(mdate),
|
contentModDate = _time2utc(mdate),
|
||||||
backupDate = _time2utc(bdate))
|
backupDate = _time2utc(bdate))
|
||||||
FSRef(self).FSSetCatalogInfo(catInfoFlags, catinfo)
|
FSRef(self).FSSetCatalogInfo(catInfoFlags, catinfo)
|
||||||
|
|
||||||
class FSRef(Carbon.File.FSRef):
|
class FSRef(Carbon.File.FSRef):
|
||||||
def as_fsspec(self):
|
def as_fsspec(self):
|
||||||
return FSSpec(self)
|
return FSSpec(self)
|
||||||
|
|
||||||
class Alias(Carbon.File.Alias):
|
class Alias(Carbon.File.Alias):
|
||||||
|
|
||||||
def GetInfo(self, index):
|
def GetInfo(self, index):
|
||||||
return self.GetAliasInfo(index)
|
return self.GetAliasInfo(index)
|
||||||
|
|
||||||
def Update(self, *args):
|
def Update(self, *args):
|
||||||
pass # print "Alias.Update not yet implemented"
|
pass # print "Alias.Update not yet implemented"
|
||||||
|
|
||||||
def Resolve(self, src=None):
|
def Resolve(self, src=None):
|
||||||
fss, changed = self.ResolveAlias(src)
|
fss, changed = self.ResolveAlias(src)
|
||||||
return FSSpec(fss), changed
|
return FSSpec(fss), changed
|
||||||
|
|
||||||
from Carbon.File import FInfo
|
from Carbon.File import FInfo
|
||||||
|
|
||||||
|
@ -120,20 +120,20 @@ FInfoType = FInfo
|
||||||
|
|
||||||
# Global functions:
|
# Global functions:
|
||||||
def ResolveAliasFile(fss, chain=1):
|
def ResolveAliasFile(fss, chain=1):
|
||||||
fss, isdir, isalias = Carbon.File.ResolveAliasFile(fss, chain)
|
fss, isdir, isalias = Carbon.File.ResolveAliasFile(fss, chain)
|
||||||
return FSSpec(fss), isdir, isalias
|
return FSSpec(fss), isdir, isalias
|
||||||
|
|
||||||
def RawFSSpec(data):
|
def RawFSSpec(data):
|
||||||
return FSSpec(rawdata=data)
|
return FSSpec(rawdata=data)
|
||||||
|
|
||||||
def RawAlias(data):
|
def RawAlias(data):
|
||||||
return Alias(rawdata=data)
|
return Alias(rawdata=data)
|
||||||
|
|
||||||
def FindApplication(*args):
|
def FindApplication(*args):
|
||||||
raise NotImplementedError, "FindApplication no longer implemented"
|
raise NotImplementedError, "FindApplication no longer implemented"
|
||||||
|
|
||||||
def NewAliasMinimalFromFullPath(path):
|
def NewAliasMinimalFromFullPath(path):
|
||||||
return Alias(Carbon.File.NewAliasMinimalFromFullPath(path, '', ''))
|
return Alias(Carbon.File.NewAliasMinimalFromFullPath(path, '', ''))
|
||||||
|
|
||||||
# Another global function:
|
# Another global function:
|
||||||
from Carbon.Folder import FindFolder
|
from Carbon.Folder import FindFolder
|
||||||
|
@ -145,54 +145,54 @@ from Carbon.Folder import FindFolder
|
||||||
_curfolder = None
|
_curfolder = None
|
||||||
|
|
||||||
def StandardGetFile(*typelist):
|
def StandardGetFile(*typelist):
|
||||||
"""Ask for an input file, optionally specifying 4-char file types that are
|
"""Ask for an input file, optionally specifying 4-char file types that are
|
||||||
allowable"""
|
allowable"""
|
||||||
return PromptGetFile('', *typelist)
|
return PromptGetFile('', *typelist)
|
||||||
|
|
||||||
def PromptGetFile(prompt, *typelist):
|
def PromptGetFile(prompt, *typelist):
|
||||||
"""Ask for an input file giving the user a prompt message. Optionally you can
|
"""Ask for an input file giving the user a prompt message. Optionally you can
|
||||||
specifying 4-char file types that are allowable"""
|
specifying 4-char file types that are allowable"""
|
||||||
import EasyDialogs
|
import EasyDialogs
|
||||||
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
||||||
DeprecationWarning, stacklevel=2)
|
DeprecationWarning, stacklevel=2)
|
||||||
if not typelist:
|
if not typelist:
|
||||||
typelist = None
|
typelist = None
|
||||||
fss = EasyDialogs.AskFileForOpen(message=prompt, wanted=FSSpec,
|
fss = EasyDialogs.AskFileForOpen(message=prompt, wanted=FSSpec,
|
||||||
typeList=typelist, defaultLocation=_handleSetFolder())
|
typeList=typelist, defaultLocation=_handleSetFolder())
|
||||||
return fss, not fss is None
|
return fss, not fss is None
|
||||||
|
|
||||||
def StandardPutFile(prompt, default=None):
|
def StandardPutFile(prompt, default=None):
|
||||||
"""Ask the user for an output file, with a prompt. Optionally you cn supply a
|
"""Ask the user for an output file, with a prompt. Optionally you cn supply a
|
||||||
default output filename"""
|
default output filename"""
|
||||||
import EasyDialogs
|
import EasyDialogs
|
||||||
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
||||||
DeprecationWarning, stacklevel=2)
|
DeprecationWarning, stacklevel=2)
|
||||||
fss = EasyDialogs.AskFileForSave(wanted=FSSpec, message=prompt,
|
fss = EasyDialogs.AskFileForSave(wanted=FSSpec, message=prompt,
|
||||||
savedFileName=default, defaultLocation=_handleSetFolder())
|
savedFileName=default, defaultLocation=_handleSetFolder())
|
||||||
return fss, not fss is None
|
return fss, not fss is None
|
||||||
|
|
||||||
def SetFolder(folder):
|
def SetFolder(folder):
|
||||||
global _curfolder
|
global _curfolder
|
||||||
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
||||||
DeprecationWarning, stacklevel=2)
|
DeprecationWarning, stacklevel=2)
|
||||||
if _curfolder:
|
if _curfolder:
|
||||||
rv = FSSpec(_curfolder)
|
rv = FSSpec(_curfolder)
|
||||||
else:
|
else:
|
||||||
rv = None
|
rv = None
|
||||||
_curfolder = folder
|
_curfolder = folder
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def _handleSetFolder():
|
def _handleSetFolder():
|
||||||
global _curfolder
|
global _curfolder
|
||||||
rv = _curfolder
|
rv = _curfolder
|
||||||
_curfolder = None
|
_curfolder = None
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def GetDirectory(prompt=None):
|
def GetDirectory(prompt=None):
|
||||||
"""Ask the user to select a folder. Optionally you can give a prompt."""
|
"""Ask the user to select a folder. Optionally you can give a prompt."""
|
||||||
import EasyDialogs
|
import EasyDialogs
|
||||||
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen",
|
||||||
DeprecationWarning, stacklevel=2)
|
DeprecationWarning, stacklevel=2)
|
||||||
fss = EasyDialogs.AskFolder(message=prompt, wanted=FSSpec,
|
fss = EasyDialogs.AskFolder(message=prompt, wanted=FSSpec,
|
||||||
defaultLocation=_handleSetFolder())
|
defaultLocation=_handleSetFolder())
|
||||||
return fss, not fss is None
|
return fss, not fss is None
|
||||||
|
|
|
@ -10,137 +10,137 @@ class ArgumentError(TypeError): pass
|
||||||
class ResourceFileNotFoundError(ImportError): pass
|
class ResourceFileNotFoundError(ImportError): pass
|
||||||
|
|
||||||
def need(restype, resid, filename=None, modname=None):
|
def need(restype, resid, filename=None, modname=None):
|
||||||
"""Open a resource file, if needed. restype and resid
|
"""Open a resource file, if needed. restype and resid
|
||||||
are required parameters, and identify the resource for which to test. If it
|
are required parameters, and identify the resource for which to test. If it
|
||||||
is available we are done. If it is not available we look for a file filename
|
is available we are done. If it is not available we look for a file filename
|
||||||
(default: modname with .rsrc appended) either in the same folder as
|
(default: modname with .rsrc appended) either in the same folder as
|
||||||
where modname was loaded from, or otherwise across sys.path.
|
where modname was loaded from, or otherwise across sys.path.
|
||||||
|
|
||||||
Returns the refno of the resource file opened (or None)"""
|
Returns the refno of the resource file opened (or None)"""
|
||||||
|
|
||||||
if modname is None and filename is None:
|
if modname is None and filename is None:
|
||||||
raise ArgumentError, "Either filename or modname argument (or both) must be given"
|
raise ArgumentError, "Either filename or modname argument (or both) must be given"
|
||||||
|
|
||||||
if type(resid) is type(1):
|
if type(resid) is type(1):
|
||||||
try:
|
try:
|
||||||
h = Res.GetResource(restype, resid)
|
h = Res.GetResource(restype, resid)
|
||||||
except Res.Error:
|
except Res.Error:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
h = Res.GetNamedResource(restype, resid)
|
h = Res.GetNamedResource(restype, resid)
|
||||||
except Res.Error:
|
except Res.Error:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Construct a filename if we don't have one
|
# Construct a filename if we don't have one
|
||||||
if not filename:
|
if not filename:
|
||||||
if '.' in modname:
|
if '.' in modname:
|
||||||
filename = modname.split('.')[-1] + '.rsrc'
|
filename = modname.split('.')[-1] + '.rsrc'
|
||||||
else:
|
else:
|
||||||
filename = modname + '.rsrc'
|
filename = modname + '.rsrc'
|
||||||
|
|
||||||
# Now create a list of folders to search
|
# Now create a list of folders to search
|
||||||
searchdirs = []
|
searchdirs = []
|
||||||
if modname == '__main__':
|
if modname == '__main__':
|
||||||
# If we're main we look in the current directory
|
# If we're main we look in the current directory
|
||||||
searchdirs = [os.curdir]
|
searchdirs = [os.curdir]
|
||||||
if sys.modules.has_key(modname):
|
if sys.modules.has_key(modname):
|
||||||
mod = sys.modules[modname]
|
mod = sys.modules[modname]
|
||||||
if hasattr(mod, '__file__'):
|
if hasattr(mod, '__file__'):
|
||||||
searchdirs = [os.path.dirname(mod.__file__)]
|
searchdirs = [os.path.dirname(mod.__file__)]
|
||||||
searchdirs.extend(sys.path)
|
searchdirs.extend(sys.path)
|
||||||
|
|
||||||
# And look for the file
|
# And look for the file
|
||||||
for dir in searchdirs:
|
for dir in searchdirs:
|
||||||
pathname = os.path.join(dir, filename)
|
pathname = os.path.join(dir, filename)
|
||||||
if os.path.exists(pathname):
|
if os.path.exists(pathname):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise ResourceFileNotFoundError, filename
|
raise ResourceFileNotFoundError, filename
|
||||||
|
|
||||||
refno = open_pathname(pathname)
|
refno = open_pathname(pathname)
|
||||||
|
|
||||||
# And check that the resource exists now
|
# And check that the resource exists now
|
||||||
if type(resid) is type(1):
|
if type(resid) is type(1):
|
||||||
h = Res.GetResource(restype, resid)
|
h = Res.GetResource(restype, resid)
|
||||||
else:
|
else:
|
||||||
h = Res.GetNamedResource(restype, resid)
|
h = Res.GetNamedResource(restype, resid)
|
||||||
return refno
|
return refno
|
||||||
|
|
||||||
def open_pathname(pathname, verbose=0):
|
def open_pathname(pathname, verbose=0):
|
||||||
"""Open a resource file given by pathname, possibly decoding an
|
"""Open a resource file given by pathname, possibly decoding an
|
||||||
AppleSingle file"""
|
AppleSingle file"""
|
||||||
try:
|
try:
|
||||||
refno = Res.FSpOpenResFile(pathname, 1)
|
refno = Res.FSpOpenResFile(pathname, 1)
|
||||||
except Res.Error, arg:
|
except Res.Error, arg:
|
||||||
if arg[0] in (-37, -39):
|
if arg[0] in (-37, -39):
|
||||||
# No resource fork. We may be on OSX, and this may be either
|
# No resource fork. We may be on OSX, and this may be either
|
||||||
# a data-fork based resource file or a AppleSingle file
|
# a data-fork based resource file or a AppleSingle file
|
||||||
# from the CVS repository.
|
# from the CVS repository.
|
||||||
try:
|
try:
|
||||||
refno = Res.FSOpenResourceFile(pathname, u'', 1)
|
refno = Res.FSOpenResourceFile(pathname, u'', 1)
|
||||||
except Res.Error, arg:
|
except Res.Error, arg:
|
||||||
if arg[0] != -199:
|
if arg[0] != -199:
|
||||||
# -199 is "bad resource map"
|
# -199 is "bad resource map"
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
return refno
|
return refno
|
||||||
# Finally try decoding an AppleSingle file
|
# Finally try decoding an AppleSingle file
|
||||||
pathname = _decode(pathname, verbose=verbose)
|
pathname = _decode(pathname, verbose=verbose)
|
||||||
refno = Res.FSOpenResourceFile(pathname, u'', 1)
|
refno = Res.FSOpenResourceFile(pathname, u'', 1)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
return refno
|
return refno
|
||||||
|
|
||||||
def resource_pathname(pathname, verbose=0):
|
def resource_pathname(pathname, verbose=0):
|
||||||
"""Return the pathname for a resource file (either DF or RF based).
|
"""Return the pathname for a resource file (either DF or RF based).
|
||||||
If the pathname given already refers to such a file simply return it,
|
If the pathname given already refers to such a file simply return it,
|
||||||
otherwise first decode it."""
|
otherwise first decode it."""
|
||||||
try:
|
try:
|
||||||
refno = Res.FSpOpenResFile(pathname, 1)
|
refno = Res.FSpOpenResFile(pathname, 1)
|
||||||
Res.CloseResFile(refno)
|
Res.CloseResFile(refno)
|
||||||
except Res.Error, arg:
|
except Res.Error, arg:
|
||||||
if arg[0] in (-37, -39):
|
if arg[0] in (-37, -39):
|
||||||
# No resource fork. We may be on OSX, and this may be either
|
# No resource fork. We may be on OSX, and this may be either
|
||||||
# a data-fork based resource file or a AppleSingle file
|
# a data-fork based resource file or a AppleSingle file
|
||||||
# from the CVS repository.
|
# from the CVS repository.
|
||||||
try:
|
try:
|
||||||
refno = Res.FSOpenResourceFile(pathname, u'', 1)
|
refno = Res.FSOpenResourceFile(pathname, u'', 1)
|
||||||
except Res.Error, arg:
|
except Res.Error, arg:
|
||||||
if arg[0] != -199:
|
if arg[0] != -199:
|
||||||
# -199 is "bad resource map"
|
# -199 is "bad resource map"
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
return refno
|
return refno
|
||||||
# Finally try decoding an AppleSingle file
|
# Finally try decoding an AppleSingle file
|
||||||
pathname = _decode(pathname, verbose=verbose)
|
pathname = _decode(pathname, verbose=verbose)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
return pathname
|
return pathname
|
||||||
|
|
||||||
def open_error_resource():
|
def open_error_resource():
|
||||||
"""Open the resource file containing the error code to error message
|
"""Open the resource file containing the error code to error message
|
||||||
mapping."""
|
mapping."""
|
||||||
need('Estr', 1, filename="errors.rsrc", modname=__name__)
|
need('Estr', 1, filename="errors.rsrc", modname=__name__)
|
||||||
|
|
||||||
def _decode(pathname, verbose=0):
|
def _decode(pathname, verbose=0):
|
||||||
# Decode an AppleSingle resource file, return the new pathname.
|
# Decode an AppleSingle resource file, return the new pathname.
|
||||||
newpathname = pathname + '.df.rsrc'
|
newpathname = pathname + '.df.rsrc'
|
||||||
if os.path.exists(newpathname) and \
|
if os.path.exists(newpathname) and \
|
||||||
os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime:
|
os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime:
|
||||||
return newpathname
|
return newpathname
|
||||||
if hasattr(os, 'access') and not \
|
if hasattr(os, 'access') and not \
|
||||||
os.access(os.path.dirname(pathname), os.W_OK|os.X_OK):
|
os.access(os.path.dirname(pathname), os.W_OK|os.X_OK):
|
||||||
# The destination directory isn't writeable. Create the file in
|
# The destination directory isn't writeable. Create the file in
|
||||||
# a temporary directory
|
# a temporary directory
|
||||||
import tempfile
|
import tempfile
|
||||||
fd, newpathname = tempfile.mkstemp(".rsrc")
|
fd, newpathname = tempfile.mkstemp(".rsrc")
|
||||||
if verbose:
|
if verbose:
|
||||||
print 'Decoding', pathname, 'to', newpathname
|
print 'Decoding', pathname, 'to', newpathname
|
||||||
import applesingle
|
import applesingle
|
||||||
applesingle.decode(pathname, newpathname, resonly=1)
|
applesingle.decode(pathname, newpathname, resonly=1)
|
||||||
return newpathname
|
return newpathname
|
||||||
|
|
1278
Lib/plat-mac/pimp.py
1278
Lib/plat-mac/pimp.py
File diff suppressed because it is too large
Load Diff
|
@ -33,29 +33,29 @@ The <date> plist data has (limited) support through the Date class.
|
||||||
|
|
||||||
Generate Plist example:
|
Generate Plist example:
|
||||||
|
|
||||||
pl = Plist(
|
pl = Plist(
|
||||||
aString="Doodah",
|
aString="Doodah",
|
||||||
aList=["A", "B", 12, 32.1, [1, 2, 3]],
|
aList=["A", "B", 12, 32.1, [1, 2, 3]],
|
||||||
aFloat = 0.1,
|
aFloat = 0.1,
|
||||||
anInt = 728,
|
anInt = 728,
|
||||||
aDict=Dict(
|
aDict=Dict(
|
||||||
anotherString="<hello & hi there!>",
|
anotherString="<hello & hi there!>",
|
||||||
aUnicodeValue=u'M\xe4ssig, Ma\xdf',
|
aUnicodeValue=u'M\xe4ssig, Ma\xdf',
|
||||||
aTrueValue=True,
|
aTrueValue=True,
|
||||||
aFalseValue=False,
|
aFalseValue=False,
|
||||||
),
|
),
|
||||||
someData = Data("<binary gunk>"),
|
someData = Data("<binary gunk>"),
|
||||||
someMoreData = Data("<lots of binary gunk>" * 10),
|
someMoreData = Data("<lots of binary gunk>" * 10),
|
||||||
aDate = Date(time.mktime(time.gmtime())),
|
aDate = Date(time.mktime(time.gmtime())),
|
||||||
)
|
)
|
||||||
# unicode keys are possible, but a little awkward to use:
|
# unicode keys are possible, but a little awkward to use:
|
||||||
pl[u'\xc5benraa'] = "That was a unicode key."
|
pl[u'\xc5benraa'] = "That was a unicode key."
|
||||||
pl.write(fileName)
|
pl.write(fileName)
|
||||||
|
|
||||||
Parse Plist example:
|
Parse Plist example:
|
||||||
|
|
||||||
pl = Plist.fromFile(pathOrFile)
|
pl = Plist.fromFile(pathOrFile)
|
||||||
print pl.aKey
|
print pl.aKey
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -71,40 +71,40 @@ INDENT = "\t"
|
||||||
|
|
||||||
class DumbXMLWriter:
|
class DumbXMLWriter:
|
||||||
|
|
||||||
def __init__(self, file):
|
def __init__(self, file):
|
||||||
self.file = file
|
self.file = file
|
||||||
self.stack = []
|
self.stack = []
|
||||||
self.indentLevel = 0
|
self.indentLevel = 0
|
||||||
|
|
||||||
def beginElement(self, element):
|
def beginElement(self, element):
|
||||||
self.stack.append(element)
|
self.stack.append(element)
|
||||||
self.writeln("<%s>" % element)
|
self.writeln("<%s>" % element)
|
||||||
self.indentLevel += 1
|
self.indentLevel += 1
|
||||||
|
|
||||||
def endElement(self, element):
|
def endElement(self, element):
|
||||||
assert self.indentLevel > 0
|
assert self.indentLevel > 0
|
||||||
assert self.stack.pop() == element
|
assert self.stack.pop() == element
|
||||||
self.indentLevel -= 1
|
self.indentLevel -= 1
|
||||||
self.writeln("</%s>" % element)
|
self.writeln("</%s>" % element)
|
||||||
|
|
||||||
def simpleElement(self, element, value=None):
|
def simpleElement(self, element, value=None):
|
||||||
if value:
|
if value:
|
||||||
value = _encode(value)
|
value = _encode(value)
|
||||||
self.writeln("<%s>%s</%s>" % (element, value, element))
|
self.writeln("<%s>%s</%s>" % (element, value, element))
|
||||||
else:
|
else:
|
||||||
self.writeln("<%s/>" % element)
|
self.writeln("<%s/>" % element)
|
||||||
|
|
||||||
def writeln(self, line):
|
def writeln(self, line):
|
||||||
if line:
|
if line:
|
||||||
self.file.write(self.indentLevel * INDENT + line + "\n")
|
self.file.write(self.indentLevel * INDENT + line + "\n")
|
||||||
else:
|
else:
|
||||||
self.file.write("\n")
|
self.file.write("\n")
|
||||||
|
|
||||||
|
|
||||||
def _encode(text):
|
def _encode(text):
|
||||||
text = text.replace("&", "&")
|
text = text.replace("&", "&")
|
||||||
text = text.replace("<", "<")
|
text = text.replace("<", "<")
|
||||||
return text.encode("utf-8")
|
return text.encode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
PLISTHEADER = """\
|
PLISTHEADER = """\
|
||||||
|
@ -114,323 +114,323 @@ PLISTHEADER = """\
|
||||||
|
|
||||||
class PlistWriter(DumbXMLWriter):
|
class PlistWriter(DumbXMLWriter):
|
||||||
|
|
||||||
def __init__(self, file):
|
def __init__(self, file):
|
||||||
file.write(PLISTHEADER)
|
file.write(PLISTHEADER)
|
||||||
DumbXMLWriter.__init__(self, file)
|
DumbXMLWriter.__init__(self, file)
|
||||||
|
|
||||||
def writeValue(self, value):
|
def writeValue(self, value):
|
||||||
if isinstance(value, (str, unicode)):
|
if isinstance(value, (str, unicode)):
|
||||||
self.simpleElement("string", value)
|
self.simpleElement("string", value)
|
||||||
elif isinstance(value, bool):
|
elif isinstance(value, bool):
|
||||||
# must switch for bool before int, as bool is a
|
# must switch for bool before int, as bool is a
|
||||||
# subclass of int...
|
# subclass of int...
|
||||||
if value:
|
if value:
|
||||||
self.simpleElement("true")
|
self.simpleElement("true")
|
||||||
else:
|
else:
|
||||||
self.simpleElement("false")
|
self.simpleElement("false")
|
||||||
elif isinstance(value, int):
|
elif isinstance(value, int):
|
||||||
self.simpleElement("integer", str(value))
|
self.simpleElement("integer", str(value))
|
||||||
elif isinstance(value, float):
|
elif isinstance(value, float):
|
||||||
# should perhaps use repr() for better precision?
|
# should perhaps use repr() for better precision?
|
||||||
self.simpleElement("real", str(value))
|
self.simpleElement("real", str(value))
|
||||||
elif isinstance(value, (dict, Dict)):
|
elif isinstance(value, (dict, Dict)):
|
||||||
self.writeDict(value)
|
self.writeDict(value)
|
||||||
elif isinstance(value, Data):
|
elif isinstance(value, Data):
|
||||||
self.writeData(value)
|
self.writeData(value)
|
||||||
elif isinstance(value, Date):
|
elif isinstance(value, Date):
|
||||||
self.simpleElement("date", value.toString())
|
self.simpleElement("date", value.toString())
|
||||||
elif isinstance(value, (tuple, list)):
|
elif isinstance(value, (tuple, list)):
|
||||||
self.writeArray(value)
|
self.writeArray(value)
|
||||||
else:
|
else:
|
||||||
assert 0, "unsuported type: %s" % type(value)
|
assert 0, "unsuported type: %s" % type(value)
|
||||||
|
|
||||||
def writeData(self, data):
|
def writeData(self, data):
|
||||||
self.beginElement("data")
|
self.beginElement("data")
|
||||||
for line in data.asBase64().split("\n"):
|
for line in data.asBase64().split("\n"):
|
||||||
if line:
|
if line:
|
||||||
self.writeln(line)
|
self.writeln(line)
|
||||||
self.endElement("data")
|
self.endElement("data")
|
||||||
|
|
||||||
def writeDict(self, d):
|
def writeDict(self, d):
|
||||||
self.beginElement("dict")
|
self.beginElement("dict")
|
||||||
items = d.items()
|
items = d.items()
|
||||||
items.sort()
|
items.sort()
|
||||||
for key, value in items:
|
for key, value in items:
|
||||||
assert isinstance(key, (str, unicode)), "keys must be strings"
|
assert isinstance(key, (str, unicode)), "keys must be strings"
|
||||||
self.simpleElement("key", key)
|
self.simpleElement("key", key)
|
||||||
self.writeValue(value)
|
self.writeValue(value)
|
||||||
self.endElement("dict")
|
self.endElement("dict")
|
||||||
|
|
||||||
def writeArray(self, array):
|
def writeArray(self, array):
|
||||||
self.beginElement("array")
|
self.beginElement("array")
|
||||||
for value in array:
|
for value in array:
|
||||||
self.writeValue(value)
|
self.writeValue(value)
|
||||||
self.endElement("array")
|
self.endElement("array")
|
||||||
|
|
||||||
|
|
||||||
class Dict:
|
class Dict:
|
||||||
|
|
||||||
"""Dict wrapper for convenient access of values through attributes."""
|
"""Dict wrapper for convenient access of values through attributes."""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.__dict__.update(kwargs)
|
self.__dict__.update(kwargs)
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
return cmp(self.__dict__, other.__dict__)
|
return cmp(self.__dict__, other.__dict__)
|
||||||
elif isinstance(other, dict):
|
elif isinstance(other, dict):
|
||||||
return cmp(self.__dict__, other)
|
return cmp(self.__dict__, other)
|
||||||
else:
|
else:
|
||||||
return cmp(id(self), id(other))
|
return cmp(id(self), id(other))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s(**%s)" % (self.__class__.__name__, self.__dict__)
|
return "%s(**%s)" % (self.__class__.__name__, self.__dict__)
|
||||||
__repr__ = __str__
|
__repr__ = __str__
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
return self.__class__(**self.__dict__)
|
return self.__class__(**self.__dict__)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
"""Delegate everything else to the dict object."""
|
"""Delegate everything else to the dict object."""
|
||||||
return getattr(self.__dict__, attr)
|
return getattr(self.__dict__, attr)
|
||||||
|
|
||||||
|
|
||||||
class Plist(Dict):
|
class Plist(Dict):
|
||||||
|
|
||||||
"""The main Plist object. Basically a dict (the toplevel object
|
"""The main Plist object. Basically a dict (the toplevel object
|
||||||
of a plist is a dict) with two additional methods to read from
|
of a plist is a dict) with two additional methods to read from
|
||||||
and write to files.
|
and write to files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def fromFile(cls, pathOrFile):
|
def fromFile(cls, pathOrFile):
|
||||||
didOpen = 0
|
didOpen = 0
|
||||||
if not hasattr(pathOrFile, "write"):
|
if not hasattr(pathOrFile, "write"):
|
||||||
pathOrFile = open(pathOrFile)
|
pathOrFile = open(pathOrFile)
|
||||||
didOpen = 1
|
didOpen = 1
|
||||||
p = PlistParser()
|
p = PlistParser()
|
||||||
plist = p.parse(pathOrFile)
|
plist = p.parse(pathOrFile)
|
||||||
if didOpen:
|
if didOpen:
|
||||||
pathOrFile.close()
|
pathOrFile.close()
|
||||||
return plist
|
return plist
|
||||||
fromFile = classmethod(fromFile)
|
fromFile = classmethod(fromFile)
|
||||||
|
|
||||||
def write(self, pathOrFile):
|
def write(self, pathOrFile):
|
||||||
if not hasattr(pathOrFile, "write"):
|
if not hasattr(pathOrFile, "write"):
|
||||||
pathOrFile = open(pathOrFile, "w")
|
pathOrFile = open(pathOrFile, "w")
|
||||||
didOpen = 1
|
didOpen = 1
|
||||||
else:
|
else:
|
||||||
didOpen = 0
|
didOpen = 0
|
||||||
|
|
||||||
writer = PlistWriter(pathOrFile)
|
writer = PlistWriter(pathOrFile)
|
||||||
writer.writeln("<plist version=\"1.0\">")
|
writer.writeln("<plist version=\"1.0\">")
|
||||||
writer.writeDict(self.__dict__)
|
writer.writeDict(self.__dict__)
|
||||||
writer.writeln("</plist>")
|
writer.writeln("</plist>")
|
||||||
|
|
||||||
if didOpen:
|
if didOpen:
|
||||||
pathOrFile.close()
|
pathOrFile.close()
|
||||||
|
|
||||||
|
|
||||||
class Data:
|
class Data:
|
||||||
|
|
||||||
"""Wrapper for binary data."""
|
"""Wrapper for binary data."""
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
def fromBase64(cls, data):
|
def fromBase64(cls, data):
|
||||||
import base64
|
import base64
|
||||||
return cls(base64.decodestring(data))
|
return cls(base64.decodestring(data))
|
||||||
fromBase64 = classmethod(fromBase64)
|
fromBase64 = classmethod(fromBase64)
|
||||||
|
|
||||||
def asBase64(self):
|
def asBase64(self):
|
||||||
import base64
|
import base64
|
||||||
return base64.encodestring(self.data)
|
return base64.encodestring(self.data)
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
return cmp(self.data, other.data)
|
return cmp(self.data, other.data)
|
||||||
elif isinstance(other, str):
|
elif isinstance(other, str):
|
||||||
return cmp(self.data, other)
|
return cmp(self.data, other)
|
||||||
else:
|
else:
|
||||||
return cmp(id(self), id(other))
|
return cmp(id(self), id(other))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(%s)" % (self.__class__.__name__, repr(self.data))
|
return "%s(%s)" % (self.__class__.__name__, repr(self.data))
|
||||||
|
|
||||||
|
|
||||||
class Date:
|
class Date:
|
||||||
|
|
||||||
"""Primitive date wrapper, uses time floats internally, is agnostic
|
"""Primitive date wrapper, uses time floats internally, is agnostic
|
||||||
about time zones.
|
about time zones.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, date):
|
def __init__(self, date):
|
||||||
if isinstance(date, str):
|
if isinstance(date, str):
|
||||||
from xml.utils.iso8601 import parse
|
from xml.utils.iso8601 import parse
|
||||||
date = parse(date)
|
date = parse(date)
|
||||||
self.date = date
|
self.date = date
|
||||||
|
|
||||||
def toString(self):
|
def toString(self):
|
||||||
from xml.utils.iso8601 import tostring
|
from xml.utils.iso8601 import tostring
|
||||||
return tostring(self.date)
|
return tostring(self.date)
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
return cmp(self.date, other.date)
|
return cmp(self.date, other.date)
|
||||||
elif isinstance(other, (int, float)):
|
elif isinstance(other, (int, float)):
|
||||||
return cmp(self.date, other)
|
return cmp(self.date, other)
|
||||||
else:
|
else:
|
||||||
return cmp(id(self), id(other))
|
return cmp(id(self), id(other))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(%s)" % (self.__class__.__name__, repr(self.toString()))
|
return "%s(%s)" % (self.__class__.__name__, repr(self.toString()))
|
||||||
|
|
||||||
|
|
||||||
class PlistParser:
|
class PlistParser:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.stack = []
|
self.stack = []
|
||||||
self.currentKey = None
|
self.currentKey = None
|
||||||
self.root = None
|
self.root = None
|
||||||
|
|
||||||
def parse(self, file):
|
def parse(self, file):
|
||||||
from xml.parsers.expat import ParserCreate
|
from xml.parsers.expat import ParserCreate
|
||||||
parser = ParserCreate()
|
parser = ParserCreate()
|
||||||
parser.StartElementHandler = self.handleBeginElement
|
parser.StartElementHandler = self.handleBeginElement
|
||||||
parser.EndElementHandler = self.handleEndElement
|
parser.EndElementHandler = self.handleEndElement
|
||||||
parser.CharacterDataHandler = self.handleData
|
parser.CharacterDataHandler = self.handleData
|
||||||
parser.ParseFile(file)
|
parser.ParseFile(file)
|
||||||
return self.root
|
return self.root
|
||||||
|
|
||||||
def handleBeginElement(self, element, attrs):
|
def handleBeginElement(self, element, attrs):
|
||||||
self.data = []
|
self.data = []
|
||||||
handler = getattr(self, "begin_" + element, None)
|
handler = getattr(self, "begin_" + element, None)
|
||||||
if handler is not None:
|
if handler is not None:
|
||||||
handler(attrs)
|
handler(attrs)
|
||||||
|
|
||||||
def handleEndElement(self, element):
|
def handleEndElement(self, element):
|
||||||
handler = getattr(self, "end_" + element, None)
|
handler = getattr(self, "end_" + element, None)
|
||||||
if handler is not None:
|
if handler is not None:
|
||||||
handler()
|
handler()
|
||||||
|
|
||||||
def handleData(self, data):
|
def handleData(self, data):
|
||||||
self.data.append(data)
|
self.data.append(data)
|
||||||
|
|
||||||
def addObject(self, value):
|
def addObject(self, value):
|
||||||
if self.currentKey is not None:
|
if self.currentKey is not None:
|
||||||
self.stack[-1][self.currentKey] = value
|
self.stack[-1][self.currentKey] = value
|
||||||
self.currentKey = None
|
self.currentKey = None
|
||||||
elif not self.stack:
|
elif not self.stack:
|
||||||
# this is the root object
|
# this is the root object
|
||||||
assert self.root is value
|
assert self.root is value
|
||||||
else:
|
else:
|
||||||
self.stack[-1].append(value)
|
self.stack[-1].append(value)
|
||||||
|
|
||||||
def getData(self):
|
def getData(self):
|
||||||
data = "".join(self.data)
|
data = "".join(self.data)
|
||||||
try:
|
try:
|
||||||
data = data.encode("ascii")
|
data = data.encode("ascii")
|
||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
pass
|
pass
|
||||||
self.data = []
|
self.data = []
|
||||||
return data
|
return data
|
||||||
|
|
||||||
# element handlers
|
# element handlers
|
||||||
|
|
||||||
def begin_dict(self, attrs):
|
def begin_dict(self, attrs):
|
||||||
if self.root is None:
|
if self.root is None:
|
||||||
self.root = d = Plist()
|
self.root = d = Plist()
|
||||||
else:
|
else:
|
||||||
d = Dict()
|
d = Dict()
|
||||||
self.addObject(d)
|
self.addObject(d)
|
||||||
self.stack.append(d)
|
self.stack.append(d)
|
||||||
def end_dict(self):
|
def end_dict(self):
|
||||||
self.stack.pop()
|
self.stack.pop()
|
||||||
|
|
||||||
def end_key(self):
|
def end_key(self):
|
||||||
self.currentKey = self.getData()
|
self.currentKey = self.getData()
|
||||||
|
|
||||||
def begin_array(self, attrs):
|
def begin_array(self, attrs):
|
||||||
a = []
|
a = []
|
||||||
self.addObject(a)
|
self.addObject(a)
|
||||||
self.stack.append(a)
|
self.stack.append(a)
|
||||||
def end_array(self):
|
def end_array(self):
|
||||||
self.stack.pop()
|
self.stack.pop()
|
||||||
|
|
||||||
def end_true(self):
|
def end_true(self):
|
||||||
self.addObject(True)
|
self.addObject(True)
|
||||||
def end_false(self):
|
def end_false(self):
|
||||||
self.addObject(False)
|
self.addObject(False)
|
||||||
def end_integer(self):
|
def end_integer(self):
|
||||||
self.addObject(int(self.getData()))
|
self.addObject(int(self.getData()))
|
||||||
def end_real(self):
|
def end_real(self):
|
||||||
self.addObject(float(self.getData()))
|
self.addObject(float(self.getData()))
|
||||||
def end_string(self):
|
def end_string(self):
|
||||||
self.addObject(self.getData())
|
self.addObject(self.getData())
|
||||||
def end_data(self):
|
def end_data(self):
|
||||||
self.addObject(Data.fromBase64(self.getData()))
|
self.addObject(Data.fromBase64(self.getData()))
|
||||||
def end_date(self):
|
def end_date(self):
|
||||||
self.addObject(Date(self.getData()))
|
self.addObject(Date(self.getData()))
|
||||||
|
|
||||||
|
|
||||||
# cruft to support booleans in Python <= 2.3
|
# cruft to support booleans in Python <= 2.3
|
||||||
import sys
|
import sys
|
||||||
if sys.version_info[:2] < (2, 3):
|
if sys.version_info[:2] < (2, 3):
|
||||||
# Python 2.2 and earlier: no booleans
|
# Python 2.2 and earlier: no booleans
|
||||||
# Python 2.2.x: booleans are ints
|
# Python 2.2.x: booleans are ints
|
||||||
class bool(int):
|
class bool(int):
|
||||||
"""Imitation of the Python 2.3 bool object."""
|
"""Imitation of the Python 2.3 bool object."""
|
||||||
def __new__(cls, value):
|
def __new__(cls, value):
|
||||||
return int.__new__(cls, not not value)
|
return int.__new__(cls, not not value)
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self:
|
if self:
|
||||||
return "True"
|
return "True"
|
||||||
else:
|
else:
|
||||||
return "False"
|
return "False"
|
||||||
True = bool(1)
|
True = bool(1)
|
||||||
False = bool(0)
|
False = bool(0)
|
||||||
else:
|
else:
|
||||||
# Bind the boolean builtins to local names
|
# Bind the boolean builtins to local names
|
||||||
True = True
|
True = True
|
||||||
False = False
|
False = False
|
||||||
bool = bool
|
bool = bool
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
import time
|
import time
|
||||||
if len(sys.argv) == 1:
|
if len(sys.argv) == 1:
|
||||||
pl = Plist(
|
pl = Plist(
|
||||||
aString="Doodah",
|
aString="Doodah",
|
||||||
aList=["A", "B", 12, 32.1, [1, 2, 3]],
|
aList=["A", "B", 12, 32.1, [1, 2, 3]],
|
||||||
aFloat = 0.1,
|
aFloat = 0.1,
|
||||||
anInt = 728,
|
anInt = 728,
|
||||||
aDict=Dict(
|
aDict=Dict(
|
||||||
anotherString="<hello & hi there!>",
|
anotherString="<hello & hi there!>",
|
||||||
aUnicodeValue=u'M\xe4ssig, Ma\xdf',
|
aUnicodeValue=u'M\xe4ssig, Ma\xdf',
|
||||||
aTrueValue=True,
|
aTrueValue=True,
|
||||||
aFalseValue=False,
|
aFalseValue=False,
|
||||||
),
|
),
|
||||||
someData = Data("<binary gunk>"),
|
someData = Data("<binary gunk>"),
|
||||||
someMoreData = Data("<lots of binary gunk>" * 10),
|
someMoreData = Data("<lots of binary gunk>" * 10),
|
||||||
aDate = Date(time.mktime(time.gmtime())),
|
aDate = Date(time.mktime(time.gmtime())),
|
||||||
)
|
)
|
||||||
elif len(sys.argv) == 2:
|
elif len(sys.argv) == 2:
|
||||||
pl = Plist.fromFile(sys.argv[1])
|
pl = Plist.fromFile(sys.argv[1])
|
||||||
else:
|
else:
|
||||||
print "Too many arguments: at most 1 plist file can be given."
|
print "Too many arguments: at most 1 plist file can be given."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# unicode keys are possible, but a little awkward to use:
|
# unicode keys are possible, but a little awkward to use:
|
||||||
pl[u'\xc5benraa'] = "That was a unicode key."
|
pl[u'\xc5benraa'] = "That was a unicode key."
|
||||||
f = StringIO()
|
f = StringIO()
|
||||||
pl.write(f)
|
pl.write(f)
|
||||||
xml = f.getvalue()
|
xml = f.getvalue()
|
||||||
print xml
|
print xml
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
pl2 = Plist.fromFile(f)
|
pl2 = Plist.fromFile(f)
|
||||||
assert pl == pl2
|
assert pl == pl2
|
||||||
f = StringIO()
|
f = StringIO()
|
||||||
pl2.write(f)
|
pl2.write(f)
|
||||||
assert xml == f.getvalue()
|
assert xml == f.getvalue()
|
||||||
#print repr(pl2)
|
#print repr(pl2)
|
||||||
|
|
|
@ -13,280 +13,280 @@ from Carbon import Qdoffs
|
||||||
from Carbon import QDOffscreen
|
from Carbon import QDOffscreen
|
||||||
from Carbon import Res
|
from Carbon import Res
|
||||||
try:
|
try:
|
||||||
import MediaDescr
|
import MediaDescr
|
||||||
except ImportError:
|
except ImportError:
|
||||||
def _audiodescr(data):
|
def _audiodescr(data):
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
def _audiodescr(data):
|
def _audiodescr(data):
|
||||||
return MediaDescr.SoundDescription.decode(data)
|
return MediaDescr.SoundDescription.decode(data)
|
||||||
try:
|
try:
|
||||||
from imgformat import macrgb
|
from imgformat import macrgb
|
||||||
except ImportError:
|
except ImportError:
|
||||||
macrgb = "Macintosh RGB format"
|
macrgb = "Macintosh RGB format"
|
||||||
import os
|
import os
|
||||||
# import audio.format
|
# import audio.format
|
||||||
|
|
||||||
class VideoFormat:
|
class VideoFormat:
|
||||||
def __init__(self, name, descr, width, height, format):
|
def __init__(self, name, descr, width, height, format):
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__descr = descr
|
self.__descr = descr
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height
|
self.__height = height
|
||||||
self.__format = format
|
self.__format = format
|
||||||
|
|
||||||
def getname(self):
|
def getname(self):
|
||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
def getdescr(self):
|
def getdescr(self):
|
||||||
return self.__descr
|
return self.__descr
|
||||||
|
|
||||||
def getsize(self):
|
def getsize(self):
|
||||||
return self.__width, self.__height
|
return self.__width, self.__height
|
||||||
|
|
||||||
def getformat(self):
|
def getformat(self):
|
||||||
return self.__format
|
return self.__format
|
||||||
|
|
||||||
class _Reader:
|
class _Reader:
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
fd = Qt.OpenMovieFile(path, 0)
|
fd = Qt.OpenMovieFile(path, 0)
|
||||||
self.movie, d1, d2 = Qt.NewMovieFromFile(fd, 0, 0)
|
self.movie, d1, d2 = Qt.NewMovieFromFile(fd, 0, 0)
|
||||||
self.movietimescale = self.movie.GetMovieTimeScale()
|
self.movietimescale = self.movie.GetMovieTimeScale()
|
||||||
try:
|
try:
|
||||||
self.audiotrack = self.movie.GetMovieIndTrackType(1,
|
self.audiotrack = self.movie.GetMovieIndTrackType(1,
|
||||||
QuickTime.AudioMediaCharacteristic, QuickTime.movieTrackCharacteristic)
|
QuickTime.AudioMediaCharacteristic, QuickTime.movieTrackCharacteristic)
|
||||||
self.audiomedia = self.audiotrack.GetTrackMedia()
|
self.audiomedia = self.audiotrack.GetTrackMedia()
|
||||||
except Qt.Error:
|
except Qt.Error:
|
||||||
self.audiotrack = self.audiomedia = None
|
self.audiotrack = self.audiomedia = None
|
||||||
self.audiodescr = {}
|
self.audiodescr = {}
|
||||||
else:
|
else:
|
||||||
handle = Res.Handle('')
|
handle = Res.Handle('')
|
||||||
n = self.audiomedia.GetMediaSampleDescriptionCount()
|
n = self.audiomedia.GetMediaSampleDescriptionCount()
|
||||||
self.audiomedia.GetMediaSampleDescription(1, handle)
|
self.audiomedia.GetMediaSampleDescription(1, handle)
|
||||||
self.audiodescr = _audiodescr(handle.data)
|
self.audiodescr = _audiodescr(handle.data)
|
||||||
self.audiotimescale = self.audiomedia.GetMediaTimeScale()
|
self.audiotimescale = self.audiomedia.GetMediaTimeScale()
|
||||||
del handle
|
del handle
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.videotrack = self.movie.GetMovieIndTrackType(1,
|
self.videotrack = self.movie.GetMovieIndTrackType(1,
|
||||||
QuickTime.VisualMediaCharacteristic, QuickTime.movieTrackCharacteristic)
|
QuickTime.VisualMediaCharacteristic, QuickTime.movieTrackCharacteristic)
|
||||||
self.videomedia = self.videotrack.GetTrackMedia()
|
self.videomedia = self.videotrack.GetTrackMedia()
|
||||||
except Qt.Error:
|
except Qt.Error:
|
||||||
self.videotrack = self.videomedia = self.videotimescale = None
|
self.videotrack = self.videomedia = self.videotimescale = None
|
||||||
if self.videotrack:
|
if self.videotrack:
|
||||||
self.videotimescale = self.videomedia.GetMediaTimeScale()
|
self.videotimescale = self.videomedia.GetMediaTimeScale()
|
||||||
x0, y0, x1, y1 = self.movie.GetMovieBox()
|
x0, y0, x1, y1 = self.movie.GetMovieBox()
|
||||||
self.videodescr = {'width':(x1-x0), 'height':(y1-y0)}
|
self.videodescr = {'width':(x1-x0), 'height':(y1-y0)}
|
||||||
self._initgworld()
|
self._initgworld()
|
||||||
self.videocurtime = None
|
self.videocurtime = None
|
||||||
self.audiocurtime = None
|
self.audiocurtime = None
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.audiomedia = None
|
self.audiomedia = None
|
||||||
self.audiotrack = None
|
self.audiotrack = None
|
||||||
self.videomedia = None
|
self.videomedia = None
|
||||||
self.videotrack = None
|
self.videotrack = None
|
||||||
self.movie = None
|
self.movie = None
|
||||||
|
|
||||||
def _initgworld(self):
|
def _initgworld(self):
|
||||||
old_port, old_dev = Qdoffs.GetGWorld()
|
old_port, old_dev = Qdoffs.GetGWorld()
|
||||||
try:
|
try:
|
||||||
movie_w = self.videodescr['width']
|
movie_w = self.videodescr['width']
|
||||||
movie_h = self.videodescr['height']
|
movie_h = self.videodescr['height']
|
||||||
movie_rect = (0, 0, movie_w, movie_h)
|
movie_rect = (0, 0, movie_w, movie_h)
|
||||||
self.gworld = Qdoffs.NewGWorld(32, movie_rect, None, None, QDOffscreen.keepLocal)
|
self.gworld = Qdoffs.NewGWorld(32, movie_rect, None, None, QDOffscreen.keepLocal)
|
||||||
self.pixmap = self.gworld.GetGWorldPixMap()
|
self.pixmap = self.gworld.GetGWorldPixMap()
|
||||||
Qdoffs.LockPixels(self.pixmap)
|
Qdoffs.LockPixels(self.pixmap)
|
||||||
Qdoffs.SetGWorld(self.gworld.as_GrafPtr(), None)
|
Qdoffs.SetGWorld(self.gworld.as_GrafPtr(), None)
|
||||||
Qd.EraseRect(movie_rect)
|
Qd.EraseRect(movie_rect)
|
||||||
self.movie.SetMovieGWorld(self.gworld.as_GrafPtr(), None)
|
self.movie.SetMovieGWorld(self.gworld.as_GrafPtr(), None)
|
||||||
self.movie.SetMovieBox(movie_rect)
|
self.movie.SetMovieBox(movie_rect)
|
||||||
self.movie.SetMovieActive(1)
|
self.movie.SetMovieActive(1)
|
||||||
self.movie.MoviesTask(0)
|
self.movie.MoviesTask(0)
|
||||||
self.movie.SetMoviePlayHints(QuickTime.hintsHighQuality, QuickTime.hintsHighQuality)
|
self.movie.SetMoviePlayHints(QuickTime.hintsHighQuality, QuickTime.hintsHighQuality)
|
||||||
# XXXX framerate
|
# XXXX framerate
|
||||||
finally:
|
finally:
|
||||||
Qdoffs.SetGWorld(old_port, old_dev)
|
Qdoffs.SetGWorld(old_port, old_dev)
|
||||||
|
|
||||||
def _gettrackduration_ms(self, track):
|
def _gettrackduration_ms(self, track):
|
||||||
tracktime = track.GetTrackDuration()
|
tracktime = track.GetTrackDuration()
|
||||||
return self._movietime_to_ms(tracktime)
|
return self._movietime_to_ms(tracktime)
|
||||||
|
|
||||||
def _movietime_to_ms(self, time):
|
def _movietime_to_ms(self, time):
|
||||||
value, d1, d2 = Qt.ConvertTimeScale((time, self.movietimescale, None), 1000)
|
value, d1, d2 = Qt.ConvertTimeScale((time, self.movietimescale, None), 1000)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _videotime_to_ms(self, time):
|
def _videotime_to_ms(self, time):
|
||||||
value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None), 1000)
|
value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None), 1000)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _audiotime_to_ms(self, time):
|
def _audiotime_to_ms(self, time):
|
||||||
value, d1, d2 = Qt.ConvertTimeScale((time, self.audiotimescale, None), 1000)
|
value, d1, d2 = Qt.ConvertTimeScale((time, self.audiotimescale, None), 1000)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _videotime_to_movietime(self, time):
|
def _videotime_to_movietime(self, time):
|
||||||
value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None),
|
value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None),
|
||||||
self.movietimescale)
|
self.movietimescale)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def HasAudio(self):
|
def HasAudio(self):
|
||||||
return not self.audiotrack is None
|
return not self.audiotrack is None
|
||||||
|
|
||||||
def HasVideo(self):
|
def HasVideo(self):
|
||||||
return not self.videotrack is None
|
return not self.videotrack is None
|
||||||
|
|
||||||
def GetAudioDuration(self):
|
def GetAudioDuration(self):
|
||||||
if not self.audiotrack:
|
if not self.audiotrack:
|
||||||
return 0
|
return 0
|
||||||
return self._gettrackduration_ms(self.audiotrack)
|
return self._gettrackduration_ms(self.audiotrack)
|
||||||
|
|
||||||
def GetVideoDuration(self):
|
def GetVideoDuration(self):
|
||||||
if not self.videotrack:
|
if not self.videotrack:
|
||||||
return 0
|
return 0
|
||||||
return self._gettrackduration_ms(self.videotrack)
|
return self._gettrackduration_ms(self.videotrack)
|
||||||
|
|
||||||
def GetAudioFormat(self):
|
def GetAudioFormat(self):
|
||||||
if not self.audiodescr:
|
if not self.audiodescr:
|
||||||
return None, None, None, None, None
|
return None, None, None, None, None
|
||||||
bps = self.audiodescr['sampleSize']
|
bps = self.audiodescr['sampleSize']
|
||||||
nch = self.audiodescr['numChannels']
|
nch = self.audiodescr['numChannels']
|
||||||
if nch == 1:
|
if nch == 1:
|
||||||
channels = ['mono']
|
channels = ['mono']
|
||||||
elif nch == 2:
|
elif nch == 2:
|
||||||
channels = ['left', 'right']
|
channels = ['left', 'right']
|
||||||
else:
|
else:
|
||||||
channels = map(lambda x: str(x+1), range(nch))
|
channels = map(lambda x: str(x+1), range(nch))
|
||||||
if bps % 8:
|
if bps % 8:
|
||||||
# Funny bits-per sample. We pretend not to understand
|
# Funny bits-per sample. We pretend not to understand
|
||||||
blocksize = 0
|
blocksize = 0
|
||||||
fpb = 0
|
fpb = 0
|
||||||
else:
|
else:
|
||||||
# QuickTime is easy (for as far as we support it): samples are always a whole
|
# QuickTime is easy (for as far as we support it): samples are always a whole
|
||||||
# number of bytes, so frames are nchannels*samplesize, and there's one frame per block.
|
# number of bytes, so frames are nchannels*samplesize, and there's one frame per block.
|
||||||
blocksize = (bps/8)*nch
|
blocksize = (bps/8)*nch
|
||||||
fpb = 1
|
fpb = 1
|
||||||
if self.audiodescr['dataFormat'] == 'raw ':
|
if self.audiodescr['dataFormat'] == 'raw ':
|
||||||
encoding = 'linear-excess'
|
encoding = 'linear-excess'
|
||||||
elif self.audiodescr['dataFormat'] == 'twos':
|
elif self.audiodescr['dataFormat'] == 'twos':
|
||||||
encoding = 'linear-signed'
|
encoding = 'linear-signed'
|
||||||
else:
|
else:
|
||||||
encoding = 'quicktime-coding-%s'%self.audiodescr['dataFormat']
|
encoding = 'quicktime-coding-%s'%self.audiodescr['dataFormat']
|
||||||
## return audio.format.AudioFormatLinear('quicktime_audio', 'QuickTime Audio Format',
|
## return audio.format.AudioFormatLinear('quicktime_audio', 'QuickTime Audio Format',
|
||||||
## channels, encoding, blocksize=blocksize, fpb=fpb, bps=bps)
|
## channels, encoding, blocksize=blocksize, fpb=fpb, bps=bps)
|
||||||
return channels, encoding, blocksize, fpb, bps
|
return channels, encoding, blocksize, fpb, bps
|
||||||
|
|
||||||
def GetAudioFrameRate(self):
|
def GetAudioFrameRate(self):
|
||||||
if not self.audiodescr:
|
if not self.audiodescr:
|
||||||
return None
|
return None
|
||||||
return int(self.audiodescr['sampleRate'])
|
return int(self.audiodescr['sampleRate'])
|
||||||
|
|
||||||
def GetVideoFormat(self):
|
def GetVideoFormat(self):
|
||||||
width = self.videodescr['width']
|
width = self.videodescr['width']
|
||||||
height = self.videodescr['height']
|
height = self.videodescr['height']
|
||||||
return VideoFormat('dummy_format', 'Dummy Video Format', width, height, macrgb)
|
return VideoFormat('dummy_format', 'Dummy Video Format', width, height, macrgb)
|
||||||
|
|
||||||
def GetVideoFrameRate(self):
|
def GetVideoFrameRate(self):
|
||||||
tv = self.videocurtime
|
tv = self.videocurtime
|
||||||
if tv == None:
|
if tv == None:
|
||||||
tv = 0
|
tv = 0
|
||||||
flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
|
flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
|
||||||
tv, dur = self.videomedia.GetMediaNextInterestingTime(flags, tv, 1.0)
|
tv, dur = self.videomedia.GetMediaNextInterestingTime(flags, tv, 1.0)
|
||||||
dur = self._videotime_to_ms(dur)
|
dur = self._videotime_to_ms(dur)
|
||||||
return int((1000.0/dur)+0.5)
|
return int((1000.0/dur)+0.5)
|
||||||
|
|
||||||
def ReadAudio(self, nframes, time=None):
|
def ReadAudio(self, nframes, time=None):
|
||||||
if not time is None:
|
if not time is None:
|
||||||
self.audiocurtime = time
|
self.audiocurtime = time
|
||||||
flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
|
flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
|
||||||
if self.audiocurtime == None:
|
if self.audiocurtime == None:
|
||||||
self.audiocurtime = 0
|
self.audiocurtime = 0
|
||||||
tv = self.audiomedia.GetMediaNextInterestingTimeOnly(flags, self.audiocurtime, 1.0)
|
tv = self.audiomedia.GetMediaNextInterestingTimeOnly(flags, self.audiocurtime, 1.0)
|
||||||
if tv < 0 or (self.audiocurtime and tv < self.audiocurtime):
|
if tv < 0 or (self.audiocurtime and tv < self.audiocurtime):
|
||||||
return self._audiotime_to_ms(self.audiocurtime), None
|
return self._audiotime_to_ms(self.audiocurtime), None
|
||||||
h = Res.Handle('')
|
h = Res.Handle('')
|
||||||
desc_h = Res.Handle('')
|
desc_h = Res.Handle('')
|
||||||
size, actualtime, sampleduration, desc_index, actualcount, flags = \
|
size, actualtime, sampleduration, desc_index, actualcount, flags = \
|
||||||
self.audiomedia.GetMediaSample(h, 0, tv, desc_h, nframes)
|
self.audiomedia.GetMediaSample(h, 0, tv, desc_h, nframes)
|
||||||
self.audiocurtime = actualtime + actualcount*sampleduration
|
self.audiocurtime = actualtime + actualcount*sampleduration
|
||||||
return self._audiotime_to_ms(actualtime), h.data
|
return self._audiotime_to_ms(actualtime), h.data
|
||||||
|
|
||||||
def ReadVideo(self, time=None):
|
def ReadVideo(self, time=None):
|
||||||
if not time is None:
|
if not time is None:
|
||||||
self.videocurtime = time
|
self.videocurtime = time
|
||||||
flags = QuickTime.nextTimeStep
|
flags = QuickTime.nextTimeStep
|
||||||
if self.videocurtime == None:
|
if self.videocurtime == None:
|
||||||
flags = flags | QuickTime.nextTimeEdgeOK
|
flags = flags | QuickTime.nextTimeEdgeOK
|
||||||
self.videocurtime = 0
|
self.videocurtime = 0
|
||||||
tv = self.videomedia.GetMediaNextInterestingTimeOnly(flags, self.videocurtime, 1.0)
|
tv = self.videomedia.GetMediaNextInterestingTimeOnly(flags, self.videocurtime, 1.0)
|
||||||
if tv < 0 or (self.videocurtime and tv <= self.videocurtime):
|
if tv < 0 or (self.videocurtime and tv <= self.videocurtime):
|
||||||
return self._videotime_to_ms(self.videocurtime), None
|
return self._videotime_to_ms(self.videocurtime), None
|
||||||
self.videocurtime = tv
|
self.videocurtime = tv
|
||||||
moviecurtime = self._videotime_to_movietime(self.videocurtime)
|
moviecurtime = self._videotime_to_movietime(self.videocurtime)
|
||||||
self.movie.SetMovieTimeValue(moviecurtime)
|
self.movie.SetMovieTimeValue(moviecurtime)
|
||||||
self.movie.MoviesTask(0)
|
self.movie.MoviesTask(0)
|
||||||
return self._videotime_to_ms(self.videocurtime), self._getpixmapcontent()
|
return self._videotime_to_ms(self.videocurtime), self._getpixmapcontent()
|
||||||
|
|
||||||
def _getpixmapcontent(self):
|
def _getpixmapcontent(self):
|
||||||
"""Shuffle the offscreen PixMap data, because it may have funny stride values"""
|
"""Shuffle the offscreen PixMap data, because it may have funny stride values"""
|
||||||
rowbytes = Qdoffs.GetPixRowBytes(self.pixmap)
|
rowbytes = Qdoffs.GetPixRowBytes(self.pixmap)
|
||||||
width = self.videodescr['width']
|
width = self.videodescr['width']
|
||||||
height = self.videodescr['height']
|
height = self.videodescr['height']
|
||||||
start = 0
|
start = 0
|
||||||
rv = ''
|
rv = ''
|
||||||
for i in range(height):
|
for i in range(height):
|
||||||
nextline = Qdoffs.GetPixMapBytes(self.pixmap, start, width*4)
|
nextline = Qdoffs.GetPixMapBytes(self.pixmap, start, width*4)
|
||||||
start = start + rowbytes
|
start = start + rowbytes
|
||||||
rv = rv + nextline
|
rv = rv + nextline
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def reader(url):
|
def reader(url):
|
||||||
try:
|
try:
|
||||||
rdr = _Reader(url)
|
rdr = _Reader(url)
|
||||||
except IOError:
|
except IOError:
|
||||||
return None
|
return None
|
||||||
return rdr
|
return rdr
|
||||||
|
|
||||||
def _test():
|
def _test():
|
||||||
import EasyDialogs
|
import EasyDialogs
|
||||||
try:
|
try:
|
||||||
import img
|
import img
|
||||||
except ImportError:
|
except ImportError:
|
||||||
img = None
|
img = None
|
||||||
import MacOS
|
import MacOS
|
||||||
Qt.EnterMovies()
|
Qt.EnterMovies()
|
||||||
path = EasyDialogs.AskFileForOpen(message='Video to convert')
|
path = EasyDialogs.AskFileForOpen(message='Video to convert')
|
||||||
if not path: sys.exit(0)
|
if not path: sys.exit(0)
|
||||||
rdr = reader(path)
|
rdr = reader(path)
|
||||||
if not rdr:
|
if not rdr:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
dstdir = EasyDialogs.AskFileForSave(message='Name for output folder')
|
dstdir = EasyDialogs.AskFileForSave(message='Name for output folder')
|
||||||
if not dstdir: sys.exit(0)
|
if not dstdir: sys.exit(0)
|
||||||
num = 0
|
num = 0
|
||||||
os.mkdir(dstdir)
|
os.mkdir(dstdir)
|
||||||
videofmt = rdr.GetVideoFormat()
|
videofmt = rdr.GetVideoFormat()
|
||||||
imgfmt = videofmt.getformat()
|
imgfmt = videofmt.getformat()
|
||||||
imgw, imgh = videofmt.getsize()
|
imgw, imgh = videofmt.getsize()
|
||||||
timestamp, data = rdr.ReadVideo()
|
timestamp, data = rdr.ReadVideo()
|
||||||
while data:
|
while data:
|
||||||
fname = 'frame%04.4d.jpg'%num
|
fname = 'frame%04.4d.jpg'%num
|
||||||
num = num+1
|
num = num+1
|
||||||
pname = os.path.join(dstdir, fname)
|
pname = os.path.join(dstdir, fname)
|
||||||
if not img: print 'Not',
|
if not img: print 'Not',
|
||||||
print 'Writing %s, size %dx%d, %d bytes'%(fname, imgw, imgh, len(data))
|
print 'Writing %s, size %dx%d, %d bytes'%(fname, imgw, imgh, len(data))
|
||||||
if img:
|
if img:
|
||||||
wrt = img.writer(imgfmt, pname)
|
wrt = img.writer(imgfmt, pname)
|
||||||
wrt.width = imgw
|
wrt.width = imgw
|
||||||
wrt.height = imgh
|
wrt.height = imgh
|
||||||
wrt.write(data)
|
wrt.write(data)
|
||||||
timestamp, data = rdr.ReadVideo()
|
timestamp, data = rdr.ReadVideo()
|
||||||
MacOS.SetCreatorAndType(pname, 'ogle', 'JPEG')
|
MacOS.SetCreatorAndType(pname, 'ogle', 'JPEG')
|
||||||
if num > 20:
|
if num > 20:
|
||||||
print 'stopping at 20 frames so your disk does not fill up:-)'
|
print 'stopping at 20 frames so your disk does not fill up:-)'
|
||||||
break
|
break
|
||||||
print 'Total frames:', num
|
print 'Total frames:', num
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
_test()
|
_test()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue