atomixlib-0.4.0/ 0000755 0001750 0000144 00000000000 10440626227 013112 5 ustar sylvain users atomixlib-0.4.0/__init__.py 0000644 0001750 0000144 00000003702 10440626202 015216 0 ustar sylvain users #!/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-INFO 0000644 0001750 0000144 00000001404 10440626202 014177 0 ustar sylvain users Metadata-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 :: XML atomixlib-0.4.0/setup.py 0000644 0001750 0000144 00000001557 10440626202 014625 0 ustar sylvain users """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/ 0000755 0001750 0000144 00000000000 10440626237 014072 5 ustar sylvain users atomixlib-0.4.0/test/test_amara.py 0000644 0001750 0000144 00000004752 10440626220 016564 0 ustar sylvain users #!/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.py 0000644 0001750 0000144 00000004646 10440626220 020016 0 ustar sylvain users #!/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-idhello 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/ 0000755 0001750 0000144 00000000000 10440626255 015103 5 ustar sylvain users atomixlib-0.4.0/atomixlib/ax_elementtree.py 0000644 0001750 0000144 00000036426 10440626227 020470 0 ustar sylvain users #!/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%s:div>' %
#(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.py 0000644 0001750 0000144 00000036665 10440626227 017245 0 ustar sylvain users #!/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%s:div>' %
(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__.py 0000644 0001750 0000144 00000000056 10440626227 017214 0 ustar sylvain users #!/usr/bin/env python
# -*- coding: utf-8 -*-