Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 1 | """macfs - Pure Python module designed to be backward compatible with |
| 2 | macfs and MACFS. |
| 3 | """ |
| 4 | import sys |
Jack Jansen | 6dd561b | 2002-12-26 21:09:39 +0000 | [diff] [blame] | 5 | import struct |
| 6 | import Carbon.Res |
| 7 | import Carbon.File |
| 8 | import Nav |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 9 | |
| 10 | # First step: ensure we also emulate the MACFS module, which contained |
| 11 | # all the constants |
| 12 | |
| 13 | sys.modules['MACFS'] = sys.modules[__name__] |
| 14 | |
| 15 | # Import all those constants |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 16 | from Carbon.Files import * |
| 17 | from Carbon.Folders import * |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 18 | |
| 19 | # For some obscure historical reason these are here too: |
| 20 | READ = 1 |
| 21 | WRITE = 2 |
| 22 | smAllScripts = -3 |
| 23 | |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 24 | # The old name of the error object: |
| 25 | error = Carbon.File.Error |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 26 | |
Jack Jansen | 6dd561b | 2002-12-26 21:09:39 +0000 | [diff] [blame] | 27 | # |
| 28 | # The various objects macfs used to export. We override them here, because some |
| 29 | # of the method names are subtly different. |
| 30 | # |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 31 | class FSSpec(Carbon.File.FSSpec): |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 32 | def as_fsref(self): |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 33 | return FSRef(self) |
| 34 | |
| 35 | def NewAlias(self, src=None): |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 36 | return Alias(Carbon.File.NewAlias(src, self)) |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 37 | |
| 38 | def GetCreatorType(self): |
| 39 | finfo = self.FSpGetFInfo() |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 40 | return finfo.Creator, finfo.Type |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 41 | |
| 42 | def SetCreatorType(self, ctor, tp): |
| 43 | finfo = self.FSpGetFInfo() |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 44 | finfo.Creator = ctor |
| 45 | finfo.Type = tp |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 46 | self.FSpSetFInfo(finfo) |
| 47 | |
| 48 | def GetFInfo(self): |
| 49 | return self.FSpGetFInfo() |
| 50 | |
| 51 | def SetFInfo(self, info): |
| 52 | return self.FSpSetFInfo(info) |
| 53 | |
| 54 | def GetDates(self): |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 55 | import os |
| 56 | statb = os.stat(self.as_pathname()) |
| 57 | return statb.st_ctime, statb.st_mtime, 0 |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 58 | |
| 59 | def SetDates(self, *dates): |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 60 | print "FSSpec.SetDates no longer implemented" |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 61 | |
| 62 | class FSRef(Carbon.File.FSRef): |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 63 | def as_fsspec(self): |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 64 | return FSSpec(self) |
| 65 | |
| 66 | class Alias(Carbon.File.Alias): |
| 67 | |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 68 | def GetInfo(self, index): |
| 69 | return self.GetAliasInfo(index) |
| 70 | |
| 71 | def Update(self, *args): |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 72 | print "Alias.Update not yet implemented" |
| 73 | |
| 74 | def Resolve(self, src=None): |
Jack Jansen | 315e9be | 2002-12-26 20:46:54 +0000 | [diff] [blame] | 75 | fss, changed = self.ResolveAlias(src) |
| 76 | return FSSpec(fss), changed |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 77 | |
| 78 | from Carbon.File import FInfo |
Jack Jansen | 6dd561b | 2002-12-26 21:09:39 +0000 | [diff] [blame] | 79 | |
| 80 | # Backward-compatible type names: |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 81 | FSSpecType = FSSpec |
| 82 | FSRefType = FSRef |
| 83 | AliasType = Alias |
| 84 | FInfoType = FInfo |
| 85 | |
Jack Jansen | 6dd561b | 2002-12-26 21:09:39 +0000 | [diff] [blame] | 86 | # Global functions: |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 87 | def ResolveAliasFile(fss, chain=1): |
Jack Jansen | 315e9be | 2002-12-26 20:46:54 +0000 | [diff] [blame] | 88 | fss, isdir, isalias = Carbon.File.ResolveAliasFile(fss, chain) |
| 89 | return FSSpec(fss), isdir, isalias |
Jack Jansen | 58fc91f | 2002-12-17 23:28:24 +0000 | [diff] [blame] | 90 | |
| 91 | def RawFSSpec(data): |
| 92 | return FSSpec(rawdata=data) |
| 93 | |
| 94 | def RawAlias(data): |
| 95 | return Alias(rawdata=data) |
| 96 | |
| 97 | def FindApplication(*args): |
| 98 | raise NotImplementedError, "FindApplication no longer implemented" |
| 99 | |
| 100 | def NewAliasMinimalFromFullPath(path): |
Jack Jansen | 315e9be | 2002-12-26 20:46:54 +0000 | [diff] [blame] | 101 | return Alias(Carbon.File.NewAliasMinimalFromFullPath(path, '', '')) |
Jack Jansen | 4235e71 | 2002-12-19 23:26:07 +0000 | [diff] [blame] | 102 | |
Jack Jansen | 6dd561b | 2002-12-26 21:09:39 +0000 | [diff] [blame] | 103 | # Another global function: |
| 104 | from Carbon.Folder import FindFolder |
| 105 | |
| 106 | # |
| 107 | # Finally the old Standard File routine emulators. |
| 108 | # |
| 109 | |
| 110 | _movablemodal = 0 |
| 111 | _curfolder = None |
| 112 | |
| 113 | def _mktypelist(typelist): |
| 114 | # Workaround for OSX typeless files: |
| 115 | if 'TEXT' in typelist and not '\0\0\0\0' in typelist: |
| 116 | typelist = typelist + ('\0\0\0\0',) |
| 117 | if not typelist: |
| 118 | return None |
| 119 | data = 'Pyth' + struct.pack("hh", 0, len(typelist)) |
| 120 | for type in typelist: |
| 121 | data = data+type |
| 122 | return Carbon.Res.Handle(data) |
| 123 | |
| 124 | def StandardGetFile(*typelist): |
| 125 | """Ask for an input file, optionally specifying 4-char file types that are |
| 126 | allowable""" |
| 127 | return apply(PromptGetFile, (None,)+typelist) |
| 128 | |
| 129 | def PromptGetFile(prompt, *typelist): |
| 130 | """Ask for an input file giving the user a prompt message. Optionally you can |
| 131 | specifying 4-char file types that are allowable""" |
| 132 | args = {} |
| 133 | flags = 0x56 |
| 134 | typehandle = _mktypelist(typelist) |
| 135 | if typehandle: |
| 136 | args['typeList'] = typehandle |
| 137 | else: |
| 138 | flags = flags | 0x01 |
| 139 | if prompt: |
| 140 | args['message'] = prompt |
| 141 | args['preferenceKey'] = 'PyMC' |
| 142 | if _movablemodal: |
| 143 | args['eventProc'] = None |
| 144 | args['dialogOptionFlags'] = flags |
| 145 | _handleSetFolder(args) |
| 146 | try: |
| 147 | rr = Nav.NavChooseFile(args) |
| 148 | good = 1 |
| 149 | except Nav.error, arg: |
| 150 | if arg[0] != -128: # userCancelledErr |
| 151 | raise Nav.error, arg |
| 152 | good = 0 |
| 153 | fss = None |
| 154 | else: |
| 155 | if rr.selection: |
| 156 | fss = FSSpec(rr.selection[0]) |
| 157 | else: |
| 158 | fss = None |
| 159 | good = 0 |
| 160 | ## if typehandle: |
| 161 | ## typehandle.DisposeHandle() |
| 162 | return fss, good |
| 163 | |
| 164 | def StandardPutFile(prompt, default=None): |
| 165 | """Ask the user for an output file, with a prompt. Optionally you cn supply a |
| 166 | default output filename""" |
| 167 | args = {} |
| 168 | flags = 0x07 |
| 169 | if prompt: |
| 170 | args['message'] = prompt |
| 171 | args['preferenceKey'] = 'PyMC' |
| 172 | if _movablemodal: |
| 173 | args['eventProc'] = None |
| 174 | if default: |
| 175 | args['savedFileName'] = default |
| 176 | args['dialogOptionFlags'] = flags |
| 177 | _handleSetFolder(args) |
| 178 | try: |
| 179 | rr = Nav.NavPutFile(args) |
| 180 | good = 1 |
| 181 | except Nav.error, arg: |
| 182 | if arg[0] != -128: # userCancelledErr |
| 183 | raise Nav.error, arg |
| 184 | good = 0 |
| 185 | fss = None |
| 186 | else: |
| 187 | fss = FSSpec(rr.selection[0]) |
| 188 | return fss, good |
| 189 | |
| 190 | def SetFolder(folder): |
| 191 | global _curfolder |
| 192 | if _curfolder: |
| 193 | rv = _curfolder |
| 194 | else: |
| 195 | rv = None |
| 196 | _curfolder = FSSpec(folder) |
| 197 | return rv |
| 198 | |
| 199 | def _handleSetFolder(args): |
| 200 | global _curfolder |
| 201 | if not _curfolder: |
| 202 | return |
| 203 | import aepack |
| 204 | fss = _curfolder |
| 205 | aedesc = aepack.pack(fss) |
| 206 | args['defaultLocation'] = aedesc |
| 207 | _curfolder = None |
| 208 | |
| 209 | def GetDirectory(prompt=None): |
| 210 | """Ask the user to select a folder. Optionally you can give a prompt.""" |
| 211 | args = {} |
| 212 | flags = 0x17 |
| 213 | if prompt: |
| 214 | args['message'] = prompt |
| 215 | args['preferenceKey'] = 'PyMC' |
| 216 | if _movablemodal: |
| 217 | args['eventProc'] = None |
| 218 | args['dialogOptionFlags'] = flags |
| 219 | _handleSetFolder(args) |
| 220 | try: |
| 221 | rr = Nav.NavChooseFolder(args) |
| 222 | good = 1 |
| 223 | except Nav.error, arg: |
| 224 | if arg[0] != -128: # userCancelledErr |
| 225 | raise Nav.error, arg |
| 226 | good = 0 |
| 227 | fss = None |
| 228 | else: |
| 229 | fss = FSSpec(rr.selection[0]) |
| 230 | return fss, good |
| 231 | |