"Fossies" - the Fresh Open Source Software Archive

Member "anticms-0.2.1/cgi-bin/code/template.py" (5 Nov 2005, 5786 Bytes) of package /linux/www/old/anticms-0.2.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "template.py" see the Fossies "Dox" file reference documentation.

    1 #!/usr/bin/env python
    2 # -*- coding: utf-8 -*-
    3 
    4 # $Id: template.py,v 1.2 2005/11/05 12:43:26 aurb Exp $
    5 
    6 # Copyright (C) 2005 Aurelius Bruzas
    7 
    8 # Permission is hereby granted, free of charge, to any person obtaining a
    9 # copy of this software and associated documentation files (the
   10 # "Software"), to deal in the Software without restriction, including
   11 # without limitation the rights to use, copy, modify, merge, publish,
   12 # distribute, sublicense, and/or sell copies of the Software, and to permit
   13 # persons to whom the Software is furnished to do so, subject to the
   14 # following conditions:
   15 
   16 # The above copyright notice and this permission notice shall be included
   17 # in all copies or substantial portions of the Software.
   18 
   19 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   20 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   21 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
   22 # NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
   23 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
   24 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
   25 # USE OR OTHER DEALINGS IN THE SOFTWARE.
   26 
   27 # (Yes, this class is released under the MIT license.)
   28 
   29 import re, types
   30 
   31 class Struct:
   32     def __init__(self, start, stop = None):
   33         self.reg_start = re.compile(start, re.S + re.U + re.M )
   34 
   35         if stop:
   36             self.reg_stop = re.compile(stop, re.S + re.U + re.M)
   37         else:
   38             self.reg_stop = None
   39 
   40 
   41     def replaceAll(self, fun, text):
   42         txt = text
   43         tmp = self.replace(fun, txt)
   44         while tmp:
   45             txt = tmp
   46             tmp = self.replace(fun, txt)
   47 
   48         return txt
   49 
   50 # ----------------------------------------------------------------------- #
   51 
   52     def searchAll(self, expr, text):
   53         start = 0
   54         m = expr.search(text, start)
   55         while m:
   56             yield m
   57             start = m.end()
   58             m = expr.search(text, start)
   59 
   60 
   61     def replace(self, fun, text):
   62         # FIXME: This is not very efficient...
   63 
   64         if self.reg_stop:
   65             items = {}
   66             for i in self.searchAll(self.reg_start, text): items[i.start()] = i
   67             for i in self.searchAll(self.reg_stop, text): items[i.start()] = i
   68             keys = items.keys()
   69             keys.sort()
   70             open = 0
   71             start = -1
   72             stop = -1
   73 
   74             for i in keys:
   75                 if items[i].re == self.reg_start:
   76                     if open == 0: start = i
   77                     open += 1
   78                 elif items[i].re == self.reg_stop:
   79                     open -= 1
   80                     if open == 0 and start != -1:
   81                         stop = i
   82                         break
   83 
   84             if start != -1 and stop != -1 and fun:
   85                 return text[:items[start].start()] + fun(items[start], items[stop], text[items[start].end():items[stop].start()]) + text[items[stop].end():]
   86             else:
   87                 return None
   88 
   89         else:
   90             try:
   91                 item = self.searchAll(self.reg_start, text).next()
   92             except:
   93                 return None
   94             else:
   95                 return text[:item.start()] + fun(item) + text[item.end():]
   96 
   97 # ----------------------------------------------------------------------- #
   98 
   99 class Template:
  100     content = {}
  101     inEncoding = 'UTF-8'
  102 
  103     stru_single = Struct("<\\s*([\\w\\.]+)\\s+([\\w\\.]+)[\\s/]*>")
  104     stru_if = Struct("<\\s*if\\s+\\'(.+?)\\'\\s+\\/(.+?)\\/\\s*>", "<\\s*\\/\\s*if\\s*>")
  105     stru_loop = Struct("<\\s*for\\s+([\\w\\.]+)\\s+in\\s+([\\w\\.]+)\\s*>", "<\\s*/\\s*for\\s*>")
  106     stru_block = Struct("<\\s*block\\s+([\\w\\.]+)\\s*>", "<\\s*/\\s*block\\s*>")
  107 
  108     def __init__(self, file = None, inenc = None):
  109         if inenc: self.inEncoding = inenc
  110         if file: self.set_file('__main', file)
  111 
  112 
  113     def set_var(self, dest, src):
  114         self.content[dest] = src
  115 
  116 
  117     def set_file(self, dest, fname):
  118         file = open(fname, "r")
  119         self.content[dest] = file.read().decode(self.inEncoding)
  120         file.close()
  121 
  122 
  123     def process(self, dest = "", source = ""):
  124         if source == "":
  125             text = unicode(self.content['__main'])
  126         else:
  127             text = unicode(self.content[source])
  128 
  129         text = self.stru_block.replaceAll(self.block_replace, text)
  130         text = self.stru_loop.replaceAll(self.loop_replace, text)
  131         text = self.stru_single.replaceAll(self.single_replace, text)
  132         text = self.stru_if.replaceAll(self.if_replace, text)
  133 
  134         if dest != "": self.content[dest] = text
  135         return text
  136 
  137 
  138     def remove_var(self, handle):
  139         self.content.pop(handle)
  140 
  141 
  142     def get_var(self, handle):
  143         return self.content[handle]
  144 
  145 # ----------------------------------------------------------------------- #
  146 
  147     def single_replace(self, match):
  148         if match.group(1) == 'val':
  149             val = unicode(self.get_value(match.group(2)))
  150             val = self.stru_block.replaceAll(self.block_replace, val)
  151             val = self.stru_loop.replaceAll(self.loop_replace, val)
  152             return val
  153         elif match.group(1) == 'count':
  154             val = self.get_value(match.group(2))
  155             if type(val) in (types.ListType, types.TupleType, types.DictType):
  156                 return unicode(len(val))
  157             else:
  158                 return u'0'
  159         else:
  160             return match.group(0)
  161 
  162 
  163     def loop_replace(self, start, end, text):
  164         base = self.get_value(start.group(2))
  165         reg_star = re.compile("\\b" + start.group(1) + "\\b", re.S + re.U + re.M)
  166         reg_cnt = re.compile("\\b" + start.group(1) + "_CNT\\b", re.S + re.U + re.M)
  167         txt = ""
  168         cnt = 1
  169 
  170         if type(base) in (types.ListType, types.TupleType):
  171             for i in range(len(base)):
  172                 txt += reg_star.sub(start.group(2) + '.' + unicode(i), reg_cnt.sub(unicode(cnt), text))
  173                 cnt += 1
  174 
  175         elif (type(base) in [types.DictType]):
  176             for i in base:
  177                 txt += reg_star.sub(start.group(2) + '.' + unicode(i), reg_cnt.sub(unicode(cnt), text))
  178                 cnt += 1
  179 
  180         else:
  181             txt = ''
  182 
  183         return txt
  184 
  185 
  186     def block_replace(self, start, end, text):
  187         self.content[start.group(1)] = text
  188         return ""
  189 
  190 
  191     def if_replace(self, start, end, text):
  192         if re.match(start.group(2), start.group(1)):
  193             return text
  194         else:
  195             return ''
  196 
  197 
  198     def get_value(self, name):
  199         base = name.split('.')
  200         ui = self.content
  201 
  202         for i in base:
  203             if type(ui) == types.ListType: i = int(i)
  204             try:
  205                 ui = ui[i]
  206             except:
  207                 ui = name
  208                 break
  209 
  210         return ui