odfmanifest.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # Copyright (C) 2006-2007 Søren Roug, European Environment Agency
  4. #
  5. # This library is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Lesser General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 2.1 of the License, or (at your option) any later version.
  9. #
  10. # This library is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public
  16. # License along with this library; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. #
  19. # Contributor(s):
  20. #
  21. from __future__ import print_function
  22. # This script lists the content of the manifest.xml file
  23. import zipfile
  24. from defusedxml.sax import make_parser
  25. from xml.sax import handler
  26. from xml.sax.xmlreader import InputSource
  27. import xml.sax.saxutils
  28. try:
  29. from cStringIO import StringIO
  30. except ImportError:
  31. from io import StringIO
  32. MANIFESTNS="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
  33. #-----------------------------------------------------------------------------
  34. #
  35. # ODFMANIFESTHANDLER
  36. #
  37. #-----------------------------------------------------------------------------
  38. class ODFManifestHandler(handler.ContentHandler):
  39. """ The ODFManifestHandler parses a manifest file and produces a list of
  40. content """
  41. def __init__(self):
  42. self.manifest = {}
  43. # Tags
  44. # FIXME: Also handle encryption data
  45. self.elements = {
  46. (MANIFESTNS, 'file-entry'): (self.s_file_entry, self.donothing),
  47. }
  48. def handle_starttag(self, tag, method, attrs):
  49. method(tag,attrs)
  50. def handle_endtag(self, tag, method):
  51. method(tag)
  52. def startElementNS(self, tag, qname, attrs):
  53. method = self.elements.get(tag, (None, None))[0]
  54. if method:
  55. self.handle_starttag(tag, method, attrs)
  56. else:
  57. self.unknown_starttag(tag,attrs)
  58. def endElementNS(self, tag, qname):
  59. method = self.elements.get(tag, (None, None))[1]
  60. if method:
  61. self.handle_endtag(tag, method)
  62. else:
  63. self.unknown_endtag(tag)
  64. def unknown_starttag(self, tag, attrs):
  65. pass
  66. def unknown_endtag(self, tag):
  67. pass
  68. def donothing(self, tag, attrs=None):
  69. pass
  70. def s_file_entry(self, tag, attrs):
  71. m = attrs.get((MANIFESTNS, 'media-type'),"application/octet-stream")
  72. p = attrs.get((MANIFESTNS, 'full-path'))
  73. self.manifest[p] = { 'media-type':m, 'full-path':p }
  74. #-----------------------------------------------------------------------------
  75. #
  76. # Reading the file
  77. #
  78. #-----------------------------------------------------------------------------
  79. def manifestlist(manifestxml):
  80. odhandler = ODFManifestHandler()
  81. parser = make_parser()
  82. parser.setFeature(handler.feature_namespaces, 1)
  83. parser.setContentHandler(odhandler)
  84. parser.setErrorHandler(handler.ErrorHandler())
  85. inpsrc = InputSource()
  86. if not isinstance(manifestxml, str):
  87. manifestxml=manifestxml.decode("utf-8")
  88. inpsrc.setByteStream(StringIO(manifestxml))
  89. parser.parse(inpsrc)
  90. return odhandler.manifest
  91. def odfmanifest(odtfile):
  92. z = zipfile.ZipFile(odtfile)
  93. manifest = z.read('META-INF/manifest.xml')
  94. z.close()
  95. return manifestlist(manifest)
  96. if __name__ == "__main__":
  97. import sys
  98. result = odfmanifest(sys.argv[1])
  99. for file in result.values():
  100. print ("%-40s %-40s" % (file['media-type'], file['full-path']))