""" OPML.py
"""
__copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
__author__ = "Juri Pakaste <juri@iki.fi>"
__license__ = """
Straw 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.
Straw 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. """
from xml.sax import saxutils, make_parser, SAXParseException
from xml.sax.handler import feature_namespaces, feature_namespace_prefixes
from xml.sax.saxutils import XMLGenerator
from xml.sax.xmlreader import AttributesImpl
import xml.sax._exceptions
import xml.sax.handler
import sys
class OPML(dict):
def __init__(self):
self.outlines = []
def output(self, stream = sys.stdout):
xg = XMLGenerator(stream, encoding='utf-8')
def elemWithContent(name, content):
xg.startElement(name, AttributesImpl({}))
if content is not None:
xg.characters(content)
xg.endElement(name)
xg.characters("\n")
xg.startElement("opml", AttributesImpl({'version': '1.1'}))
xg.startElement("head", AttributesImpl({}))
for key in ('title', 'dateCreated', 'dateModified', 'ownerName',
'ownerEmail', 'expansionState', 'vertScrollState',
'windowTop', 'windowBotton', 'windowRight', 'windowLeft'):
if self.has_key(key) and self[key] != "":
elemWithContent(key, self[key])
xg.endElement("head")
xg.startElement("body", AttributesImpl({}))
for o in self.outlines:
o.output(xg)
xg.endElement("body")
xg.endElement("opml")
class Outline(dict):
__slots__ = ('_children')
def __init__(self):
self._children = []
def add_child(self, outline):
self._children.append(outline)
def get_children_iter(self):
return self.OIterator(self)
children = property(get_children_iter, None, None, "")
def output(self, xg):
xg.startElement("outline", AttributesImpl(self))
for c in self.children:
c.output(xg)
xg.endElement("outline")
xg.characters("\n")
class OIterator:
def __init__(self, o):
self._o = o
self._index = -1
def __iter__(self):
return self
def next(self):
self._index += 1
if self._index < len(self._o._children):
return self._o._children[self._index]
else:
raise StopIteration
class OutlineList:
def __init__(self):
self._roots = []
self._stack = []
def add_outline(self, outline):
if len(self._stack):
self._stack[-1].add_child(outline)
else:
self._roots.append(outline)
self._stack.append(outline)
def close_outline(self):
if len(self._stack):
del self._stack[-1]
def roots(self):
return self._roots
class OPMLHandler(xml.sax.handler.ContentHandler):
def __init__(self):
self._outlines = OutlineList()
self._opml = None
self._content = ""
def startElement(self, name, attrs):
if self._opml is None:
if name != 'opml':
raise ValueError, "This doesn't look like OPML"
self._opml = OPML()
if name == 'outline':
o = Outline()
o.update(attrs)
self._outlines.add_outline(o)
self._content = ""
def endElement(self, name):
if name == 'outline':
self._outlines.close_outline()
return
if name == 'opml':
self._opml.outlines = self._outlines.roots()
return
for key in ('title', 'dateCreated', 'dateModified', 'ownerName',
'ownerEmail', 'expansionState', 'vertScrollState',
'windowTop', 'windowBotton', 'windowRight', 'windowLeft'):
if name == key:
self._opml[key] = self._content
return
def characters(self, ch):
self._content += ch
def get_opml(self):
return self._opml
def parse(stream):
parser = make_parser()
parser.setFeature(feature_namespaces, 0)
handler = OPMLHandler()
parser.setContentHandler(handler)
parser.parse(stream)
return handler.get_opml()
syntax highlighted by Code2HTML, v. 0.9.1