Package turbogears :: Package command :: Module kid2genshi

Source Code for Module turbogears.command.kid2genshi

  1  """Command for converting Kid to Genshi templates. 
  2   
  3  Currently only converts the Kid namespace and simple py:extend directives. 
  4   
  5  """ 
  6   
  7  import optparse 
  8  import os 
  9  import re 
 10   
 11  from turbogears.util import get_package_name 
 12   
 13   
14 -class Kid2Genshi(object):
15 """Convert Kid to Genshi templates.""" 16 17 desc = "Convert all Kid templates in the project to Genshi" 18 19 engines = ('Kid', 'Genshi') 20 extensions = ('.kid', '.html') 21 xmlns = ('http://purl.org/kid/ns#', 'http://genshi.edgewall.org/') 22 23 need_project = True 24
25 - def __init__(self, version):
26 parser = optparse.OptionParser( 27 usage="%prog [options]", 28 version="%prog " + version) 29 parser.add_option("-f", "--force", 30 help="overwrite existing templates", 31 action='store_true', dest="force") 32 parser.add_option("-k", "--keep", 33 help="keep the original templates", 34 action='store_true', dest="keep") 35 parser.add_option("-r", "--reverse", 36 help="convert Genshi to Kid", 37 action='store_true', dest="reverse") 38 self.parser = parser
39
40 - def convert_template(self, filename, force=False, keep=False):
41 extensions = self.extensions 42 from_index, to_index = self.from_index, self.to_index 43 if not force and os.path.exists(filename + extensions[to_index]): 44 return 45 f = open(filename + extensions[from_index], 'rb') 46 try: 47 try: 48 old = f.read() 49 finally: 50 f.close() 51 except IOError: 52 print "Could not open", filename 53 return False 54 new = old 55 for n, r in enumerate(self.re_convert): 56 new = r[0].sub(r[1], new, 1) 57 if not n and new == old: 58 return 59 print "Converting", filename, "..." 60 f = open(filename + extensions[to_index], 'wb') 61 try: 62 f.write(new) 63 finally: 64 f.close() 65 if not keep: 66 os.unlink(filename + extensions[from_index]) 67 if self.engines[from_index] == 'Kid': 68 try: 69 os.unlink(filename + '.pyc') 70 except OSError: 71 pass 72 try: 73 os.unlink(filename + '.pyo') 74 except OSError: 75 pass 76 return True
77
78 - def change_config(self, filename):
79 f = open(filename, 'rb') 80 try: 81 try: 82 old = f.read() 83 finally: 84 f.close() 85 except IOError: 86 print "Could not open", filename 87 return False 88 new_defaultview = r'\1%s\2' % self.engines[self.to_index].lower() 89 new = self.re_defaultview.sub(new_defaultview, old, 1) 90 if new == old: 91 return 92 print "Changing", filename, "..." 93 f = open(filename, 'wb') 94 try: 95 f.write(new) 96 finally: 97 f.close() 98 return True
99
100 - def run(self):
101 options, args = self.parser.parse_args() 102 force, keep, reverse = options.force, options.keep, options.reverse 103 from_index, to_index = 0, 1 104 if reverse: 105 from_index, to_index = to_index, from_index 106 self.from_index, self.to_index = from_index, to_index 107 engines, extensions, xmlns = self.engines, self.extensions, self.xmlns 108 package_name = get_package_name() 109 convert = [(r'<([a-z]+)\b([^<]*\bxmlns:py\s*=\s*[\'"])' 110 r'%s([\'"][^<]*>.*</\1)>' % xmlns[from_index], 111 r"<\1\2%s\3>" % self.xmlns[to_index])] 112 if reverse: 113 convert.append((r'<([a-z]+)\b([^<]*)\b' 114 r'xmlns:xi(\s*=\s*")http://www.w3.org/2001/XInclude' 115 r'("[^<]*>)\s*<xi:include\s+href=[\'"]' 116 r'([^\'"]*)\.html[\'"]/>(.*</\1)>', 117 r"<\1\2py:extends\3'\5.kid'\4\6>")) 118 else: 119 convert.append((r'<([a-z]+)\b([^<]*)\b' 120 r'py:extends(\s*=\s*")\'([^\'"]*)\.kid\'("[^<]*>)(.*</\1)>', 121 r'<\1\2xmlns:xi\3http://www.w3.org/2001/XInclude\5' 122 r'<xi:include href="\4.html"/>\6>')) 123 # we could append more conversion rules here 124 self.re_convert = [(re.compile(r[0], re.S), r[1]) for r in convert] 125 self.re_defaultview = re.compile( 126 r'^(\s*tg.defaultview\s*=\s*[\'"])(?:%s)([\'"]\s*(?:#.*)?)$' 127 % engines[from_index].lower(), re.M) 128 print "Converting all %s to %s templates in package %s" % ( 129 engines[from_index], engines[to_index], package_name) 130 print "(the %s templates will be %s) ..." % (engines[from_index], 131 keep and 'kept' or 'removed') 132 n = 0 133 for dirpath, dirnames, filenames in os.walk(package_name): 134 i = 0 135 while i < len(dirnames): 136 dirname = dirnames[i] 137 if dirname.startswith('.') or dirname.endswith('~'): 138 del dirnames[i] 139 else: 140 i += 1 141 for filename in filenames: 142 if filename.endswith('~'): 143 continue 144 name, ext = os.path.splitext(filename) 145 if ext == extensions[from_index]: 146 filename = os.path.join(dirpath, name) 147 if self.convert_template(filename, force, keep): 148 n += 1 149 if n: 150 if n > 1: 151 print "%d %s templates have been converted to %s." % ( 152 n, engines[from_index], engines[to_index]) 153 print "Changing the configuration of package %s ..." % package_name 154 if not self.change_config( 155 os.path.join(package_name, 'config', 'app.cfg')): 156 print "Application config with defaultview setting not found." 157 elif force: 158 print "No %s templates were found in the current project." % ( 159 engines[from_index]) 160 else: 161 print "No %s templates needed to be converted in this project." % ( 162 engines[from_index])
163