From 8b293e9091299dd5f470f00f866eee55a974d875 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Mon, 11 Aug 2003 16:16:55 +0000 Subject: [PATCH 1/1] Added an experimental implementation of BIFE in python. --- byfe/__init__.py | 75 ++++++++++++++++++++++++++++++++++++++++++++ byfe/core.py | 75 ++++++++++++++++++++++++++++++++++++++++++++ byfe/hit.py | 56 +++++++++++++++++++++++++++++++++ byfe/parser.py | 56 +++++++++++++++++++++++++++++++++ index.xbf | 15 +++++++++ test.tpl | 6 ++++ test2.tpl | 3 ++ tests/parser_test.py | 32 +++++++++++++++++++ tests/sqlite.py | 14 +++++++++ 9 files changed, 332 insertions(+) create mode 100644 byfe/__init__.py create mode 100644 byfe/core.py create mode 100644 byfe/hit.py create mode 100644 byfe/parser.py create mode 100644 index.xbf create mode 100644 test.tpl create mode 100644 test2.tpl create mode 100755 tests/parser_test.py create mode 100755 tests/sqlite.py diff --git a/byfe/__init__.py b/byfe/__init__.py new file mode 100644 index 0000000..043414a --- /dev/null +++ b/byfe/__init__.py @@ -0,0 +1,75 @@ +# vim: set expandtab tabstop=4 shiftwidth=4: + +class widget: + """Base widget class.""" + + def __init__(self, attrs = None): + if attrs is None: + attrs = {} + self.attrs = attrs + + def __repr__(self): + return 'widget(attrs=' + str(self.attrs) + ')' + + def render(self, userdata = None): + return str(self) + + +class container(widget): + """Base container widget class.""" + + def __init__(self, attrs = None, content = None): + widget.__init__(self, attrs) + self.content = [] + if content: + self.content.append(content) + + def __repr__(self): + return 'container(attrs=' + str(self.attrs) + ', content=' \ + + str(self.content) + ')' + + def __len__(self): + return len(self.content) + + def __getitem__(self, item): + return self.content[item] + + def __setitem__(self, item, value): + self.content[item] = value + + def __delitem__(self, item): + del self.content[item] + + def __contains__(self, item): + return item in self.content + + def __iter__(self): + for i in self.content: yield i + + def append(self, content): + self.content.append(content) + + def extend(self, content): + self.content.extend(content) + + def renderContent(self, userdata = None): + out = '' + for content in self.content: + if isinstance(content, widget): + out += content.render(userdata) + else: + out += str(content); + return out; + + +class fallback(container): + """Fallback widget to use when no specific widget is implemented.""" + + def __init__(self, name, attrs = None, content = None): + container.__init__(self, attrs, content) + self.name = name + + def __repr__(self): + return 'fallback(name=\'' + str(self.name) + '\', attrs=' \ + + str(self.attrs) + ', content=' + str(self.content) + ')' + diff --git a/byfe/core.py b/byfe/core.py new file mode 100644 index 0000000..043414a --- /dev/null +++ b/byfe/core.py @@ -0,0 +1,75 @@ +# vim: set expandtab tabstop=4 shiftwidth=4: + +class widget: + """Base widget class.""" + + def __init__(self, attrs = None): + if attrs is None: + attrs = {} + self.attrs = attrs + + def __repr__(self): + return 'widget(attrs=' + str(self.attrs) + ')' + + def render(self, userdata = None): + return str(self) + + +class container(widget): + """Base container widget class.""" + + def __init__(self, attrs = None, content = None): + widget.__init__(self, attrs) + self.content = [] + if content: + self.content.append(content) + + def __repr__(self): + return 'container(attrs=' + str(self.attrs) + ', content=' \ + + str(self.content) + ')' + + def __len__(self): + return len(self.content) + + def __getitem__(self, item): + return self.content[item] + + def __setitem__(self, item, value): + self.content[item] = value + + def __delitem__(self, item): + del self.content[item] + + def __contains__(self, item): + return item in self.content + + def __iter__(self): + for i in self.content: yield i + + def append(self, content): + self.content.append(content) + + def extend(self, content): + self.content.extend(content) + + def renderContent(self, userdata = None): + out = '' + for content in self.content: + if isinstance(content, widget): + out += content.render(userdata) + else: + out += str(content); + return out; + + +class fallback(container): + """Fallback widget to use when no specific widget is implemented.""" + + def __init__(self, name, attrs = None, content = None): + container.__init__(self, attrs, content) + self.name = name + + def __repr__(self): + return 'fallback(name=\'' + str(self.name) + '\', attrs=' \ + + str(self.attrs) + ', content=' + str(self.content) + ')' + diff --git a/byfe/hit.py b/byfe/hit.py new file mode 100644 index 0000000..a4527d1 --- /dev/null +++ b/byfe/hit.py @@ -0,0 +1,56 @@ +# vim: set expandtab tabstop=4 shiftwidth=4: + +import os + +class HIT: + """Hooks vs IT template engine.""" + root = '.' + use_path = False + group = '' + postfix = '.tpl.html' + + def __init__(self, root = root, postfix = postfix, use_path = use_path, group = group): + """Constructor.""" + self.root = root + self.use_path = use_path + self.postfix = postfix + self.group = [] + self.cache = {} + self.buffer = {} + self.group.append(group) + + def parse(self, name, vars = {}, **more_vars): + """Parses a block of code.""" + cache_key = self.group[len(self.group)-1] + os.sep + name + self.postfix + filename = self.root + os.sep + cache_key + if not self.cache.has_key(cache_key): + self.cache[cache_key] = file(filename).read() + out = self.cache[cache_key] + for key, val in vars.items(): + out = out.replace('{' + key + '}', val) + for key, val in more_vars.items(): + out = out.replace('{' + key + '}', val) + return out + + def parseBuffered(self, name, vars = {}, **more_vars): + """Parses a block of code leaving the result in a temporary buffer.""" + self.buffer[self.group + os.sep + name] += self.parse(name, vars); + + def get_buffer(name): + """Gets a parsed buffer.""" + return self.buffer[self.group + os.sep + name] + + def pop_buffer(name): + """Pops a parsed buffer.""" + buff = self.buffer[self.group + os.sep + name] + del self.buffer[self.group + os.sep + name] + return buff + + def push_group(group = ''): + """Pushes a group to work on.""" + self.group.append(group) + + def pop_group(): + """Pops the last group worked on.""" + return self.group.pop() + diff --git a/byfe/parser.py b/byfe/parser.py new file mode 100644 index 0000000..eda9872 --- /dev/null +++ b/byfe/parser.py @@ -0,0 +1,56 @@ +# vim: set expandtab tabstop=4 shiftwidth=4: + +from xml.sax import saxutils, make_parser +from os import sep + +class Parser(xml.sax.saxutils.DefaultHandler): + """ByFE XML Parser.""" + + def __init__(self, fallback = None, cache = os.sep + 'tmp'): + """Constructor.""" + self.fallback = fallback + self.cache = cache + self.parser = xml.sax.make_parser() + self.parser.setFeature(xml.sax.handler.feature_namespaces, 0) + self.parser.setContentHandler(self) + + def startElement(self, name, attrs): # FIXME - arreglar a partir de aca. + """Start element handler.""" + mods = name.lower().split('.') + classname = path.pop() + modulename = 'bife.' + mods.join('.') + try: + module = __import__(modulename, None, None, True) + classobj = getattr(module, classname) + obj = classobj(attrs) + except: + #if self.fallback: + obj = self.fallback(name, attrs) + #else: + # raise "Class not found '$class'." + self.stack[] = obj + + def endElement(self, name): + """End element handler.""" + end(self.stack) + current = self.stack[key(self.stack)] + self.stack.pop() + end(self.stack) + parent = self.stack[key(self.stack)] + if parent: + parent.addContents(current) + else: + self.root = current + + def characters(self, data): + """Caracter data handler.""" + end(self.stack) + current = self.stack[key(self.stack)] + current.addContents(data) + + def parse(self, file): + # TODO - cache + if !self.parser.parse(self.parser, file) + + def parseString(self, string): + if !self.parser.parseString(self.parser, string, self) diff --git a/index.xbf b/index.xbf new file mode 100644 index 0000000..3e846c1 --- /dev/null +++ b/index.xbf @@ -0,0 +1,15 @@ + + + BIFE is working! +

Translate Fallback is working too!

+

This is a very bad use for BIFE, because I'm writing HTML :-P

+ A little of 'real' use +

Here's a link to another BIFE file

+ Links to subdirectories +

Here's a file in a directory.

+

And a file in a subdirectory.

+

Finally a file in a another directory.

+
+ View BIFE (xbf) source | + View PHP source +
diff --git a/test.tpl b/test.tpl new file mode 100644 index 0000000..5adc97d --- /dev/null +++ b/test.tpl @@ -0,0 +1,6 @@ +Este es un template. Todos los valores como este: {VALOR} +van a ser reemplazados. +También podemos poner algo anidado: +{ANIDADO} + +Chau. diff --git a/test2.tpl b/test2.tpl new file mode 100644 index 0000000..f31f2f6 --- /dev/null +++ b/test2.tpl @@ -0,0 +1,3 @@ +Esto está contenido en otro lado. +La hora es {HORA} +Fin de texto incluido desde {VALOR} diff --git a/tests/parser_test.py b/tests/parser_test.py new file mode 100755 index 0000000..29f3f68 --- /dev/null +++ b/tests/parser_test.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# vim: set et ts=4 sw=4: + +from xml.sax import saxutils, make_parser +from xml.sax.handler import feature_namespaces +from sys import argv + +class Parser(saxutils.DefaultHandler): + def __init__(self): + self.level = 0 + self.parser = make_parser() + self.parser.setFeature(feature_namespaces, 0) + self.parser.setContentHandler(self) + + def startElement(self, name, attrs): + print self.level * ' ', 'Inicio:', name + self.level += 1 + for key, val in attrs.items(): + print self.level * ' ', key, '=', val + + def endElement(self, name): + self.level -= 1 + print self.level * ' ', 'Fin:', name + + def characters(self, data): + print self.level * ' ', 'Datos:', data + + def parse(self, file): + self.parser.parse(file) + +if __name__ == '__main__': + Parser().parse(argv[1]) diff --git a/tests/sqlite.py b/tests/sqlite.py new file mode 100755 index 0000000..079d876 --- /dev/null +++ b/tests/sqlite.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +# vim: set et ts=4 sw=4 tw=0 fdm=syntax fileencoding=iso-8859-1: + +import sqlite + +def printall(db, table='test'): + """Funcion que imprime todos los elementos de una tabla de sqlite. + """ + dbh = sqlite.connect(db) + dbr = dbh.cursor() + dbr.execute('SELECT * FROM ' + table) + for row in dbr.fetchall(): + for k, v in row: print k, '=', v + -- 2.43.0