PageRenderTime 55ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/web2py/scripts/contentparser.py

https://gitlab.com/sunkistm/gitlab-web2py
Python | 132 lines | 113 code | 7 blank | 12 comment | 6 complexity | cd824a93d42c1562c6f69e10805affd2 MD5 | raw file
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import cStringIO
  4. import re
  5. import sys
  6. import tarfile
  7. import urllib
  8. import xml.parsers.expat as expat
  9. """
  10. Update script for contenttype.py module.
  11. Usage: python contentupdate.py /path/to/contenttype.py
  12. If no path is specified, script will look for contenttype.py in current
  13. working directory.
  14. Internet connection is required to perform the update.
  15. """
  16. OVERRIDE = [
  17. ('.pdb', 'chemical/x-pdb'),
  18. ('.xyz', 'chemical/x-pdb')
  19. ]
  20. class MIMEParser(dict):
  21. def __start_element_handler(self, name, attrs):
  22. if name == 'mime-type':
  23. if self.type:
  24. for extension in self.extensions:
  25. self[extension] = self.type
  26. self.type = attrs['type'].lower()
  27. self.extensions = []
  28. elif name == 'glob':
  29. pattern = attrs['pattern']
  30. if pattern.startswith('*.'):
  31. self.extensions.append(pattern[1:].lower())
  32. def __init__(self, fileobj):
  33. dict.__init__(self)
  34. self.type = ''
  35. self.extensions = ''
  36. parser = expat.ParserCreate()
  37. parser.StartElementHandler = self.__start_element_handler
  38. parser.ParseFile(fileobj)
  39. for extension, contenttype in OVERRIDE:
  40. self[extension] = contenttype
  41. if __name__ == '__main__':
  42. try:
  43. path = sys.argv[1]
  44. except:
  45. path = 'contenttype.py'
  46. vregex = re.compile('database version (?P<version>.+?)\.?\n')
  47. sys.stdout.write('Checking contenttype.py database version:')
  48. sys.stdout.flush()
  49. try:
  50. pathfile = open(path)
  51. try:
  52. current = pathfile.read()
  53. finally:
  54. pathfile.close()
  55. cversion = re.search(vregex, current).group('version')
  56. sys.stdout.write('\t[OK] version %s\n' % cversion)
  57. except Exception, e:
  58. sys.stdout.write('\t[ERROR] %s\n' % e)
  59. exit()
  60. sys.stdout.write('Checking freedesktop.org database version:')
  61. sys.stdout.flush()
  62. try:
  63. search = re.search(
  64. '(?P<url>http://freedesktop.org/.+?/shared-mime-info-(?P<version>.+?)\.tar\.(?P<type>[gb]z2?))',
  65. urllib.urlopen('http://www.freedesktop.org/wiki/Software/shared-mime-info').read())
  66. url = search.group('url')
  67. assert url is not None
  68. nversion = search.group('version')
  69. assert nversion is not None
  70. ftype = search.group('type')
  71. assert ftype is not None
  72. sys.stdout.write('\t[OK] version %s\n' % nversion)
  73. except:
  74. sys.stdout.write('\t[ERROR] unknown version\n')
  75. exit()
  76. if cversion == nversion:
  77. sys.stdout.write('\nContenttype.py database is up to date\n')
  78. exit()
  79. try:
  80. raw_input('\nContenttype.py database updates are available from:\n%s (approx. 0.5MB)\nPress enter to continue or CTRL-C to quit now\nWARNING: this will replace contenttype.py file content IN PLACE' % url)
  81. except:
  82. exit()
  83. sys.stdout.write('\nDownloading new database:')
  84. sys.stdout.flush()
  85. fregex = re.compile('^.*/freedesktop\.org\.xml$')
  86. try:
  87. io = cStringIO.StringIO()
  88. io.write(urllib.urlopen(url).read())
  89. sys.stdout.write('\t[OK] done\n')
  90. except Exception, e:
  91. sys.stdout.write('\t[ERROR] %s\n' % e)
  92. exit()
  93. sys.stdout.write('Installing new database:')
  94. sys.stdout.flush()
  95. try:
  96. tar = tarfile.TarFile.open(fileobj=io, mode='r:%s' % ftype)
  97. try:
  98. for content in tar.getnames():
  99. if fregex.match(content):
  100. xml = tar.extractfile(content)
  101. break
  102. finally:
  103. tar.close()
  104. data = MIMEParser(xml)
  105. io = cStringIO.StringIO()
  106. io.write('CONTENT_TYPE = {\n')
  107. for key in sorted(data):
  108. io.write(' \'%s\': \'%s\',\n' % (key, data[key]))
  109. io.write(' }')
  110. io.seek(0)
  111. contenttype = open('contenttype.py', 'w')
  112. try:
  113. contenttype.write(re.sub(vregex, 'database version %s.\n' % nversion, re.sub('CONTENT_TYPE = \{(.|\n)+?\}', io.getvalue(), current)))
  114. finally:
  115. contenttype.close()
  116. if not current.closed:
  117. current.close()
  118. sys.stdout.write('\t\t\t[OK] done\n')
  119. except Exception, e:
  120. sys.stdout.write('\t\t\t[ERROR] %s\n' % e)