/Lib/plat-mac/macostools.py

http://unladen-swallow.googlecode.com/ · Python · 137 lines · 126 code · 3 blank · 8 comment · 3 complexity · e86ca529817f476dd387f5935c8b3ed3 MD5 · raw file

  1. """macostools - Various utility functions for MacOS.
  2. mkalias(src, dst) - Create a finder alias 'dst' pointing to 'src'
  3. copy(src, dst) - Full copy of 'src' to 'dst'
  4. """
  5. from warnings import warnpy3k
  6. warnpy3k("In 3.x, the macostools module is removed.", stacklevel=2)
  7. from Carbon import Res
  8. from Carbon import File, Files
  9. import os
  10. import MacOS
  11. try:
  12. openrf = MacOS.openrf
  13. except AttributeError:
  14. # Backward compatibility
  15. openrf = open
  16. Error = 'macostools.Error'
  17. BUFSIZ=0x80000 # Copy in 0.5Mb chunks
  18. COPY_FLAGS = (Files.kIsStationary|Files.kNameLocked|Files.kHasBundle|
  19. Files.kIsInvisible|Files.kIsAlias)
  20. #
  21. # Not guaranteed to be correct or stay correct (Apple doesn't tell you
  22. # how to do this), but it seems to work.
  23. #
  24. def mkalias(src, dst, relative=None):
  25. """Create a finder alias"""
  26. srcfsr = File.FSRef(src)
  27. # The next line will fail under unix-Python if the destination
  28. # doesn't exist yet. We should change this code to be fsref-based.
  29. dstdir, dstname = os.path.split(dst)
  30. if not dstdir: dstdir = os.curdir
  31. dstdirfsr = File.FSRef(dstdir)
  32. if relative:
  33. relativefsr = File.FSRef(relative)
  34. # ik mag er geen None in stoppen :-(
  35. alias = File.FSNewAlias(relativefsr, srcfsr)
  36. else:
  37. alias = srcfsr.FSNewAliasMinimal()
  38. dstfsr, dstfss = Res.FSCreateResourceFile(dstdirfsr, unicode(dstname),
  39. File.FSGetResourceForkName())
  40. h = Res.FSOpenResourceFile(dstfsr, File.FSGetResourceForkName(), 3)
  41. resource = Res.Resource(alias.data)
  42. resource.AddResource('alis', 0, '')
  43. Res.CloseResFile(h)
  44. dstfinfo = dstfss.FSpGetFInfo()
  45. dstfinfo.Flags = dstfinfo.Flags|0x8000 # Alias flag
  46. dstfss.FSpSetFInfo(dstfinfo)
  47. def mkdirs(dst):
  48. """Make directories leading to 'dst' if they don't exist yet"""
  49. if dst == '' or os.path.exists(dst):
  50. return
  51. head, tail = os.path.split(dst)
  52. if os.sep == ':' and not ':' in head:
  53. head = head + ':'
  54. mkdirs(head)
  55. try:
  56. os.mkdir(dst, 0777)
  57. except OSError, e:
  58. # be happy if someone already created the path
  59. if e.errno != errno.EEXIST:
  60. raise
  61. def touched(dst):
  62. """Tell the finder a file has changed. No-op on MacOSX."""
  63. import warnings
  64. warnings.warn("macostools.touched() has been deprecated",
  65. DeprecationWarning, 2)
  66. def touched_ae(dst):
  67. """Tell the finder a file has changed"""
  68. pardir = os.path.split(dst)[0]
  69. if not pardir:
  70. pardir = os.curdir
  71. import Finder
  72. f = Finder.Finder()
  73. f.update(File.FSRef(pardir))
  74. def copy(src, dst, createpath=0, copydates=1, forcetype=None):
  75. """Copy a file, including finder info, resource fork, etc"""
  76. src = File.pathname(src)
  77. dst = File.pathname(dst)
  78. if createpath:
  79. mkdirs(os.path.split(dst)[0])
  80. ifp = open(src, 'rb')
  81. ofp = open(dst, 'wb')
  82. d = ifp.read(BUFSIZ)
  83. while d:
  84. ofp.write(d)
  85. d = ifp.read(BUFSIZ)
  86. ifp.close()
  87. ofp.close()
  88. ifp = openrf(src, '*rb')
  89. ofp = openrf(dst, '*wb')
  90. d = ifp.read(BUFSIZ)
  91. while d:
  92. ofp.write(d)
  93. d = ifp.read(BUFSIZ)
  94. ifp.close()
  95. ofp.close()
  96. srcfss = File.FSSpec(src)
  97. dstfss = File.FSSpec(dst)
  98. sf = srcfss.FSpGetFInfo()
  99. df = dstfss.FSpGetFInfo()
  100. df.Creator, df.Type = sf.Creator, sf.Type
  101. if forcetype is not None:
  102. df.Type = forcetype
  103. df.Flags = (sf.Flags & COPY_FLAGS)
  104. dstfss.FSpSetFInfo(df)
  105. if copydates:
  106. srcfsr = File.FSRef(src)
  107. dstfsr = File.FSRef(dst)
  108. catinfo, _, _, _ = srcfsr.FSGetCatalogInfo(Files.kFSCatInfoAllDates)
  109. dstfsr.FSSetCatalogInfo(Files.kFSCatInfoAllDates, catinfo)
  110. def copytree(src, dst, copydates=1):
  111. """Copy a complete file tree to a new destination"""
  112. if os.path.isdir(src):
  113. mkdirs(dst)
  114. files = os.listdir(src)
  115. for f in files:
  116. copytree(os.path.join(src, f), os.path.join(dst, f), copydates)
  117. else:
  118. copy(src, dst, 1, copydates)