{{{ # Programmer: limodou # E-mail: limodou@gmail.com # # Copyleft 2006 limodou # # Distributed under the terms of the GPL (GNU Public License) # # NewEdit is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Version 0.1 # This program is used to parse django's urlconf file. It can deal with standard # urls.py , e.g., it can parse prefix, pattern, method, and extra dictionary. # How to use it: # # from DjangoUrlConf import URLConf # #URLConf can receive a usrconf filename, or leave it empty # u = URLConf([urlsfile]) # #add common pattern # u.add(r'^test/$', 'newtest.test.main') # #add include pattern # u.add(r'^ajax/input/$', "include('newtest.test.ajax')") # #easyadd, it can automaticaly add '^' at the begin and '$' at the end # u.easyadd('tttt/input/', 'newtest.test.main') # #you can also pass it a dict variable # u.easyadd('tttt/input/', 'newtest.test.main', {'template': 'my_calendar/calendar'}) # #you can find a pattern # u.find(r'^ajax/input/$') # #or easyfind a pattern # u.easyfind('ajax/input/') # #find mapping method # u.has_method('newtest.test.ajax') # #save to a file, if the filename is omit, then use the filename which passwd to URLConf class # u.save([filename]) import sys class URLPatterns: def __init__(self): self.orders = [] self.prefix = '' self.nodes = {} def render(self): s = ['urlpatterns = patterns(%s\n' % self.prefix] for key in self.orders: if not self.nodes.has_key(key) : s.append(key) else: s.append(self.render_item(key)) s.append(")\n") return ''.join(s) def render_item(self, key): s = [] p, d = self.nodes[key] if not p.startswith('include('): p = repr(p) s.append(" (r%r, %s" % (key, p)) if d: if isinstance(d, dict): d = repr(d) s.append(", %s),\n" % d) else: s.append("),\n") return ''.join(s) def parse(self, text): text = text.replace('\r\n', '\n') text = text.replace('\r', '\n') i = 0 last = 0 flag = 0 #0 begin 1 comment 2 pattern while i -1: key = eval(t[:pos]) pos += 1 begin = pos pos = t.find(',', pos) if pos > -1: pattern = t[begin:pos].lstrip() dict = t[pos+1:].rstrip() else: pattern = t[begin:].strip() dict = None if key not in self.orders: self.orders.append(key) self.nodes[key] = (pattern, dict) while text[i] != '\n': i += 1 i += 1 last = i else: while i < len(text) and text[i] != '\n': i += 1 i += 1 self.orders.append(text[last:i]) last = i self.orders.pop(-1) def remove(self, key): if self.nodes.has_key(key): s = self.render_item(key) del self.nodes[key] pos = self.orders.index(key) self.orders[pos] = '#' + s def find(self, pattern): return self.nodes.get(pattern, None) def add(self, pattern, method, dict=None): if pattern not in self.orders: self.orders.append(pattern) self.nodes[pattern] = (method, dict) def has_method(self, method): for key, v in self.nodes(): p, d = v if p == method: return key return None class URLConf: def __init__(self, urlconf_filename=''): self.nodes = [] self.urlconf = URLPatterns() self.filename = urlconf_filename self.read(self.filename) def out(self): self.save(sys.stdout) def save(self, filename=None): if not filename: filename = self.filename if isinstance(filename, (str, unicode)): f = file(filename, 'w') else: f = filename text = [] for node in self.nodes: if isinstance(node, URLPatterns): text.append(node.render()) else: if isinstance(node, (list, tuple)): text.append(''.join(node)) else: text.append(node) s = ''.join(text) if s.find('from django.conf.urls.defaults import *') == -1: s = 'from django.conf.urls.defaults import *\n\n' + s f.write(s) def find(self, pattern): return self.urlconf.find(pattern, None) def easyfind(self, pattern): pattern = '^%s$' % pattern return self.find(pattern, None) def add(self, pattern, method, dict=None): self.urlconf.add(pattern, method, dict) def easyadd(self, pattern, method, dict=None): pattern = '^%s$' % pattern self.add(pattern, method, dict) def has_method(self, method): return self.urlconf.has_method(method) def read(self, filename): if not filename: self.nodes.append(self.urlconf) return f = file(filename) for line in f: if not line.startswith('urlpatterns'): self.nodes.append(line) else: begin = line.rfind('(') end = line.rfind(',') self.urlconf.prefix = line[begin+1:end] t = f.next() s = [] while t.strip() != ')': s.append(t) t = f.next() self.urlconf.parse(''.join(s+[')'])) self.nodes.append(self.urlconf) if __name__ == '__main__': # u = URLConf('urls.py') u = URLConf() # print u.find('^ajax/input/$') u.add('^test/$', 'newtest.test.main') u.add('^ajax/input/$', "include('newtest.test.ajax')") u.easyadd('tttt/input/', 'newtest.test.main') u.easyadd('tttt/input/', 'newtest.test.main', {'template': 'my_calendar/calendar'}) u.out() }}}