/Lib/plat-mac/macresource.py

http://unladen-swallow.googlecode.com/ · Python · 149 lines · 101 code · 15 blank · 33 comment · 44 complexity · 0c4c21dbab1a59f5ac5af67960466a05 MD5 · raw file

  1. """macresource - Locate and open the resources needed for a script."""
  2. from warnings import warnpy3k
  3. warnpy3k("In 3.x, the macresource module is removed.", stacklevel=2)
  4. from Carbon import Res
  5. import os
  6. import sys
  7. import MacOS
  8. import macostools
  9. class ArgumentError(TypeError): pass
  10. class ResourceFileNotFoundError(ImportError): pass
  11. def need(restype, resid, filename=None, modname=None):
  12. """Open a resource file, if needed. restype and resid
  13. are required parameters, and identify the resource for which to test. If it
  14. is available we are done. If it is not available we look for a file filename
  15. (default: modname with .rsrc appended) either in the same folder as
  16. where modname was loaded from, or otherwise across sys.path.
  17. Returns the refno of the resource file opened (or None)"""
  18. if modname is None and filename is None:
  19. raise ArgumentError, "Either filename or modname argument (or both) must be given"
  20. if type(resid) is type(1):
  21. try:
  22. h = Res.GetResource(restype, resid)
  23. except Res.Error:
  24. pass
  25. else:
  26. return None
  27. else:
  28. try:
  29. h = Res.GetNamedResource(restype, resid)
  30. except Res.Error:
  31. pass
  32. else:
  33. return None
  34. # Construct a filename if we don't have one
  35. if not filename:
  36. if '.' in modname:
  37. filename = modname.split('.')[-1] + '.rsrc'
  38. else:
  39. filename = modname + '.rsrc'
  40. # Now create a list of folders to search
  41. searchdirs = []
  42. if modname == '__main__':
  43. # If we're main we look in the current directory
  44. searchdirs = [os.curdir]
  45. if sys.modules.has_key(modname):
  46. mod = sys.modules[modname]
  47. if hasattr(mod, '__file__'):
  48. searchdirs = [os.path.dirname(mod.__file__)]
  49. searchdirs.extend(sys.path)
  50. # And look for the file
  51. for dir in searchdirs:
  52. pathname = os.path.join(dir, filename)
  53. if os.path.exists(pathname):
  54. break
  55. else:
  56. raise ResourceFileNotFoundError, filename
  57. refno = open_pathname(pathname)
  58. # And check that the resource exists now
  59. if type(resid) is type(1):
  60. h = Res.GetResource(restype, resid)
  61. else:
  62. h = Res.GetNamedResource(restype, resid)
  63. return refno
  64. def open_pathname(pathname, verbose=0):
  65. """Open a resource file given by pathname, possibly decoding an
  66. AppleSingle file"""
  67. try:
  68. refno = Res.FSpOpenResFile(pathname, 1)
  69. except (AttributeError, Res.Error), arg:
  70. if isinstance(arg, AttributeError) or arg[0] in (-37, -39):
  71. # No resource fork. We may be on OSX, and this may be either
  72. # a data-fork based resource file or a AppleSingle file
  73. # from the CVS repository.
  74. try:
  75. refno = Res.FSOpenResourceFile(pathname, u'', 1)
  76. except Res.Error, arg:
  77. if arg[0] != -199:
  78. # -199 is "bad resource map"
  79. raise
  80. else:
  81. return refno
  82. # Finally try decoding an AppleSingle file
  83. pathname = _decode(pathname, verbose=verbose)
  84. refno = Res.FSOpenResourceFile(pathname, u'', 1)
  85. else:
  86. raise
  87. return refno
  88. def resource_pathname(pathname, verbose=0):
  89. """Return the pathname for a resource file (either DF or RF based).
  90. If the pathname given already refers to such a file simply return it,
  91. otherwise first decode it."""
  92. try:
  93. refno = Res.FSpOpenResFile(pathname, 1)
  94. Res.CloseResFile(refno)
  95. except (AttributeError, Res.Error), arg:
  96. if isinstance(arg, AttributeError) or arg[0] in (-37, -39):
  97. # No resource fork. We may be on OSX, and this may be either
  98. # a data-fork based resource file or a AppleSingle file
  99. # from the CVS repository.
  100. try:
  101. refno = Res.FSOpenResourceFile(pathname, u'', 1)
  102. except Res.Error, arg:
  103. if arg[0] != -199:
  104. # -199 is "bad resource map"
  105. raise
  106. else:
  107. return refno
  108. # Finally try decoding an AppleSingle file
  109. pathname = _decode(pathname, verbose=verbose)
  110. else:
  111. raise
  112. return pathname
  113. def open_error_resource():
  114. """Open the resource file containing the error code to error message
  115. mapping."""
  116. need('Estr', 1, filename="errors.rsrc", modname=__name__)
  117. def _decode(pathname, verbose=0):
  118. # Decode an AppleSingle resource file, return the new pathname.
  119. newpathname = pathname + '.df.rsrc'
  120. if os.path.exists(newpathname) and \
  121. os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime:
  122. return newpathname
  123. if hasattr(os, 'access') and not \
  124. os.access(os.path.dirname(pathname), os.W_OK|os.X_OK):
  125. # The destination directory isn't writeable. Create the file in
  126. # a temporary directory
  127. import tempfile
  128. fd, newpathname = tempfile.mkstemp(".rsrc")
  129. if verbose:
  130. print 'Decoding', pathname, 'to', newpathname
  131. import applesingle
  132. applesingle.decode(pathname, newpathname, resonly=1)
  133. return newpathname