Changes between Initial Version and Version 1 of PythonScriptForParsingUrlConf


Ignore:
Timestamp:
Feb 5, 2006, 7:44:40 PM (18 years ago)
Author:
limodou@…
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PythonScriptForParsingUrlConf

    v1 v1  
     1{{{
     2#   Programmer: limodou
     3#   E-mail:     limodou@gmail.com
     4#
     5#   Copyleft 2006 limodou
     6#
     7#   Distributed under the terms of the GPL (GNU Public License)
     8#
     9#   NewEdit is free software; you can redistribute it and/or modify
     10#   it under the terms of the GNU General Public License as published by
     11#   the Free Software Foundation; either version 2 of the License, or
     12#   (at your option) any later version.
     13#
     14#   This program is distributed in the hope that it will be useful,
     15#   but WITHOUT ANY WARRANTY; without even the implied warranty of
     16#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17#   GNU General Public License for more details.
     18#
     19#   You should have received a copy of the GNU General Public License
     20#   along with this program; if not, write to the Free Software
     21#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     22#
     23#   Version 0.1
     24#   This program is used to parse django's urlconf file. It can deal with standard
     25#   urls.py , e.g., it can parse prefix, pattern, method, and extra dictionary.
     26#   How to use it:
     27#
     28#   from DjangoUrlConf import URLConf
     29#   #URLConf can receive a usrconf filename, or leave it empty
     30#   u = URLConf([urlsfile])
     31#   #add common pattern
     32#   u.add(r'^test/$', 'newtest.test.main')
     33#   #add include pattern
     34#   u.add(r'^ajax/input/$', "include('newtest.test.ajax')")
     35#   #easyadd, it can automaticaly add '^' at the begin and '$' at the end
     36#   u.easyadd('tttt/input/', 'newtest.test.main')
     37#   #you can also pass it a dict variable
     38#   u.easyadd('tttt/input/', 'newtest.test.main', {'template': 'my_calendar/calendar'})
     39#   #you can find a pattern
     40#   u.find(r'^ajax/input/$')
     41#   #or easyfind a pattern
     42#   u.easyfind('ajax/input/')
     43#   #find mapping method
     44#   u.has_method('newtest.test.ajax')
     45#   #save to a file, if the filename is omit, then use the filename which passwd to URLConf class
     46#   u.save([filename])
     47
     48import sys
     49
     50class URLPatterns:
     51    def __init__(self):
     52        self.orders = []
     53        self.prefix = ''
     54        self.nodes = {}
     55   
     56    def render(self):
     57        s = ['urlpatterns = patterns(%s\n' % self.prefix]
     58        for key in self.orders:
     59            if not self.nodes.has_key(key) :
     60                s.append(key)
     61            else:
     62                s.append(self.render_item(key))
     63        s.append(")\n")
     64        return ''.join(s)
     65   
     66    def render_item(self, key):
     67        s = []
     68        p, d = self.nodes[key]
     69        if not p.startswith('include('):
     70            p = repr(p)
     71        s.append("    (r%r, %s" % (key, p))
     72        if d:
     73            if isinstance(d, dict):
     74                d = repr(d)
     75            s.append(", %s),\n" % d)
     76        else:
     77            s.append("),\n")
     78        return ''.join(s)
     79   
     80    def parse(self, text):
     81        text = text.replace('\r\n', '\n')
     82        text = text.replace('\r', '\n')
     83       
     84        i = 0
     85        last = 0
     86        flag = 0 #0 begin 1 comment 2 pattern
     87        while i<len(text):
     88            #skip blank
     89            while text[i] in (' ', '\t'):
     90                i += 1
     91            if text[i] == '#':  #if comment:
     92                while text[i] != '\n':
     93                    i += 1
     94                i += 1
     95                self.orders.append(text[last:i])
     96                last = i
     97            elif text[i] == '(':
     98                i += 1
     99                last = i
     100                level = 1
     101                while level != 0:
     102                    if text[i] == '(':
     103                        level += 1
     104                    elif text[i] == ')':
     105                        level -= 1
     106                    i += 1
     107                t = text[last:i-1]
     108                pos = t.find(',')
     109                if pos > -1:
     110                    key = eval(t[:pos])
     111                    pos += 1
     112                    begin = pos
     113                    pos = t.find(',', pos)
     114                    if pos > -1:
     115                        pattern = t[begin:pos].lstrip()
     116                        dict = t[pos+1:].rstrip()
     117                    else:
     118                        pattern = t[begin:].strip()
     119                        dict = None
     120                if key not in self.orders:
     121                    self.orders.append(key)
     122                self.nodes[key] = (pattern, dict)
     123                while text[i] != '\n':
     124                    i += 1
     125                i += 1
     126                last = i
     127            else:
     128                while i < len(text) and text[i] != '\n':
     129                    i += 1
     130                i += 1
     131                self.orders.append(text[last:i])
     132                last = i
     133               
     134        self.orders.pop(-1)
     135               
     136               
     137    def remove(self, key):
     138        if self.nodes.has_key(key):
     139            s = self.render_item(key)
     140            del self.nodes[key]
     141            pos = self.orders.index(key)
     142            self.orders[pos] = '#' + s
     143     
     144    def find(self, pattern):
     145        return self.nodes.get(pattern, None)
     146   
     147    def add(self, pattern, method, dict=None):
     148        if pattern not in self.orders:
     149            self.orders.append(pattern)
     150        self.nodes[pattern] = (method, dict)
     151       
     152    def has_method(self, method):
     153        for key, v in self.nodes():
     154            p, d = v
     155            if p == method:
     156                return key
     157        return None
     158       
     159
     160class URLConf:
     161    def __init__(self, urlconf_filename=''):
     162        self.nodes = []
     163        self.urlconf = URLPatterns()
     164        self.filename = urlconf_filename
     165        self.read(self.filename)
     166       
     167    def out(self):
     168        self.save(sys.stdout)
     169                   
     170    def save(self, filename=None):
     171        if not filename:
     172            filename = self.filename
     173        if isinstance(filename, (str, unicode)):
     174            f = file(filename, 'w')
     175        else:
     176            f = filename
     177        text = []
     178        for node in self.nodes:
     179            if isinstance(node, URLPatterns):
     180                text.append(node.render())
     181            else:
     182                if isinstance(node, (list, tuple)):
     183                    text.append(''.join(node))
     184                else:
     185                    text.append(node)
     186        s = ''.join(text)
     187        if s.find('from django.conf.urls.defaults import *') == -1:
     188            s = 'from django.conf.urls.defaults import *\n\n' + s
     189           
     190        f.write(s)
     191       
     192                   
     193    def find(self, pattern):
     194        return self.urlconf.find(pattern, None)
     195   
     196    def easyfind(self, pattern):
     197        pattern = '^%s$' % pattern
     198        return self.find(pattern, None)       
     199   
     200    def add(self, pattern, method, dict=None):
     201        self.urlconf.add(pattern, method, dict)
     202       
     203    def easyadd(self, pattern, method, dict=None):
     204        pattern = '^%s$' % pattern
     205        self.add(pattern, method, dict)
     206       
     207    def has_method(self, method):
     208        return self.urlconf.has_method(method)
     209       
     210    def read(self, filename):
     211        if not filename:
     212            self.nodes.append(self.urlconf)
     213            return
     214       
     215        f = file(filename)
     216        for line in f:
     217            if not line.startswith('urlpatterns'):
     218                self.nodes.append(line)
     219            else:
     220                begin = line.rfind('(')
     221                end = line.rfind(',')
     222                self.urlconf.prefix = line[begin+1:end]
     223                t = f.next()
     224                s = []
     225                while t.strip() != ')':
     226                    s.append(t)
     227                    t = f.next()
     228                self.urlconf.parse(''.join(s+[')']))
     229                self.nodes.append(self.urlconf)
     230               
     231if __name__ == '__main__':
     232#    u = URLConf('urls.py')
     233    u = URLConf()
     234#    print u.find('^ajax/input/$')
     235    u.add('^test/$', 'newtest.test.main')
     236    u.add('^ajax/input/$', "include('newtest.test.ajax')")
     237    u.easyadd('tttt/input/', 'newtest.test.main')
     238    u.easyadd('tttt/input/', 'newtest.test.main', {'template': 'my_calendar/calendar'})
     239    u.out()
     240}}}
Back to Top