예제 #1
0
    def extend_atom(self, entry):
        '''Add additional fields to an RSS item.

        :param feed: The RSS item XML element to use.
        '''

        groups = {None: entry}
        for media_content in self.__media_content:
            # Define current media:group
            group = groups.get(media_content.get('group'))
            if group is None:
                group = xml_elem('{%s}group' % MEDIA_NS, entry)
                groups[media_content.get('group')] = group
            # Add content
            content = xml_elem('{%s}content' % MEDIA_NS, group)
            for attr in ('url', 'fileSize', 'type', 'medium', 'isDefault',
                         'expression', 'bitrate', 'framerate', 'samplingrate',
                         'channels', 'duration', 'height', 'width', 'lang'):
                if media_content.get(attr):
                    content.set(attr, media_content[attr])

        for media_thumbnail in self.__media_thumbnail:
            # Define current media:group
            group = groups.get(media_thumbnail.get('group'))
            if group is None:
                group = xml_elem('{%s}group' % MEDIA_NS, entry)
                groups[media_thumbnail.get('group')] = group
            # Add thumbnails
            thumbnail = xml_elem('{%s}thumbnail' % MEDIA_NS, group)
            for attr in ('url', 'height', 'width', 'time'):
                if media_thumbnail.get(attr):
                    thumbnail.set(attr, media_thumbnail[attr])

        return entry
예제 #2
0
    def extend_file(self, entry):
        '''Add additional fields to an RSS item.

        :param feed: The RSS item XML element to use.
        '''

        GEO_NS = 'http://www.georss.org/georss'

        if self.__point:
            point = xml_elem('{%s}point' % GEO_NS, entry)
            point.text = self.__point

        if self.__line:
            line = xml_elem('{%s}line' % GEO_NS, entry)
            line.text = self.__line

        if self.__polygon:
            polygon = xml_elem('{%s}polygon' % GEO_NS, entry)
            polygon.text = self.__polygon

        if self.__box:
            box = xml_elem('{%s}box' % GEO_NS, entry)
            box.text = self.__box

        if self.__featuretypetag:
            featuretypetag = xml_elem('{%s}featuretypetag' % GEO_NS, entry)
            featuretypetag.text = self.__featuretypetag

        if self.__relationshiptag:
            relationshiptag = xml_elem('{%s}relationshiptag' % GEO_NS, entry)
            relationshiptag.text = self.__relationshiptag

        if self.__featurename:
            featurename = xml_elem('{%s}featurename' % GEO_NS, entry)
            featurename.text = self.__featurename

        if self.__elev:
            elevation = xml_elem('{%s}elev' % GEO_NS, entry)
            elevation.text = str(self.__elev)

        if self.__floor:
            floor = xml_elem('{%s}floor' % GEO_NS, entry)
            floor.text = str(self.__floor)

        if self.__radius:
            radius = xml_elem('{%s}radius' % GEO_NS, entry)
            radius.text = str(self.__radius)

        return entry
예제 #3
0
def _add_text_elm(entry, data, name):
    """Add a text subelement to an entry"""
    if not data:
        return

    elm = xml_elem(name, entry)
    type_ = data.get('type')
    if data.get('src'):
        if name != 'content':
            raise ValueError("Only the 'content' element of an entry can "
                             "contain a 'src' attribute")
        elm.attrib['src'] = data['src']
    elif data.get(name):
        # Surround xhtml with a div tag, parse it and embed it
        if type_ == 'xhtml':
            xhtml = '<div xmlns="http://www.w3.org/1999/xhtml">' \
                    + data.get(name) + '</div>'
            elm.append(xml_fromstring(xhtml))
        elif type_ == 'CDATA':
            elm.text = CDATA(data.get(name))
        # Parse XML and embed it
        elif type_ and (type_.endswith('/xml') or type_.endswith('+xml')):
            elm.append(xml_fromstring(data[name]))
        # Embed the text in escaped form
        elif not type_ or type_.startswith('text') or type_ == 'html':
            elm.text = data.get(name)
        # Everything else should be included base64 encoded
        else:
            raise NotImplementedError(
                'base64 encoded {} is not supported at the moment. '
                'Pull requests adding support are welcome.'.format(name)
            )
    # Add type description of the content
    if type_:
        elm.attrib['type'] = type_
예제 #4
0
    def extend_rss(self, entry):
        '''Add additional fields to an RSS item.

        :param feed: The RSS item XML element to use.
        '''
        if self.__torrent_filename:
            filename = xml_elem('{%s}filename' % TORRENT_NS, entry)
            filename.text = self.__torrent_filename

        if self.__torrent_contentlength:
            contentlength = xml_elem('{%s}contentlength' % TORRENT_NS, entry)
            contentlength.text = self.__torrent_contentlength

        if self.__torrent_infohash:
            infohash = xml_elem('{%s}infohash' % TORRENT_NS, entry)
            infohash.text = self.__torrent_infohash
            magnet = xml_elem('{%s}magneturi' % TORRENT_NS, entry)
            magnet.text = 'magnet:?xt=urn:btih:' + self.__torrent_infohash

        if self.__torrent_seeds:
            seeds = xml_elem('{%s}seed' % TORRENT_NS, entry)
            seeds.text = self.__torrent_seeds

        if self.__torrent_peers:
            peers = xml_elem('{%s}peers' % TORRENT_NS, entry)
            peers.text = self.__torrent_peers

        if self.__torrent_verified:
            verified = xml_elem('{%s}verified' % TORRENT_NS, entry)
            verified.text = self.__torrent_verified
    def extend_rss(self, entry):
        '''Add additional fields to an RSS item.

        :param feed: The RSS item XML element to use.
        '''
        ITUNES_NS = 'http://www.itunes.com/dtds/podcast-1.0.dtd'

        if self.__itunes_author:
            author = xml_elem('{%s}author' % ITUNES_NS, entry)
            author.text = self.__itunes_author

        if self.__itunes_block is not None:
            block = xml_elem('{%s}block' % ITUNES_NS, entry)
            block.text = 'yes' if self.__itunes_block else 'no'

        if self.__itunes_image:
            image = xml_elem('{%s}image' % ITUNES_NS, entry)
            image.attrib['href'] = self.__itunes_image

        if self.__itunes_duration:
            duration = xml_elem('{%s}duration' % ITUNES_NS, entry)
            duration.text = self.__itunes_duration

        if self.__itunes_explicit in ('yes', 'no', 'clean'):
            explicit = xml_elem('{%s}explicit' % ITUNES_NS, entry)
            explicit.text = self.__itunes_explicit

        if self.__itunes_is_closed_captioned is not None:
            is_closed_captioned = xml_elem('{%s}isClosedCaptioned' % ITUNES_NS,
                                           entry)
            if self.__itunes_is_closed_captioned:
                is_closed_captioned.text = 'yes'
            else:
                is_closed_captioned.text = 'no'

        if self.__itunes_order is not None and self.__itunes_order >= 0:
            order = xml_elem('{%s}order' % ITUNES_NS, entry)
            order.text = str(self.__itunes_order)

        if self.__itunes_subtitle:
            subtitle = xml_elem('{%s}subtitle' % ITUNES_NS, entry)
            subtitle.text = self.__itunes_subtitle

        if self.__itunes_summary:
            summary = xml_elem('{%s}summary' % ITUNES_NS, entry)
            summary.text = self.__itunes_summary
        return entry
예제 #6
0
    def _extend_xml(self, xml_element):
        '''Extend xml_element with set DC fields.

        :param xml_element: etree element
        '''
        DCELEMENTS_NS = 'http://purl.org/dc/elements/1.1/'

        for elem in ['contributor', 'coverage', 'creator', 'date',
                     'description', 'language', 'publisher', 'relation',
                     'rights', 'source', 'subject', 'title', 'type', 'format',
                     'identifier']:
            if hasattr(self, '_dcelem_%s' % elem):
                for val in getattr(self, '_dcelem_%s' % elem) or []:
                    node = xml_elem('{%s}%s' % (DCELEMENTS_NS, elem),
                                    xml_element)
                    node.text = val
예제 #7
0
def _set_value(channel, name, value):
    if value:
        newelem = xml_elem('{%s}' % SYNDICATION_NS + name, channel)
        newelem.text = value
예제 #8
0
    def _create_atom(self, extensions=True):
        '''Create a ATOM feed xml structure containing all previously set
        fields.

        :returns: Tuple containing the feed root element and the element tree.
        '''
        nsmap = dict()
        if extensions:
            for ext in self.__extensions.values() or []:
                if ext.get('atom'):
                    nsmap.update(ext['inst'].extend_ns())

        feed = xml_elem('feed',
                        xmlns='http://www.w3.org/2005/Atom',
                        nsmap=nsmap)
        if self.__atom_feed_xml_lang:
            feed.attrib['{http://www.w3.org/XML/1998/namespace}lang'] = \
                    self.__atom_feed_xml_lang

        if not (self.__atom_id and self.__atom_title and self.__atom_updated):
            missing = ([] if self.__atom_title else ['title']) + \
                      ([] if self.__atom_id else ['id']) + \
                      ([] if self.__atom_updated else ['updated'])
            missing = ', '.join(missing)
            raise ValueError('Required fields not set (%s)' % missing)
        id = xml_elem('id', feed)
        id.text = self.__atom_id
        title = xml_elem('title', feed)
        title.text = self.__atom_title
        updated = xml_elem('updated', feed)
        updated.text = self.__atom_updated.isoformat()

        # Add author elements
        for a in self.__atom_author or []:
            # Atom requires a name. Skip elements without.
            if not a.get('name'):
                continue
            author = xml_elem('author', feed)
            name = xml_elem('name', author)
            name.text = a.get('name')
            if a.get('email'):
                email = xml_elem('email', author)
                email.text = a.get('email')
            if a.get('uri'):
                uri = xml_elem('uri', author)
                uri.text = a.get('uri')

        for l in self.__atom_link or []:
            link = xml_elem('link', feed, href=l['href'])
            if l.get('rel'):
                link.attrib['rel'] = l['rel']
            if l.get('type'):
                link.attrib['type'] = l['type']
            if l.get('hreflang'):
                link.attrib['hreflang'] = l['hreflang']
            if l.get('title'):
                link.attrib['title'] = l['title']
            if l.get('length'):
                link.attrib['length'] = l['length']

        for c in self.__atom_category or []:
            cat = xml_elem('category', feed, term=c['term'])
            if c.get('scheme'):
                cat.attrib['scheme'] = c['scheme']
            if c.get('label'):
                cat.attrib['label'] = c['label']

        # Add author elements
        for c in self.__atom_contributor or []:
            # Atom requires a name. Skip elements without.
            if not c.get('name'):
                continue
            contrib = xml_elem('contributor', feed)
            name = xml_elem('name', contrib)
            name.text = c.get('name')
            if c.get('email'):
                email = xml_elem('email', contrib)
                email.text = c.get('email')
            if c.get('uri'):
                uri = xml_elem('uri', contrib)
                uri.text = c.get('uri')

        if self.__atom_generator and self.__atom_generator.get('value'):
            generator = xml_elem('generator', feed)
            generator.text = self.__atom_generator['value']
            if self.__atom_generator.get('uri'):
                generator.attrib['uri'] = self.__atom_generator['uri']
            if self.__atom_generator.get('version'):
                generator.attrib['version'] = self.__atom_generator['version']

        if self.__atom_icon:
            icon = xml_elem('icon', feed)
            icon.text = self.__atom_icon

        if self.__atom_logo:
            logo = xml_elem('logo', feed)
            logo.text = self.__atom_logo

        if self.__atom_rights:
            rights = xml_elem('rights', feed)
            rights.text = self.__atom_rights

        if self.__atom_subtitle:
            subtitle = xml_elem('subtitle', feed)
            subtitle.text = self.__atom_subtitle

        if extensions:
            for ext in self.__extensions.values() or []:
                if ext.get('atom'):
                    ext['inst'].extend_atom(feed)

        for entry in self.__feed_entries:
            entry = entry.atom_entry()
            feed.append(entry)

        doc = etree.ElementTree(feed)
        return feed, doc
예제 #9
0
    def _create_rss(self, extensions=True):
        '''Create an RSS feed xml structure containing all previously set
        fields.

        :returns: Tuple containing the feed root element and the element tree.
        '''
        nsmap = dict()
        if extensions:
            for ext in self.__extensions.values() or []:
                if ext.get('rss'):
                    nsmap.update(ext['inst'].extend_ns())

        nsmap.update({
            'atom': 'http://www.w3.org/2005/Atom',
            'content': 'http://purl.org/rss/1.0/modules/content/'
        })

        feed = xml_elem('rss', version='2.0', nsmap=nsmap)
        channel = xml_elem('channel', feed)
        if not (self.__rss_title and self.__rss_link
                and self.__rss_description):
            missing = ([] if self.__rss_title else ['title']) + \
                      ([] if self.__rss_link else ['link']) + \
                      ([] if self.__rss_description else ['description'])
            missing = ', '.join(missing)
            raise ValueError('Required fields not set (%s)' % missing)
        title = xml_elem('title', channel)
        title.text = self.__rss_title
        link = xml_elem('link', channel)
        link.text = self.__rss_link
        desc = xml_elem('description', channel)
        desc.text = self.__rss_description
        for ln in self.__atom_link or []:
            # It is recommended to include a atom self link in rss documents…
            if ln.get('rel') == 'self':
                selflink = xml_elem('{http://www.w3.org/2005/Atom}link',
                                    channel,
                                    href=ln['href'],
                                    rel='self')
                if ln.get('type'):
                    selflink.attrib['type'] = ln['type']
                if ln.get('hreflang'):
                    selflink.attrib['hreflang'] = ln['hreflang']
                if ln.get('title'):
                    selflink.attrib['title'] = ln['title']
                if ln.get('length'):
                    selflink.attrib['length'] = ln['length']
                break
        if self.__rss_category:
            for cat in self.__rss_category:
                category = xml_elem('category', channel)
                category.text = cat['value']
                if cat.get('domain'):
                    category.attrib['domain'] = cat['domain']
        if self.__rss_cloud:
            cloud = xml_elem('cloud', channel)
            cloud.attrib['domain'] = self.__rss_cloud.get('domain')
            cloud.attrib['port'] = self.__rss_cloud.get('port')
            cloud.attrib['path'] = self.__rss_cloud.get('path')
            cloud.attrib['registerProcedure'] = self.__rss_cloud.get(
                'registerProcedure')
            cloud.attrib['protocol'] = self.__rss_cloud.get('protocol')
        if self.__rss_copyright:
            copyright = xml_elem('copyright', channel)
            copyright.text = self.__rss_copyright
        if self.__rss_docs:
            docs = xml_elem('docs', channel)
            docs.text = self.__rss_docs
        if self.__rss_generator:
            generator = xml_elem('generator', channel)
            generator.text = self.__rss_generator
        if self.__rss_image:
            image = xml_elem('image', channel)
            url = xml_elem('url', image)
            url.text = self.__rss_image.get('url')
            title = xml_elem('title', image)
            title.text = self.__rss_image.get('title', self.__rss_title)
            link = xml_elem('link', image)
            link.text = self.__rss_image.get('link', self.__rss_link)
            if self.__rss_image.get('width'):
                width = xml_elem('width', image)
                width.text = self.__rss_image.get('width')
            if self.__rss_image.get('height'):
                height = xml_elem('height', image)
                height.text = self.__rss_image.get('height')
            if self.__rss_image.get('description'):
                description = xml_elem('description', image)
                description.text = self.__rss_image.get('description')
        if self.__rss_language:
            language = xml_elem('language', channel)
            language.text = self.__rss_language
        if self.__rss_lastBuildDate:
            lastBuildDate = xml_elem('lastBuildDate', channel)

            lastBuildDate.text = formatRFC2822(self.__rss_lastBuildDate)
        if self.__rss_managingEditor:
            managingEditor = xml_elem('managingEditor', channel)
            managingEditor.text = self.__rss_managingEditor
        if self.__rss_pubDate:
            pubDate = xml_elem('pubDate', channel)
            pubDate.text = formatRFC2822(self.__rss_pubDate)
        if self.__rss_rating:
            rating = xml_elem('rating', channel)
            rating.text = self.__rss_rating
        if self.__rss_skipHours:
            skipHours = xml_elem('skipHours', channel)
            for h in self.__rss_skipHours:
                hour = xml_elem('hour', skipHours)
                hour.text = str(h)
        if self.__rss_skipDays:
            skipDays = xml_elem('skipDays', channel)
            for d in self.__rss_skipDays:
                day = xml_elem('day', skipDays)
                day.text = d
        if self.__rss_textInput:
            textInput = xml_elem('textInput', channel)
            textInput.attrib['title'] = self.__rss_textInput.get('title')
            textInput.attrib['description'] = \
                self.__rss_textInput.get('description')
            textInput.attrib['name'] = self.__rss_textInput.get('name')
            textInput.attrib['link'] = self.__rss_textInput.get('link')
        if self.__rss_ttl:
            ttl = xml_elem('ttl', channel)
            ttl.text = str(self.__rss_ttl)
        if self.__rss_webMaster:
            webMaster = xml_elem('webMaster', channel)
            webMaster.text = self.__rss_webMaster

        if extensions:
            for ext in self.__extensions.values() or []:
                if ext.get('rss'):
                    ext['inst'].extend_rss(feed)

        for entry in self.__feed_entries:
            item = entry.rss_entry()
            channel.append(item)

        doc = etree.ElementTree(feed)
        return feed, doc
예제 #10
0
    def extend_rss(self, rss_feed):
        '''Extend an RSS feed root with set itunes fields.

        :returns: The feed root element.
        '''
        ITUNES_NS = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
        channel = rss_feed[0]

        if self.__itunes_author:
            author = xml_elem('{%s}author' % ITUNES_NS, channel)
            author.text = self.__itunes_author

        if self.__itunes_block is not None:
            block = xml_elem('{%s}block' % ITUNES_NS, channel)
            block.text = 'yes' if self.__itunes_block else 'no'

        for c in self.__itunes_category or []:
            if not c.get('cat'):
                continue
            category = channel.find(
                    '{%s}category[@text="%s"]' % (ITUNES_NS, c.get('cat')))
            if category is None:
                category = xml_elem('{%s}category' % ITUNES_NS, channel)
                category.attrib['text'] = c.get('cat')

            if c.get('sub'):
                subcategory = xml_elem('{%s}category' % ITUNES_NS, category)
                subcategory.attrib['text'] = c.get('sub')

        if self.__itunes_image:
            image = xml_elem('{%s}image' % ITUNES_NS, channel)
            image.attrib['href'] = self.__itunes_image

        if self.__itunes_explicit in ('yes', 'no', 'clean'):
            explicit = xml_elem('{%s}explicit' % ITUNES_NS, channel)
            explicit.text = self.__itunes_explicit

        if self.__itunes_complete in ('yes', 'no'):
            complete = xml_elem('{%s}complete' % ITUNES_NS, channel)
            complete.text = self.__itunes_complete

        if self.__itunes_new_feed_url:
            new_feed_url = xml_elem('{%s}new-feed-url' % ITUNES_NS, channel)
            new_feed_url.text = self.__itunes_new_feed_url

        if self.__itunes_owner:
            owner = xml_elem('{%s}owner' % ITUNES_NS, channel)
            owner_name = xml_elem('{%s}name' % ITUNES_NS, owner)
            owner_name.text = self.__itunes_owner.get('name')
            owner_email = xml_elem('{%s}email' % ITUNES_NS, owner)
            owner_email.text = self.__itunes_owner.get('email')

        if self.__itunes_subtitle:
            subtitle = xml_elem('{%s}subtitle' % ITUNES_NS, channel)
            subtitle.text = self.__itunes_subtitle

        if self.__itunes_summary:
            summary = xml_elem('{%s}summary' % ITUNES_NS, channel)
            summary.text = self.__itunes_summary

        if self.__itunes_type in ('episodic', 'serial'):
            type = xml_elem('{%s}type' % ITUNES_NS, channel)
            type.text = self.__itunes_type

        return rss_feed
예제 #11
0
    def rss_entry(self, extensions=True):
        '''Create a RSS item and return it.'''
        entry = xml_elem('item')
        if not (self.__rss_title or
                self.__rss_description or
                self.__rss_content):
            raise ValueError('Required fields not set')
        if self.__rss_title:
            title = xml_elem('title', entry)
            title.text = self.__rss_title
        if self.__rss_link:
            link = xml_elem('link', entry)
            link.text = self.__rss_link
        if self.__rss_description and self.__rss_content:
            description = xml_elem('description', entry)
            description.text = self.__rss_description
            XMLNS_CONTENT = 'http://purl.org/rss/1.0/modules/content/'
            content = xml_elem('{%s}encoded' % XMLNS_CONTENT, entry)
            content.text = CDATA(self.__rss_content['content']) \
                if self.__rss_content.get('type', '') == 'CDATA' \
                else self.__rss_content['content']
        elif self.__rss_description:
            description = xml_elem('description', entry)
            description.text = self.__rss_description
        elif self.__rss_content:
            description = xml_elem('description', entry)
            description.text = CDATA(self.__rss_content['content']) \
                if self.__rss_content.get('type', '') == 'CDATA' \
                else self.__rss_content['content']
        for a in self.__rss_author or []:
            author = xml_elem('author', entry)
            author.text = a
        if self.__rss_guid.get('guid'):
            guid = xml_elem('guid', entry)
            guid.text = self.__rss_guid['guid']
            permaLink = str(self.__rss_guid.get('permalink', False)).lower()
            guid.attrib['isPermaLink'] = permaLink
        for cat in self.__rss_category or []:
            category = xml_elem('category', entry)
            category.text = cat['value']
            if cat.get('domain'):
                category.attrib['domain'] = cat['domain']
        if self.__rss_comments:
            comments = xml_elem('comments', entry)
            comments.text = self.__rss_comments
        if self.__rss_enclosure:
            enclosure = xml_elem('enclosure', entry)
            enclosure.attrib['url'] = self.__rss_enclosure['url']
            enclosure.attrib['length'] = self.__rss_enclosure['length']
            enclosure.attrib['type'] = self.__rss_enclosure['type']
        if self.__rss_pubDate:
            pubDate = xml_elem('pubDate', entry)
            pubDate.text = formatRFC2822(self.__rss_pubDate)
        if self.__rss_source:
            source = xml_elem('source', entry, url=self.__rss_source['url'])
            source.text = self.__rss_source['title']

        if extensions:
            for ext in self.__extensions.values() or []:
                if ext.get('rss'):
                    ext['inst'].extend_rss(entry)

        return entry
예제 #12
0
    def atom_entry(self, extensions=True):
        '''Create an ATOM entry and return it.'''
        entry = xml_elem('entry')
        if not (self.__atom_id and self.__atom_title and self.__atom_updated):
            raise ValueError('Required fields not set')
        id = xml_elem('id', entry)
        id.text = self.__atom_id
        title = xml_elem('title', entry)
        title.text = self.__atom_title
        updated = xml_elem('updated', entry)
        updated.text = self.__atom_updated.isoformat()

        # An entry must contain an alternate link if there is no content
        # element.
        if not self.__atom_content:
            links = self.__atom_link or []
            if not [l for l in links if l.get('rel') == 'alternate']:
                raise ValueError('Entry must contain an alternate link or ' +
                                 'a content element.')

        # Add author elements
        for a in self.__atom_author or []:
            # Atom requires a name. Skip elements without.
            if not a.get('name'):
                continue
            author = xml_elem('author', entry)
            name = xml_elem('name', author)
            name.text = a.get('name')
            if a.get('email'):
                email = xml_elem('email', author)
                email.text = a.get('email')
            if a.get('uri'):
                uri = xml_elem('uri', author)
                uri.text = a.get('uri')

        _add_text_elm(entry, self.__atom_content, 'content')

        for l in self.__atom_link or []:
            link = xml_elem('link', entry, href=l['href'])
            if l.get('rel'):
                link.attrib['rel'] = l['rel']
            if l.get('type'):
                link.attrib['type'] = l['type']
            if l.get('hreflang'):
                link.attrib['hreflang'] = l['hreflang']
            if l.get('title'):
                link.attrib['title'] = l['title']
            if l.get('length'):
                link.attrib['length'] = l['length']

        _add_text_elm(entry, self.__atom_summary, 'summary')

        for c in self.__atom_category or []:
            cat = xml_elem('category', entry, term=c['term'])
            if c.get('scheme'):
                cat.attrib['scheme'] = c['scheme']
            if c.get('label'):
                cat.attrib['label'] = c['label']

        # Add author elements
        for c in self.__atom_contributor or []:
            # Atom requires a name. Skip elements without.
            if not c.get('name'):
                continue
            contrib = xml_elem('contributor', entry)
            name = xml_elem('name', contrib)
            name.text = c.get('name')
            if c.get('email'):
                email = xml_elem('email', contrib)
                email.text = c.get('email')
            if c.get('uri'):
                uri = xml_elem('uri', contrib)
                uri.text = c.get('uri')

        if self.__atom_published:
            published = xml_elem('published', entry)
            published.text = self.__atom_published.isoformat()

        if self.__atom_rights:
            rights = xml_elem('rights', entry)
            rights.text = self.__atom_rights

        if self.__atom_source:
            source = xml_elem('source', entry)
            if self.__atom_source.get('title'):
                source_title = xml_elem('title', source)
                source_title.text = self.__atom_source['title']
            if self.__atom_source.get('link'):
                xml_elem('link', source, href=self.__atom_source['link'])

        if extensions:
            for ext in self.__extensions.values() or []:
                if ext.get('atom'):
                    ext['inst'].extend_atom(entry)

        return entry