Changes between Version 2 and Version 3 of PythonScriptForParsingUrlConf


Ignore:
Timestamp:
02/12/2011 03:36:14 AM (5 years ago)
Author:
José Jorge Lorenzo Vila
Comment:

restored original content

Legend:

Unmodified
Added
Removed
Modified
  • PythonScriptForParsingUrlConf

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