1 """macostools - Various utility functions for MacOS.
3 mkalias(src, dst) - Create a finder alias 'dst' pointing to 'src'
4 copy(src, dst) - Full copy of 'src' to 'dst'
8 from Carbon
import File
, Files
15 except AttributeError:
16 # Backward compatability
19 Error
= 'macostools.Error'
21 BUFSIZ
=0x80000 # Copy in 0.5Mb chunks
23 COPY_FLAGS
= (Files
.kIsStationary|Files
.kNameLocked|Files
.kHasBundle|
24 Files
.kIsInvisible|Files
.kIsAlias
)
27 # Not guaranteed to be correct or stay correct (Apple doesn't tell you
28 # how to do this), but it seems to work.
30 def mkalias(src
, dst
, relative
=None):
31 """Create a finder alias"""
32 srcfsr
= File
.FSRef(src
)
33 # The next line will fail under unix-Python if the destination
34 # doesn't exist yet. We should change this code to be fsref-based.
35 dstdir
, dstname
= os
.path
.split(dst
)
36 if not dstdir
: dstdir
= os
.curdir
37 dstdirfsr
= File
.FSRef(dstdir
)
39 relativefsr
= File
.FSRef(relative
)
40 # ik mag er geen None in stoppen :-(
41 alias
= File
.FSNewAlias(relativefsr
, srcfsr
)
43 alias
= srcfsr
.FSNewAliasMinimal()
45 dstfsr
, dstfss
= Res
.FSCreateResourceFile(dstdirfsr
, unicode(dstname
),
46 File
.FSGetResourceForkName())
47 h
= Res
.FSOpenResourceFile(dstfsr
, File
.FSGetResourceForkName(), 3)
48 resource
= Res
.Resource(alias
.data
)
49 resource
.AddResource('alis', 0, '')
52 dstfinfo
= dstfss
.FSpGetFInfo()
53 dstfinfo
.Flags
= dstfinfo
.Flags|
0x8000 # Alias flag
54 dstfss
.FSpSetFInfo(dstfinfo
)
57 """Make directories leading to 'dst' if they don't exist yet"""
58 if dst
== '' or os
.path
.exists(dst
):
60 head
, tail
= os
.path
.split(dst
)
61 if os
.sep
== ':' and not ':' in head
:
67 """Tell the finder a file has changed. No-op on MacOSX."""
68 if sys
.platform
!= 'mac': return
70 warnings
.filterwarnings("ignore", "macfs.*", DeprecationWarning, __name__
)
72 file_fss
= macfs
.FSSpec(dst
)
73 vRefNum
, dirID
, name
= file_fss
.as_tuple()
74 dir_fss
= macfs
.FSSpec((vRefNum
, dirID
, ''))
75 crdate
, moddate
, bkdate
= dir_fss
.GetDates()
80 dir_fss
.SetDates(crdate
, now
, bkdate
)
85 """Tell the finder a file has changed"""
86 pardir
= os
.path
.split(dst
)[0]
91 f
.update(File
.FSRef(pardir
))
93 def copy(src
, dst
, createpath
=0, copydates
=1, forcetype
=None):
94 """Copy a file, including finder info, resource fork, etc"""
95 src
= File
.pathname(src
)
96 dst
= File
.pathname(dst
)
98 mkdirs(os
.path
.split(dst
)[0])
100 ifp
= open(src
, 'rb')
101 ofp
= open(dst
, 'wb')
109 ifp
= openrf(src
, '*rb')
110 ofp
= openrf(dst
, '*wb')
118 srcfss
= File
.FSSpec(src
)
119 dstfss
= File
.FSSpec(dst
)
120 sf
= srcfss
.FSpGetFInfo()
121 df
= dstfss
.FSpGetFInfo()
122 df
.Creator
, df
.Type
= sf
.Creator
, sf
.Type
123 if forcetype
!= None:
125 df
.Flags
= (sf
.Flags
& COPY_FLAGS
)
126 dstfss
.FSpSetFInfo(df
)
128 srcfsr
= File
.FSRef(src
)
129 dstfsr
= File
.FSRef(dst
)
130 catinfo
, _
, _
, _
= srcfsr
.FSGetCatalogInfo(Files
.kFSCatInfoAllDates
)
131 dstfsr
.FSSetCatalogInfo(Files
.kFSCatInfoAllDates
, catinfo
)
134 def copytree(src
, dst
, copydates
=1):
135 """Copy a complete file tree to a new destination"""
136 if os
.path
.isdir(src
):
138 files
= os
.listdir(src
)
140 copytree(os
.path
.join(src
, f
), os
.path
.join(dst
, f
), copydates
)
142 copy(src
, dst
, 1, copydates
)