atomixlib-0.4.0/0000755000175000001440000000000010440626227013112 5ustar sylvainusersatomixlib-0.4.0/__init__.py0000644000175000001440000000370210440626202015216 0ustar sylvainusers#!/usr/bin/env python # -*- coding: utf-8 -*- __version__ = "0.4.0" __authors__ = ["Sylvain Hellegouarch (sh@defuze.org)", "Andrew Ittner (andrew.ittner@usa.net)"] __date__ = "2006/05/14" __copyright__ = """ Copyright (c) 2005, 2006 Sylvain Hellegouarch & Andrew Ittner All rights reserved. """ __license__ = """ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Sylvain Hellegouarch & Andrew Ittner nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ __doc__ = """ atomixlib provides a simple API to generate Atom 1.0 documents (http://atompub.org/) It supports all the atom elements except atom:source. """ atomixlib-0.4.0/PKG-INFO0000644000175000001440000000140410440626202014177 0ustar sylvainusersMetadata-Version: 1.1 Name: atomixlib Version: 0.4.0 Author: Sylvain Hellegouarch, Andrew Ittner Author-email: sh at defuze org, andrew.ittner at usa.net Maintainer: Sylvain Hellegouarch Maintainer-email: sh at defuze org Home-page: http://trac.defuze.org/browser/oss/atomixlib Download-url: http://trac.defuze.org/browser/oss/atomixlib Summary: A module to generate Atom 1.0 documents through a simple API License: BSD Description: Atom is an XML format for syndication of resources. atomixlib tries to simplify to Python developers the creation of Atom 1.0 documents by providing a simple API. Keywords: xml, atom Platform: any Requires: Amara or ElementTree Classifier: Development Status :: 5 - Production/Stable Classifier: Topic :: Text Processing :: Markup :: XMLatomixlib-0.4.0/setup.py0000644000175000001440000000155710440626202014625 0ustar sylvainusers"""A module to generate Atom 1.0 documents through a simple API Atom is an XML format for syndication of resources. atomixlib tries to simplify to Python developers the creation of Atom 1.0 documents by providing a simple API. """ from distutils.core import setup from distutils.command.install import INSTALL_SCHEMES doclines = __doc__.split("\n") for scheme in INSTALL_SCHEMES.values(): scheme['data'] = scheme['purelib'] setup(name = "atomixlib", version = '0.4.0', description = doclines[0], maintainer = "Sylvain Hellegouarch", maintainer_email = "sh@defuze.org", url = "http://trac.defuze.org/browser/oss/atomixlib", download_url = "http://trac.defuze.org/browser/oss/atomixlib", packages = ["atomixlib"], platforms = ["any"], license = 'BSD', long_description = "\n".join(doclines[2:]), ) atomixlib-0.4.0/test/0000755000175000001440000000000010440626237014072 5ustar sylvainusersatomixlib-0.4.0/test/test_amara.py0000644000175000001440000000475210440626220016564 0ustar sylvainusers#!/usr/bin/env python # -*- coding: utf-8 -*- import unittest from atomixlib import ax_amara as atomixlib class TestAtomFeed(unittest.TestCase): def testcreate(self): self.assert_(atomixlib.create_feed()) def testserialize(self): empty_doc = """ """ f = atomixlib.create_feed() self.assertEqual(empty_doc, f.xml()) def testid(self): doc = """ test """ f = atomixlib.create_feed() f.add_id(u'test') self.assertEqual(doc, f.xml()) def testauthor(self): doc = """ sylvain test@test.com http://test.com """ f = atomixlib.create_feed() f.add_author(u'sylvain', email=u'test@test.com', uri=u'http://test.com') self.assertEqual(doc, f.xml()) def testentry(self): doc = """ """ f = atomixlib.create_feed() f.add_entry() self.assertEqual(doc, f.xml()) def testfull(self): doc = """ feed-id 2006-05-14T14:30:44.079458Z sylvain test@test.com http://test.com entry-id
hello there
""" f = atomixlib.create_feed() f.add_id(u'feed-id') f.add_published(u'2006-05-14T14:30:44.079458Z') f.add_author(u'sylvain', email=u'test@test.com', uri=u'http://test.com') f.add_category(u'atom') f.add_entry() f.add_id(u'entry-id') f.add_content('hello there', target='inlineXHTML') self.assertEqual(doc, f.xml()) if __name__ == '__main__': unittest.main() atomixlib-0.4.0/test/test_elementtree.py0000644000175000001440000000464610440626220020016 0ustar sylvainusers#!/usr/bin/env python # -*- coding: utf-8 -*- import unittest from atomixlib import ax_elementtree as atomixlib class TestAtomFeed(unittest.TestCase): def testcreate(self): self.assert_(atomixlib.create_feed()) def testserialize(self): empty_doc = """ """ f = atomixlib.create_feed() self.assertEqual(empty_doc, f.xml()) def testid(self): doc = """ test""" f = atomixlib.create_feed() f.add_id(u'test') self.assertEqual(doc, f.xml()) def testauthor(self): doc = """ sylvaintest@test.comhttp://test.com""" f = atomixlib.create_feed() f.add_author(u'sylvain', email=u'test@test.com', uri=u'http://test.com') self.assertEqual(doc, f.xml()) def testentry(self): doc = """ """ f = atomixlib.create_feed() f.add_entry() self.assertEqual(doc, f.xml()) def testfull(self): doc = """ feed-id2006-05-14T14:30:44.079458Zsylvaintest@test.comhttp://test.comentry-id
hello there
""" f = atomixlib.create_feed() f.add_id(u'feed-id') f.add_published(u'2006-05-14T14:30:44.079458Z') f.add_author(u'sylvain', email=u'test@test.com', uri=u'http://test.com') f.add_category(u'atom') f.add_entry() f.add_id(u'entry-id') f.add_content('hello there', target='inlineXHTML') self.assertEqual(doc, f.xml()) if __name__ == '__main__': unittest.main() atomixlib-0.4.0/atomixlib/0000755000175000001440000000000010440626255015103 5ustar sylvainusersatomixlib-0.4.0/atomixlib/ax_elementtree.py0000644000175000001440000003642610440626227020470 0ustar sylvainusers#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################# # Get the ElementTree source at: # http://effbot.org/downloads/index.cgi#elementtree # This version of atomixlib-et requires ElementTree 1.2.6 or above ############################################# #try: # from cElementTree import Element, SubElement, parse # from cElementTree import ElementTree as ETX #except ImportError: from elementtree.ElementTree import Element, SubElement, parse from elementtree import ElementTree as ETX ATOM10_NS_STR = 'http://www.w3.org/2005/Atom' ATOM10_NS = u'http://www.w3.org/2005/Atom' XHTML1_NS_STR = 'http://www.w3.org/1999/xhtml' XHTML1_NS = u'http://www.w3.org/1999/xhtml' GENERATOR_NAME = u'atomixlib [elementtree]' ENCODING = 'UTF-8' DUMMY_URI = u'http://dummy.com' #COMMON_PREFIXES = { u'atom': ATOM10_NS, u'': XHTML1_NS } COMMON_PREFIXES = { u'atom': ATOM10_NS, u'xhtml': XHTML1_NS } ############################################# # Public API ############################################# def create_feed(encoding=ENCODING, prefixes={}, uri=DUMMY_URI): """ Create an empty atom feed document. Return an instance of Atomix class. Keyword arguments: encoding -- encoding used throughout the XML document prefixes -- namespaces you might want to attach to the XML document uri -- base URI for the XML document created """ # join any user-defined prefixes with default namespace and switch to key=URL, value=prefix for k, v in COMMON_PREFIXES.items(): prefixes[v] = k # update the ET namespace dict ETX._namespace_map.update(prefixes) # create root element return Atomix(Element('{%s}feed' % ATOM10_NS), encoding=ENCODING) def create_entry(encoding=ENCODING, prefixes={}, uri=DUMMY_URI): """ Create an empty atom entry document. Return an instance of Atomix class. Keyword arguments: encoding -- encoding used throughout the XML document prefixes -- namespaces you might want to attach to the XML document uri -- base URI for the XML document created """ for k, v in COMMON_PREFIXES.items(): prefixes[v] = k # update the ET namespace dict ETX._namespace_map.update(prefixes) return Atomix(Element('{%s}feed' % ATOM10_NS), encoding=ENCODING) def load(source, encoding=ENCODING, prefixes={}, uri=DUMMY_URI): """ TODO: convert Load an Atom document and parse it. Returns an instance of Atomix class. Keyword arguments: source -- can be a string, a path, an URI or a file object encoding -- encoding used throughout the XML document prefixes -- namespaces you might want to attach to the XML document uri -- base URI for the XML document created (only required when source is a string) """ for k, v in COMMON_PREFIXES.items(): prefixes[v] = k # update the ET namespace dict ETX._namespace_map.update(prefixes) # In the case where the source is a string, we need the uri as well if isinstance(source, basestring): return Atomix(Element('{%s}feed' % ATOM10_NS), encoding=ENCODING) return Atomix(ETX.parse(source), encoding=ENCODING) class Atomix: """ Provides the API to generate Atom 1.0 documents. The methods of this class follows the Atom specification closely. It supports all the atom elements except atom:source. Atomix holds an internal cursor to the current element under edition Each method adds an atom element to the element handled by the cursor. Only adding an entry will change the internal cursor to the newly created entry. Nontheless, if you need to come back to a specific atom element (feed or entry) you can set the cursor to the requested element. For example: atom : create_feed() # sets the cursor to atom.doc.feed atom.add_entry() # changes the cursor to atom.doc.feed.entry[-1] atom.cursor = atom.doc.feed # oops let's come back to the feed element for a while This should be rarely used as long as you create your atom document sequentially. Atomix also holds the namespace prefix used for XHTML input. By default it falls back to '' so that you do not need to specify the namespace prefix at all. But if you need to set a specific one simply do this: atom = create_feed() atom.xhtmlprefix = 'xhtml' atom.add_entry() atom.add_content('yeah', target='inlineXHTML') """ def __init__(self, atom, encoding=ENCODING): """ initialize an Atomix instance Keyword arguments: atom -- an ElementTree Element instance (the root element) encoding -- the encoding used throughout the XML document """ self.doc = atom self.encoding = encoding self.xhtmlprefix = '' # using ElementTree, the doc is already either 'atom:feed' or 'atom:entry', # so no need to distinguish self.cursor = self.doc def __str__(self): """ return an unindented version of the XML document as a string """ #TODO: indentation? # return self.doc.xml(encoding=self.encoding) return ETX.tostring(self.doc, encoding=self.encoding) def xml(self, indent='no'): """ return the atom document as a string Keyword arguments: indent -- specifies whether or not the result should be indented """ #TODO: indentation? #return self.doc.xml(indent=indent, encoding=self.encoding) return ETX.tostring(self.doc, encoding=self.encoding) def add_entry(self): """ insert an atom:entry element into the Atom document it will set the internal cursor to the newly created entry. """ self.doc.append(Element('{%s}entry' % ATOM10_NS)) self.cursor = self.doc[-1] def add_id(self, uri): """ insert an atom:id element into the Atom document Keyword arguments: uri -- the id value as an URI """ self.cursor.append(Element('{%s}id' % ATOM10_NS)) self.cursor[-1].text = uri def add_author(self, name, email=None, uri=None): """ insert an atom:author element into the Atom document Keyword arguments: name -- the name of the author email -- the email of the author, appended only if provided uri -- the uri of the author, appended only if provided """ self.cursor.append(Element('{%s}author' % ATOM10_NS)) construct_person(self.cursor[-1], name, email, uri) def add_category(self, term, scheme=None, label=None): """ insert an atom:category element into the Atom document Keyword arguments: term -- the term defining the category scheme -- appended only if provided label -- a friendly user label of the category, appended only if provided """ self.cursor.append(Element('{%s}category' % ATOM10_NS)) add_attribute(self.cursor[-1], u'term', term) add_attribute(self.cursor[-1], u'scheme', scheme) add_attribute(self.cursor[-1], u'label', label) def add_contributor(self, name, email=None, uri=None): """ insert an atom:contributor element into the Atom document Keyword arguments: name -- the name of the author email -- the email of the author, appended only if provided uri -- the uri of the author, appended only if provided """ self.cursor.append(Element('{%s}contributor' % ATOM10_NS)) construct_person(self.cursor[-1], name, email, uri) def add_generator(self, value=GENERATOR_NAME, uri=None, version=None): """ insert an atom:generator element into the Atom document Keyword arguments: value -- the representation as a string of the generator uri -- the uri of the author, appended only if provided version -- the version of the generator """ self.cursor.append(Element('{%s}generator' % ATOM10_NS)) self.cursor[-1].text = value add_attribute(self.cursor[-1], u'uri', uri) if value == GENERATOR_NAME and version == None: # automatically add this module's version add_attribute(self.cursor[-1], u'version', __version__) else: add_attribute(self.cursor[-1], u'version', version) def add_icon(self, uri): """ insert an atom:icon element into the Atom document Keyword arguments: uri -- the uri of the author, appended only if provided """ self.cursor.append(Element('{%s}icon' % ATOM10_NS)) self.cursor[-1].text = uri def add_title(self, title, mediaType='text'): """ insert an atom:title element into the Atom document Keyword arguments: title -- title value to be added mediaType -- media type used for the title (text, html or xhtml) """ self.cursor.append(Element('{%s}title' % ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor[-1], title, self.encoding, self.xhtmlprefix) def add_updated(self, isoDate=None): """ insert an atom:updated element into the Atom document Keyword arguments: isoDate -- value of the date respecting ISO 8601 format """ self.cursor.append(Element('{%s}updated' % ATOM10_NS)) construct_date(self.cursor[-1], isoDate) def add_published(self, isoDate=None): """ insert an atom:published element into the Atom document Keyword arguments: isoDate -- value of the date respecting ISO 8601 format """ self.cursor.append(Element('{%s}published' % ATOM10_NS)) construct_date(self.cursor[-1], isoDate) def add_link(self, href, rel=None, mediaType=None, hreflang=None, title=None, length=None, uri=None): """ insert an atom:link element into the Atom document Keyword arguments: href -- the URI of the link rel -- the type of the link mediaType -- the media type of the link hreflang -- the language of the link title -- a lable for the link length -- the length of the resource targeted by the URI uri -- if no rel provided, one must provide the uri """ self.cursor.append(Element('{%s}link' % ATOM10_NS)) add_attribute(self.cursor[-1], u'href', href) if rel: add_attribute(self.cursor[-1], u'rel', rel) elif uri: add_attribute(self.cursor[-1], u'uri', uri) add_attribute(self.cursor[-1], u'type', mediaType) add_attribute(self.cursor[-1], u'hreflang', hreflang) add_attribute(self.cursor[-1], u'title', title) add_attribute(self.cursor[-1], u'length', length) def add_logo(self, uri): """ insert an atom:logo element into the Atom document Keyword arguments: uri -- the uri of the author, appended only if provided """ self.cursor.append(Element('{%s}logo' % ATOM10_NS)) self.cursor[-1].text = uri def add_rights(self, text, mediaType=u'text'): """ insert an atom:rights element into the Atom document Keyword arguments: text -- rights value to be added mediaType -- media type used for the rights (text, html or xhtml) """ self.cursor.append(Element('{%s}rights' % ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor[-1], text, self.encoding, self.xhtmlprefix) def add_subtitle(self, text, mediaType=u'text'): """ insert an atom:subtitle element into the Atom document Keyword arguments: text -- subtitle value to be added mediaType -- media type used for the subtitle (text, html or xhtml) """ self.cursor.append(Element('{%s}subtitle' % ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor[-1], text, self.encoding, self.xhtmlprefix) def add_summary(self, text, mediaType=u'text'): """ insert an atom:summary element into the Atom document Keyword arguments: text -- summary to be added mediaType -- media type used for the summary (text, html or xhtml) """ self.cursor.append(Element('{%s}summary' % ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor[-1], text, self.encoding, self.xhtmlprefix) def add_content(self, text='', target='inlineText', src=None): """ insert an atom:content element into the Atom document Keyword arguments: text -- the actual content target -- the type of content src -- the source of the actual content """ self.cursor.append(Element('{%s}content' % ATOM10_NS)) if target in ['inlineText', 'inlineOther']: construct_plain_text(self.cursor[-1], text, self.encoding) elif target == 'inlineXHTML': construct_xhtml_text(self.cursor[-1], text, self.encoding, self.xhtmlprefix) elif target == 'inlineHTML': construct_html_text(self.cursor[-1], text, self.encoding) elif target == 'outOfLine': construct_out_of_line_content(self.cursor[-1], text, src, self.encoding) ############################################# # Helper internal functions # Private API ############################################# def construct_person(node, name, email=None, uri=None): #TODO: remove doc parameter node.append(Element('{%s}name' % ATOM10_NS)) node[-1].text = name if email: node.append(Element('{%s}email' % ATOM10_NS)) node[-1].text = email if uri: node.append(Element('{%s}uri' % ATOM10_NS)) node[-1].text = uri def construct_plain_text(node, text, encoding, unused=None): node.set(u'type', u'text') node.text = text def construct_html_text(node, html, encoding, unused=None): node.set(u'type', u'html') node.text = html def construct_xhtml_text(node, xhtml, encoding, xhtmlprefix): node.set(u'type', u'xhtml') try: if xhtmlprefix: nodediv = Element('{%s}div' % XHTML1_NS) nodediv.append(ETX.XML(xhtml)) node.append(nodediv) #node.append(ETX.XML('<%s:div xmlns:%s="%s">%s' % #(xhtmlprefix, xhtmlprefix, XHTML1_NS_STR, xhtml, xhtmlprefix))) #, #encoding=encoding) else: nodediv = Element('div', {'xmlns': XHTML1_NS}) nodediv.append(ETX.XML(xhtml)) node.append(nodediv) except: # attempt to parse by wrapping xhtml in div nodediv = ETX.XML('
%s
' % (XHTML1_NS, xhtml)) node.append(nodediv) def construct_out_of_line_content(node, text, mediaType, src, encoding): node.set(u'type', mediaType) node.set(u'src', src) node.text = text def get_isodate(): """ returns a date respecting ISO 8601 format """ import datetime return unicode(datetime.datetime.utcnow().isoformat() + 'Z') def construct_date(node, isoDate=None): if not isoDate: isoDate = get_isodate() node.text = isoDate def add_attribute(node, name, value): if value: node.set(name, value) _text_construct_mapper = { u'text': construct_plain_text, u'html': construct_html_text, u'xhtml': construct_xhtml_text } atomixlib-0.4.0/atomixlib/ax_amara.py0000644000175000001440000003666510440626227017245 0ustar sylvainusers#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################# # A big thanks to Uche Ogbuji # (http://copia.ogbuji.net/blog/) # for his help to improve atomixlib # specially for the cursor idea :) ############################################# ############################################# # Get the excellent Amara toolkit at: # http://uche.ogbuji.net/uche.ogbuji.net/tech/4suite/amara/ # This version of atomixlib requires Amara 1.1.6 or above # It won't work with Amara 1.0 ############################################# import amara ATOM10_NS_STR = 'http://www.w3.org/2005/Atom' ATOM10_NS = u'http://www.w3.org/2005/Atom' XHTML1_NS_STR = 'http://www.w3.org/1999/xhtml' XHTML1_NS = u'http://www.w3.org/1999/xhtml' GENERATOR_NAME = u'atomixlib [amara]' ENCODING = 'UTF-8' DUMMY_URI = u'http://dummy.com' COMMON_PREFIXES = { u'atom': ATOM10_NS, u'': XHTML1_NS } ############################################# # Public API ############################################# def create_feed(encoding=ENCODING, prefixes={}, uri=DUMMY_URI): """ Create an empty atom feed document. Return an instance of Atomix class. Keyword arguments: encoding -- encoding used throughout the XML document prefixes -- namespaces you might want to attach to the XML document uri -- base URI for the XML document created """ prefixes.update(COMMON_PREFIXES) return Atomix(amara.parse('' % (ATOM10_NS_STR, ), uri=uri, prefixes=prefixes), encoding=ENCODING) def create_entry(encoding=ENCODING, prefixes={}, uri=DUMMY_URI): """ Create an empty atom entry document. Return an instance of Atomix class. Keyword arguments: encoding -- encoding used throughout the XML document prefixes -- namespaces you might want to attach to the XML document uri -- base URI for the XML document created """ prefixes.update(COMMON_PREFIXES) return Atomix(amara.parse('' % (ATOM10_NS_STR, ), uri=uri, prefixes=prefixes), encoding=ENCODING) def load(source, encoding=ENCODING, prefixes={}, uri=DUMMY_URI): """ Load an Atom document and parse it. Returns an instance of Atomix class. Keyword arguments: source -- can be a string, a path, an URI or a file object encoding -- encoding used throughout the XML document prefixes -- namespaces you might want to attach to the XML document uri -- base URI for the XML document created (only required when source is a string) """ prefixes.update(COMMON_PREFIXES) # In the case where the source is a string, we need the uri as well if isinstance(source, basestring): return Atomix(amara.parse(source, uri=uri, prefixes=prefixes), encoding=ENCODING) return Atomix(amara.parse(source, prefixes=prefixes), encoding=ENCODING) class Atomix: """ Provides the API to generate Atom 1.0 documents. The methods of this class follows the Atom specification closely. It supports all the atom elements except atom:source. Atomix holds an internal cursor to the current element under edition Each method adds an atom element to the element handled by the cursor. Only adding an entry will change the internal cursor to the newly created entry. Nontheless, if you need to come back to a specific atom element (feed or entry) you can set the cursor to the requested element. For example: atom : create_feed() # sets the cursor to atom.doc.feed atom.add_entry() # changes the cursor to atom.doc.feed.entry[-1] atom.cursor = atom.doc.feed # oops let's come back to the feed element for a while This should be rarely used as long as you create your atom document sequentially. Atomix also holds the namespace prefix used for XHTML input. By default it falls back to '' so that you do not need to specify the namespace prefix at all. But if you need to set a specific one simply do this: atom = create_feed() atom.xhtmlprefix = 'xhtml' atom.add_entry() atom.add_content('yeah', target='inlineXHTML') """ def __init__(self, atom, encoding=ENCODING): """ initialize an Atomix instance Keyword arguments: atom -- an amara bindery instance encoding -- the encoding used throughout the XML document """ self.doc = atom self.encoding = encoding self.xhtmlprefix = '' try: self.cursor = self.doc.feed except: self.cursor = self.doc.entry def __str__(self): """ return an unindented version of the XML document as a string """ return self.doc.xml(encoding=self.encoding) def xml(self, indent='no'): """ return the atom document as a string Keyword arguments: indent -- specifies whether or not the result should be indented """ return self.doc.xml(indent=indent, encoding=self.encoding) def add_entry(self): """ insert an atom:entry element into the Atom document it will set the internal cursor to the newly created entry. """ self.doc.feed.xml_append(self.doc.xml_create_element(u"atom:entry", ns=ATOM10_NS)) self.cursor = self.doc.feed.entry[-1] def add_id(self, uri): """ insert an atom:id element into the Atom document Keyword arguments: uri -- the id value as an URI """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:id", ns=ATOM10_NS)) self.cursor.id = uri def add_author(self, name, email=None, uri=None): """ insert an atom:author element into the Atom document Keyword arguments: name -- the name of the author email -- the email of the author, appended only if provided uri -- the uri of the author, appended only if provided """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:author", ns=ATOM10_NS)) construct_person(self.doc, self.cursor.author[-1], name, email, uri) def add_category(self, term, scheme=None, label=None): """ insert an atom:category element into the Atom document Keyword arguments: term -- the term defining the category scheme -- appended only if provided label -- a friendly user label of the category, appended only if provided """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:category", ns=ATOM10_NS)) add_attribute(self.cursor.category[-1], u'term', term) add_attribute(self.cursor.category[-1], u'scheme', scheme) add_attribute(self.cursor.category[-1], u'label', label) def add_contributor(self, name, email=None, uri=None): """ insert an atom:contributor element into the Atom document Keyword arguments: name -- the name of the author email -- the email of the author, appended only if provided uri -- the uri of the author, appended only if provided """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:contributor", ns=ATOM10_NS)) construct_person(self.doc, self.cursor.contributor[-1], name, email, uri) def add_generator(self, value=GENERATOR_NAME, uri=None, version=None): """ insert an atom:generator element into the Atom document Keyword arguments: value -- the representation as a string of the generator uri -- the uri of the author, appended only if provided version -- the version of the generator """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:generator", ns=ATOM10_NS)) self.cursor.generator[-1] = value add_attribute(self.cursor.generator[-1], u'uri', uri) if value == GENERATOR_NAME and version == None: # automatically add this module's version add_attribute(self.cursor[-1], u'version', __version__) else: add_attribute(self.cursor[-1], u'version', version) def add_icon(self, uri): """ insert an atom:icon element into the Atom document Keyword arguments: uri -- the uri of the author, appended only if provided """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:icon", ns=ATOM10_NS)) self.cursor.icon[-1] = uri def add_title(self, title, mediaType='text'): """ insert an atom:title element into the Atom document Keyword arguments: title -- title value to be added mediaType -- media type used for the title (text, html or xhtml) """ self.cursor.xml_append(self.doc.xml_create_element(u'atom:title', ns=ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor.title[-1], title, self.encoding, self.xhtmlprefix) def add_updated(self, isoDate=None): """ insert an atom:updated element into the Atom document Keyword arguments: isoDate -- value of the date respecting ISO 8601 format """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:updated", ns=ATOM10_NS)) construct_date(self.cursor.updated[-1], isoDate) def add_published(self, isoDate=None): """ insert an atom:published element into the Atom document Keyword arguments: isoDate -- value of the date respecting ISO 8601 format """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:published", ns=ATOM10_NS)) construct_date(self.cursor.published[-1], isoDate) def add_link(self, href, rel=None, mediaType=None, hreflang=None, title=None, length=None, uri=None): """ insert an atom:link element into the Atom document Keyword arguments: href -- the URI of the link rel -- the type of the link mediaType -- the media type of the link hreflang -- the language of the link title -- a lable for the link length -- the length of the resource targeted by the URI uri -- if no rel provided, one must provide the uri """ self.cursor.xml_append(self.doc.xml_create_element(u"atom:link", ns=ATOM10_NS)) add_attribute(self.cursor.link[-1], u'href', href) if rel: add_attribute(self.cursor.link[-1], u'rel', rel) elif uri: add_attribute(self.cursor.link[-1], u'uri', uri) add_attribute(self.cursor.link[-1], u'type', mediaType) add_attribute(self.cursor.link[-1], u'hreflang', hreflang) add_attribute(self.cursor.link[-1], u'title', title) add_attribute(self.cursor.link[-1], u'length', length) def add_logo(self, uri): """ insert an atom:logo element into the Atom document Keyword arguments: uri -- the uri of the author, appended only if provided """ self.cursor.xml_append(self.doc.xml_create_element(u'atom:logo', ns=ATOM10_NS)) self.cursor.logo[-1] = uri def add_rights(self, text, mediaType=u'text'): """ insert an atom:rights element into the Atom document Keyword arguments: text -- rights value to be added mediaType -- media type used for the rights (text, html or xhtml) """ self.cursor.xml_append(self.doc.xml_create_element(u'atom:rights', ns=ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor.rights[-1], text, self.encoding, self.xhtmlprefix) def add_subtitle(self, text, mediaType=u'text'): """ insert an atom:subtitle element into the Atom document Keyword arguments: text -- subtitle value to be added mediaType -- media type used for the subtitle (text, html or xhtml) """ self.cursor.xml_append(self.doc.xml_create_element(u'atom:subtitle', ns=ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor.subtitle[-1], text, self.encoding, self.xhtmlprefix) def add_summary(self, text, mediaType=u'text'): """ insert an atom:summary element into the Atom document Keyword arguments: text -- summary to be added mediaType -- media type used for the summary (text, html or xhtml) """ self.cursor.xml_append(self.doc.xml_create_element(u'atom:summary', ns=ATOM10_NS)) _text_construct_mapper[mediaType](self.cursor.summary[-1], text, self.encoding, self.xhtmlprefix) def add_content(self, text='', target='inlineText', src=None): """ insert an atom:content element into the Atom document Keyword arguments: text -- the actual content target -- the type of content src -- the source of the actual content """ self.cursor.xml_append(self.doc.xml_create_element(u'atom:content', ns=ATOM10_NS)) if target in ['inlineText', 'inlineOther']: construct_plain_text(self.cursor.content[-1], text, self.encoding) elif target == 'inlineXHTML': construct_xhtml_text(self.cursor.content[-1], text, self.encoding, self.xhtmlprefix) elif target == 'inlineHTML': construct_html_text(self.cursor.content[-1], text, self.encoding) elif target == 'outOfLine': construct_out_of_line_content(self.cursor.content[-1], text, src, self.encoding) ############################################# # Helper internal functions # Private API ############################################# def construct_person(doc, node, name, email=None, uri=None): node.xml_append(doc.xml_create_element(u"atom:name", ns=ATOM10_NS)) node.name = name if email: node.xml_append(doc.xml_create_element(u"atom:email", ns=ATOM10_NS)) node.email = email if uri: node.xml_append(doc.xml_create_element(u"atom:uri", ns=ATOM10_NS)) node.uri = uri def construct_plain_text(node, text, encoding, unused=None): node.xml_set_attribute(u'type', u'text') node.xml_children.append(text) def construct_html_text(node, html, encoding, unused=None): node.xml_set_attribute(u'type', u'html') node.xml_children.append(html) def construct_xhtml_text(node, xhtml, encoding, xhtmlprefix): node.xml_set_attribute(u'type', u'xhtml') if xhtmlprefix: node.xml_append_fragment('<%s:div xmlns:%s="%s">%s' % (xhtmlprefix, xhtmlprefix, XHTML1_NS_STR, xhtml, xhtmlprefix), encoding=encoding) else: node.xml_append_fragment('
%s
' % (xhtml, ), encoding=encoding) def construct_out_of_line_content(node, text, mediaType, src, encoding): node.xml_set_attribute(u'type', mediaType) node.xml_set_attribute(u'src', src) node.xml_children.append(text) def get_isodate(): """ returns a date respecting ISO 8601 format """ import datetime return unicode(datetime.datetime.utcnow().isoformat() + 'Z') def construct_date(node, isoDate=None): if not isoDate: isoDate = get_isodate() node.xml_children.append(isoDate) def add_attribute(node, name, value): if value: node.xml_set_attribute(name, value) _text_construct_mapper = { u'text': construct_plain_text, u'html': construct_html_text, u'xhtml': construct_xhtml_text } atomixlib-0.4.0/atomixlib/__init__.py0000644000175000001440000000005610440626227017214 0ustar sylvainusers#!/usr/bin/env python # -*- coding: utf-8 -*-