python-feedgen/feedgen/ext/media.py
Lars Kiesow 8487af298e
Add Media RSS to RSS
This patch adds the necessary RSS extension to ensure that added Media
RSS elements end up in the resulting RSS XML.

Part of #58
2017-05-21 23:55:49 +02:00

179 lines
7.9 KiB
Python

# -*- coding: utf-8 -*-
'''
feedgen.ext.media
~~~~~~~~~~~~~~~~~~~~~~~~~
Extends the feedgen to produce media tags.
:copyright: 2013-2017, Lars Kiesow <lkiesow@uos.de>
:license: FreeBSD and LGPL, see license.* for more details.
'''
from lxml import etree
from feedgen.ext.base import BaseExtension, BaseEntryExtension
MEDIA_NS = 'http://search.yahoo.com/mrss/'
class MediaExtension(BaseExtension):
'''FeedGenerator extension for torrent feeds.
'''
def extend_ns(self):
return {'media': MEDIA_NS}
class MediaEntryExtension(BaseEntryExtension):
'''FeedEntry extension for media tags.
'''
def __init__(self):
self.__media_content = []
self.__media_thumbnail = None
def extend_atom(self, entry):
'''Add additional fields to an RSS item.
:param feed: The RSS item XML element to use.
'''
group = etree.SubElement(entry, '{%s}group' % MEDIA_NS)
if self.__media_content:
content = etree.SubElement(group, '{%s}content' % MEDIA_NS)
if self.__media_content.get('url'):
content.set('url', self.__media_content.get('url'))
if self.__media_content.get('fileSize'):
content.set('fileSize', self.__media_content.get('fileSize'))
if self.__media_content.get('type'):
content.set('type', self.__media_content.get('type'))
if self.__media_content.get('medium'):
content.set('medium', self.__media_content.get('medium'))
if self.__media_content.get('isDefault'):
content.set('isDefault', self.__media_content.get('isDefault'))
if self.__media_content.get('expression'):
content.set(
'expression', self.__media_content.get('expression'))
if self.__media_content.get('bitrate'):
content.set('bitrate', self.__media_content.get('bitrate'))
if self.__media_content.get('framerate'):
content.set('framerate', self.__media_content.get('framerate'))
if self.__media_content.get('samplingrate'):
content.set('samplingrate',
self.__media_content.get('samplingrate'))
if self.__media_content.get('channels'):
content.set('channels', self.__media_content.get('channels'))
if self.__media_content.get('duration'):
content.set('duration', self.__media_content.get('duration'))
if self.__media_content.get('height'):
content.set('height', self.__media_content.get('height'))
if self.__media_content.get('width'):
content.set('width', self.__media_content.get('width'))
if self.__media_content.get('lang'):
content.set('lang', self.__media_content.get('lang'))
if self.__media_thumbnail:
thumbnail = etree.SubElement(group, '{%s}thumbnail' % MEDIA_NS)
if self.__media_thumbnail.get('url'):
thumbnail.set('url', self.__media_thumbnail.get('url'))
if self.__media_thumbnail.get('height'):
thumbnail.set('height', self.__media_thumbnail.get('height'))
if self.__media_thumbnail.get('width'):
thumbnail.set('width', self.__media_thumbnail.get('width'))
if self.__media_thumbnail.get('lang'):
thumbnail.set('lang', self.__media_thumbnail.get('lang'))
return entry
def extend_rss(self, item):
return self.extend_atom(item)
def media_content(self, url=None, fileSize=None, type=None, medium=None,
isDefault=None, expression=None, bitrate=None,
framerate=None, samplingrate=None, channels=None,
duration=None, height=None, width=None, lang=None):
'''<media:content> is a sub-element of either <item> or <media:group>.
Media objects that are not the same content should not be included in
the same <media:group> element. The sequence of these items implies
the order of presentation. While many of the attributes appear to be
audio/video specific, this element can be used to publish any type
of media. It contains 14 attributes, most of which are optional.
:param url: should specify the direct URL to the media object.
:param fileSize: number of bytes of the media object.
:param type: standard MIME type of the object.
:param medium: type of object
(image | audio | video | document | executable).
:param isDefault: determines if this is the default object.
:param expression: determines if the object is a sample or the full
version of the object, or even if it is a
continuous stream (sample | full | nonstop).
:param bitrate: kilobits per second rate of media.
:param framerate: number of frames per second for the media object.
:param samplingrate: number of samples per second taken to create the
media object. It is expressed in thousands of
samples per second (kHz).
:param channels: number of audio channels in the media object.
:param duration: number of seconds the media object plays.
:param height: height of the media object.
:param width: width of the media object.
:param lang: is the primary language encapsulated in the media object.
:returns: The media content tag.
'''
if url is not None:
self.__media_content = {'url': url}
if fileSize is not None:
self.__media_content['fileSize'] = fileSize
if type is not None:
self.__media_content['type'] = type
if medium is not None:
self.__media_content['medium'] = medium
if isDefault is not None:
self.__media_content['isDefault'] = isDefault
if expression is not None:
self.__media_content['expression'] = expression
if bitrate is not None:
self.__media_content['bitrate'] = bitrate
if framerate is not None:
self.__media_content['framerate'] = framerate
if samplingrate is not None:
self.__media_content['samplingrate'] = samplingrate
if channels is not None:
self.__media_content['channels'] = channels
if duration is not None:
self.__media_content['duration'] = duration
if height is not None:
self.__media_content['height'] = height
if width is not None:
self.__media_content['width'] = width
if lang is not None:
self.__media_content['lang'] = lang
return self.__media_content
def media_thumbnail(self, url=None, height=None, width=None, time=None):
'''Allows particular images to be used as representative images for
the media object. If multiple thumbnails are included, and time
coding is not at play, it is assumed that the images are in order
of importance. It has one required attribute and three optional
attributes.
:param url: should specify the direct URL to the media object.
:param height: height of the media object.
:param width: width of the media object.
:param time: specifies the time offset in relation to the media object.
:returns: The media thumbnail tag.
'''
if url is not None:
self.__media_thumbnail = {'url': url}
if height is not None:
self.__media_thumbnail['height'] = height
if width is not None:
self.__media_thumbnail['width'] = width
if time is not None:
self.__media_thumbnail['time'] = time
return self.__media_thumbnail