diff --git a/Mac/scripts/BuildApplet.py b/Mac/scripts/BuildApplet.py index 4cff1852b16..b57c425b110 100644 --- a/Mac/scripts/BuildApplet.py +++ b/Mac/scripts/BuildApplet.py @@ -6,64 +6,32 @@ It is created by copying an applet template and then adding a 'PYC ' resource named __main__ containing the compiled, marshalled script. """ -DEBUG=0 import sys sys.stdout = sys.stderr -import string import os -import marshal -import imp import macfs -import MACFS import MacOS -from Res import * -import macostools import EasyDialogs +import buildtools -# .pyc file (and 'PYC ' resource magic number) -MAGIC = imp.get_magic() - -# Template file (searched on sys.path) -TEMPLATE = "PythonApplet" - -# Specification of our resource -RESTYPE = 'PYC ' -RESNAME = '__main__' - -# A resource with this name sets the "owner" (creator) of the destination -# XXXX Should look for id=0 -OWNERNAME = "owner resource" - -# OpenResFile mode parameters -READ = 1 -WRITE = 2 - -def findtemplate(): - """Locate the applet template along sys.path""" - for p in sys.path: - template = os.path.join(p, TEMPLATE) - try: - template, d1, d2 = macfs.ResolveAliasFile(template) - break - except (macfs.error, ValueError): - continue - else: - die("Template %s not found on sys.path" % `TEMPLATE`) - return - template = template.as_pathname() - return template def main(): - global DEBUG - DEBUG=1 + try: + buildapplet() + except buildtools.BuildError, detail: + EasyDialogs.Message(detail) + + +def buildapplet(): + buildtools.DEBUG=1 # Find the template # (there's no point in proceeding if we can't find it) - template = findtemplate() - + template = buildtools.findtemplate() + # Ask for source text if not specified in sys.argv[1:] if not sys.argv[1:]: @@ -75,267 +43,24 @@ def main(): if tf[-3:] == '.py': tf = tf[:-3] else: - tf = tf + '.out' + tf = tf + '.applet' dstfss, ok = macfs.StandardPutFile('Save application as:', tf) if not ok: return dstfilename = dstfss.as_pathname() cr, tp = MacOS.GetCreatorAndType(filename) if tp == 'APPL': - update(template, filename, dstfilename) + buildtools.update(template, filename, dstfilename) else: - process(template, filename, dstfilename) + buildtools.process(template, filename, dstfilename, 1) else: # Loop over all files to be processed for filename in sys.argv[1:]: cr, tp = MacOS.GetCreatorAndType(filename) if tp == 'APPL': - update(template, filename, '') + buildtools.update(template, filename, '') else: - process(template, filename, '') - -def process(template, filename, output): - - if DEBUG: - progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120) - progress.label("Compiling...") - else: - progress = None - - # Read the source and compile it - # (there's no point overwriting the destination if it has a syntax error) - - fp = open(filename) - text = fp.read() - fp.close() - try: - code = compile(text, filename, "exec") - except (SyntaxError, EOFError): - die("Syntax error in script %s" % `filename`) - return - - # Set the destination file name - - if string.lower(filename[-3:]) == ".py": - destname = filename[:-3] - rsrcname = destname + '.rsrc' - else: - destname = filename + ".applet" - rsrcname = filename + '.rsrc' - - if output: - destname = output - - process_common(template, progress, code, rsrcname, destname, 0) - -def update(template, filename, output): - if DEBUG: - progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120) - else: - progress = None - if not output: - output = filename + ' (updated)' - process_common(template, progress, None, filename, output, 1) - - -def process_common(template, progress, code, rsrcname, destname, is_update): - # Try removing the output file - try: - os.unlink(destname) - except os.error: - pass - - - # Create FSSpecs for the various files - - template_fss = macfs.FSSpec(template) - template_fss, d1, d2 = macfs.ResolveAliasFile(template_fss) - dest_fss = macfs.FSSpec(destname) - - # Copy data (not resources, yet) from the template - if DEBUG: - progress.label("Copy data fork...") - progress.set(10) - - tmpl = open(template, "rb") - dest = open(destname, "wb") - data = tmpl.read() - if data: - dest.write(data) - dest.close() - tmpl.close() - del dest - del tmpl - - # Open the output resource fork - - if DEBUG: - progress.label("Copy resources...") - progress.set(20) - try: - output = FSpOpenResFile(dest_fss, WRITE) - except MacOS.Error: - CreateResFile(destname) - output = FSpOpenResFile(dest_fss, WRITE) - - # Copy the resources from the target specific resource template, if any - typesfound, ownertype = [], None - try: - input = FSpOpenResFile(rsrcname, READ) - except (MacOS.Error, ValueError): - pass - if DEBUG: - progress.inc(50) - else: - if is_update: - skip_oldfile = ['cfrg'] - else: - skip_oldfile = [] - typesfound, ownertype = copyres(input, output, skip_oldfile, 0, progress) - CloseResFile(input) - - # Check which resource-types we should not copy from the template - skiptypes = [] - if 'SIZE' in typesfound: skiptypes.append('SIZE') - if 'BNDL' in typesfound: skiptypes = skiptypes + ['BNDL', 'FREF', 'icl4', - 'icl8', 'ics4', 'ics8', 'ICN#', 'ics#'] - skipowner = (ownertype <> None) - - # Copy the resources from the template - - input = FSpOpenResFile(template_fss, READ) - dummy, tmplowner = copyres(input, output, skiptypes, skipowner, progress) - if ownertype == None: - ownertype = tmplowner - CloseResFile(input) - if ownertype == None: - die("No owner resource found in either resource file or template") - - # Make sure we're manipulating the output resource file now - - UseResFile(output) - - if code: - # Delete any existing 'PYC ' resource named __main__ - - try: - res = Get1NamedResource(RESTYPE, RESNAME) - res.RemoveResource() - except Error: - pass - - # Create the raw data for the resource from the code object - if DEBUG: - progress.label("Write PYC resource...") - progress.set(120) - - data = marshal.dumps(code) - del code - data = (MAGIC + '\0\0\0\0') + data - - # Create the resource and write it - - id = 0 - while id < 128: - id = Unique1ID(RESTYPE) - res = Resource(data) - res.AddResource(RESTYPE, id, RESNAME) - res.WriteResource() - res.ReleaseResource() - - # Close the output file - - CloseResFile(output) - - # Now set the creator, type and bundle bit of the destination - dest_finfo = dest_fss.GetFInfo() - dest_finfo.Creator = ownertype - dest_finfo.Type = 'APPL' - dest_finfo.Flags = dest_finfo.Flags | MACFS.kHasBundle - dest_finfo.Flags = dest_finfo.Flags & ~MACFS.kHasBeenInited - dest_fss.SetFInfo(dest_finfo) - - macostools.touched(dest_fss) - if DEBUG: - progress.label("Done.") - - -# Copy resources between two resource file descriptors. -# skip a resource named '__main__' or (if skipowner is set) 'Owner resource'. -# Also skip resources with a type listed in skiptypes. -# -def copyres(input, output, skiptypes, skipowner, progress=None): - ctor = None - alltypes = [] - UseResFile(input) - ntypes = Count1Types() - progress_type_inc = 50/ntypes - for itype in range(1, 1+ntypes): - type = Get1IndType(itype) - if type in skiptypes: - continue - alltypes.append(type) - nresources = Count1Resources(type) - progress_cur_inc = progress_type_inc/nresources - for ires in range(1, 1+nresources): - res = Get1IndResource(type, ires) - id, type, name = res.GetResInfo() - lcname = string.lower(name) -## if (type, lcname) == (RESTYPE, RESNAME): -## continue # Don't copy __main__ from template - # XXXX should look for id=0 - if lcname == OWNERNAME: - if skipowner: - continue # Skip this one - else: - ctor = type - size = res.size - attrs = res.GetResAttrs() - if DEBUG and progress: - progress.label("Copy %s %d %s"%(type, id, name)) - progress.inc(progress_cur_inc) - res.LoadResource() - res.DetachResource() - UseResFile(output) - try: - res2 = Get1Resource(type, id) - except MacOS.Error: - res2 = None - if res2: - if DEBUG and progress: - progress.label("Overwrite %s %d %s"%(type, id, name)) - res2.RemoveResource() - res.AddResource(type, id, name) - res.WriteResource() - attrs = attrs | res.GetResAttrs() - res.SetResAttrs(attrs) - UseResFile(input) - return alltypes, ctor - - -# Show a message and exit - -def die(str): - message(str) - sys.exit(1) - - -# Show a message - -def message(str, id = 256): - from Dlg import * - d = GetNewDialog(id, -1) - if not d: - print "Error:", `str` - print "DLOG id =", id, "not found." - return - tp, h, rect = d.GetDialogItem(2) - SetDialogItemText(h, str) - d.SetDialogDefaultItem(1) - while 1: - n = ModalDialog(None) - if n == 1: break - del d + buildtools.process(template, filename, '', 1) if __name__ == '__main__': diff --git a/Mac/scripts/BuildApplet.rsrc.hqx b/Mac/scripts/BuildApplet.rsrc.hqx index 5f104277440..cf90017d005 100644 --- a/Mac/scripts/BuildApplet.rsrc.hqx +++ b/Mac/scripts/BuildApplet.rsrc.hqx @@ -1,38 +1,38 @@ (This file must be converted with BinHex 4.0) -:%%*eD@aN3A"`E'9d,R*cFQ-!FR0bBe*6483"!*!(#dPr5J#3"!%!!!!+2!!!#6` -!!!%00K3J9#"S!"3J8(d4X'J4!$S"CbB5,`a1ZJ)-$$S!@RN33R9TE'4"F("XCA3 -ZFR0bBf-ZD(&iBbjSFAJZ1'*`H3!!FR0bBe*6483"!!"!!!%!N!m"Al1`(eFK!*! -'#dRr%F#SD3%G3"(rma0`!"!Zrr1pdK&Q%&%f[P9V!3,fK[P9V!3%`86)"Caj -%&3`!!"aP%R!!%#j$&3`!!"pL"R!"B!!"!3)X@P3Y,N5p!3!E2!&Q-#G92KT+J#" -6!LJ![`!Z)J$Y#3)"!%#$+0Xd%kRA,`a1ZJ%*5QGV!3#Q9d-k!!!"!*!,3!!!!+! -!!!&3!!!#U!!!"&3!!!NN!!!5P!!$rrm!"!!!J!2rr`!"!!)!!3!#!!%!!`!"!!2 -J!3!$)!%!!L!"!!)J!rrr,J3!!,i$rrm1!+`%!!'Z#!!"rK!!!"!J!!!)3!!!")! -!!!-!N"K!!!!!i!!!!I!!!!2i!!!(r!!!$r`!!"rm!!2rr`!(rrq!!rrr!!(rrJ! -"rri!!Irr!!(rrq!"rrmJ!Irq)!(rrL!$rrmZ"rrr[J2rr`i!rr`!!Iri!!(rm!! -!(q!!!!r!!!!(J!!!!`#3%3T3i!!HK)!!"k%J!!!!"d&38%`!N!C!!!!"!!+!"8! -)3$ri%"!3(K!5%"-rq`iJ$N!#J!%!N!8"!!1!"m!2`$ri(r!IrKrb(r-rq`rJ$m! -$J!%!N!8%!*"5r`#3([m!r`#3(2m!X!$r!*!Dr`#`!,!!r`#3'2m!!!#`!2m&r`# -3&[m!!,!!!2m&"Im!N"Ar!!#`!,!!!2m&r`#3%2q3%J#3$Im!!#X!+j!+q5[jqIm -!N!hrN")!N!rr!!!VN!VjqIm!N"$r!!!!+j!)qIRjr`#3%2m!!#Z3#[Rjrrm!N!r -r!!!!+j!)qIRjrj!&!*!-r`!!+j!+qIRrr`!!r`#3$2m!!!!VN!MjqIRr!!!!r`# -3$2m!!#Z3#[Rjr`!!!2m!N![rN")!!2m!APjH!*!'r`!!+`!VN!Vj+rRjr`$rrej -HAJ#3"rq3%J#3"&jHAJ#3#E!&X!@`X2NVN!Ajr`#3%E#`"E!&X,#`q5XV+rRr!*! -5X*!)q5XVqIm!N"IrqC!%+rRr!*!CrrNV+rRr!*!ErrRjr`#3(Irr!*"b!J#3+3m -!N!r`m!#3$3m&$`#3$I"382!!N!X2!!82(`#3#r!&!2%I!*!+$`"38!mI!*!)rj! -*!*!'$`$!c*!&h0h`!*!'rj!*!*!($`$-N!AGm!#3"`m!$-c-c-hGm!#3"`m!c*! -&hIm!N!F2!!c-c-c0hIrrm!#3"3m!c*!&hIm!m!#3"3m!$-c-c-hGm!$`!*!&$`$ --N!AGm!$`!*!&rj!*!2#lX!!!$`$!c*!&h0h`rlZ`!!!!rj!*!!#lX!#3"&&49Gc --c0m!N!J&89&9AFc0m!#3#!99999Gc0m!N!X2hGh0m!#3$2h-h`#3$3rGm!#3$[m -!N$S"!*!Br`#3$[m!r`#3$2m!X!$r!*!+r`#3"2m&!*!(rj!,!*!'r`!VN!Ajr`# -3"rm!+j!&qIq3"!#3"2m!+j!&qIm!!2m!N!6r!#Z3"IRr!!"HAJ!!rj!,!&jH!*! -%X,#`+b[jr`#3#E#`X#[jr`#3$2rjr`#3$[m!N"Z!!*!,$`#3"r$`!*!&$`82!*! -&m!!2%!!!!2q3"I!!!!m-c-cI!!!!$`c-c0rrm!!2$-c-h`$`!!m-c-cI!,X!rj! -&m,X!!&9FcI!!N!49A0m!N!Epm!#3"Jm!N!m(9%9B9!!"!*!%!3#3"!FUN!3!!J# -3"#a3HA3a!!!!!8C548B!!J!!!)!!!3#"!!)!JNP$6L-!!J!!!5`!!3!!!!)!N!3 -"!!!!#M`!!!Nm!!!"$3FdRi3RUJ!!!"`!rJ!*3Nj%6!!!!&**3diM!!!!AP0*@N8 -!!!"U4P*&4J!#!(CTBh-M!!!!QQPME$J!!!#QD@0X0!!!!,*TBh-i!!!![QPMFc3 -!!!$+8(Pd-3!!!0B!J2rr!!!*$!FdR-!",2rr!*!%"c5G$2q3"!!!!33!N!@!rrm -!!!%5"c5G#!#"rrm!!!Ma"c5G"!##rrm!!!N""c5FV!%Xrrm!!!%G"c5FZ!%Xrrm -!!!&K"c5F[!%Xrrm!!!9P"c5Fb!%Xrrm!!!GT"c5FY!%Xrrm!!!KY"c5Fa!#3"JM -m"c5G!!j2GfjPFL"bCA0[GA*MC@-!: +:%%*eD@aN3A"`E'9d,R*cFQ-!FR0bBe*6483"!*!(#h()%3#3"!%!!!!+8!!!#9! +!!!%K0K3J9#"S!"3J8(d4X'J4!$S"CbB5,`a1ZJ)-$$S!@RN33R9TE'4"F("XCA3 +ZFR0bBh3#!!!!8'&bG&0*9#%!N!43BA*d8dP8)3#3',(QTJ%!N!B,FIm4`+KT!4e +!%Irc%h!!%#lrmlh5%@B386Dq9@X"!8*%[D'q9@X"!6"4-J&R(N39$!!!('85F!! +3,N-9$!!!(f)'F!&J!!%"!LaD9#dZ4,d"!"Xm!@B`*e8q'NU!)&-#+!#r!#iL!1d +*!J%!3)-Sfc36UGF[$%kk!3P+CfX"!+CA3cS!!!%!N!Y!!!!!S!!!!9!!!!+S!!! +%9!!!#53!!"+8!!2rr`!%!!#!!rrr!!%!!J!"!!)!!3!$!!%!!q!"!!-J!3!#)!% +!!L!$rrmZ"!!![J2rr`i!V!3!!Di)!!(q%!!!%#!!!!K!!!!%J!!!!`#3'%!!!!$ +J!!!"m!!!!rJ!!!Im!!!2r!!!(r`!!rrr!!Irri!$rrm!!Irq!!(rrJ!"rrm!!Ir +ri!(rrb!"rriJ!Irq)!2rrbi(rrqq!rrr$J$rr!!"rrJ!!Ir`!!!Ii!!!$m!!!!H +!!!!$!*!4#P$J!"k%J!!(S5!!!!!(39"36!#3"N!!!!%!!S!&3!K!2rJ3%"!H%") +3%crl$L!13!+!!3#3"3%!!i!(`!r!2rJIm"rq(r)Imcrl$q!2`!1!!3#3"33!N&, +r!*!Hr`$r!*!Fr`#`!2m!N"Vr!,!!X!$r!*!Br`!!!,!!r`Ar!*!@r`!!X!!!r`8 +&r`#3&Im!!,!!X!!!r`Ar!*!3rj!5!*!0r`!!+`!VN!Vj+rRjr`#3$Iq3%J#3$rm +!!#Z3#[Rjr`#3%2m!!!!VN!MjqIRr!*!3r`!!+j!+qIRrr`#3$rm!!!!VN!MjqIR +rN!8!N!cr!!!VN!VjqIrr!!$r!*!-r`!!!#Z3#2RjqIm!!!$r!*!-r`!!+j!+qIR +r!!!!r`#3#rq3%J!!r`"HAPi!N!Er!!!V!#Z3#[NVqIRr!2rrAPjH!*!(rj!5!*! +%APjH!*!*X!@`"E#`q5Z3"IRr!*!4X,!&X!@`X,$j+bXVqIm!N"+`N!Mj+b[jr`# +3&rrjN!3VqIm!N"Rrq5XVqIm!N"[rqIRr!*!Grrm!N()#!*!T$`#3$r$`!*!0$`8 +2!*!0m&"3m!#3#`m!"3mI!*!,m!8!m4m!N!S2!&"3$am!N!MrN!N!N!B2!-$-N!A +FhI!!N!ErN!N!N!F2!-b3"Gh`!*!($`!-c-c-cGh`!*!($`$-N!AGr`#3"`m!$-c +-c-hGrrr`!*!&$`$-N!AGr`$`!*!&$`!-c-c-cGh`!2!!N!82!-b3"Gh`!2!!N!A +rN!N!m,Z`!!!2!-$-N!AFhI$rZl!!!!$rN!N!!,Z`!*!%89&9h-c-h`#3#!94899 +Gc-h`!*!)"99999h-h`#3#`rGhFh`!*!-rFcI!*!0$ph`!*!1r`#31J%!N"Mr!*! +1r`$r!*!-r`#`!2m!N!Vr!*!%r`8!N!IrN!X!N!Er!#Z3"IRr!*!(r`!VN!Ajrj! +%!*!%r`!VN!Ajr`!!r`#3"2m!+j!&qIm!!&jH!!$rN!X!APi!N!5`X,!V+rRr!*! +*X,#`+rRr!*!-rrRr!*!1r`#3'i!!N!X2!*!(m2!!N!82"3m!N!A`!!m3!!!!rj! +&m!!!$`c-c0m!!!!2$-c-hrr`!!m-c-cI!2!!$`c-c0m!Z`$rN!A`Z`!!99c0m!# +3"&9Fh`#3"[h`!*!'$`#3$`G849K8!!%!N!3"!*!%"bU3"!!#!*!%,&"jG$%!!!! +"4P*&4J!#!!!!J!!"!)%!!J##5801)`!#!!!",!!"!!!!!J#3"4"849K8G(4iG!# +S-$%i-3#3"!%!!!!+8!!!#9!!!!%K"Hr&G#kN!!!!(!%5!!T#6N4-!!!!@NP$6L- +!!!"Q8dPD43!!!(*'8N9'!!)!IQPMFb-!!!#LD@0X1!!!!+jTBf`d!!!!ZQPMFcJ +!!!$'D@0c0!!!!0*3HA3a!!!!hNG9YdN!!!$U!)$rr`!!#3`!N!3",2rr!*!)rj! +%!!!""!A[aI3!J2rr!!!"%J#3"B(rr`!!#2%!N!@#rrm!!!N"!*!%!5crr`!!!4d +!N!3",2rr!!!"B3#3"!%Xrrm!!!9P!*!%!5crr`!!"fN!N!3",2rr!!!)E3#3#JM +m!*!%+!(rr`!!#6`!N!316hGZCA)JFQ9cEh9bBf8%j!: