Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 66 additions & 2 deletions PyMediaRSS2Gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,14 @@ def __init__(
duration=None,
height=None,
width=None,
lang=None
lang=None,


media_thumbnails=None,
):
"""Create a media:content element, args will be attributes."""
self.media_thumbnails = media_thumbnails

self.element_attrs = OrderedDict()

self._add_attribute('url', url)
Expand Down Expand Up @@ -113,7 +118,16 @@ def _add_attribute(self, name, value, allowed_values=None):

def publish(self, handler):
"""Publish the MediaContent as XML."""
PyRSS2Gen._element(handler, "media:content", None, self.element_attrs)
handler.startElement("media:content", self.element_attrs)

if hasattr(self, 'media_thumbnails'):
if not isinstance(self.media_thumbnails, list):
self.media_thumbnails = [self.media_thumbnails]

for t in self.media_thumbnails:
PyRSS2Gen._opt_element(handler, "media:thumbnail", t)

handler.endElement("media:content")

def __repr__(self):
"""Return a nice string representation for prettier debugging."""
Expand Down Expand Up @@ -243,3 +257,53 @@ def publish_extensions(self, handler):

if hasattr(self, 'media_text'):
PyRSS2Gen._opt_element(handler, "media:text", self.media_text)

class MediaThumbnail(object):

"""Publish a Media Thumbnail Item."""

def __init__(
self,
url,
height=None,
width=None,
time=None # string in the NTP format - see http://www.rssboard.org/media-rss
):
"""Create a thumbnail element that contains args as attributes."""

self.element_attrs = OrderedDict()
self._add_attribute('url', url)
self._add_attribute('width', width)
self._add_attribute('height', height)
self._add_attribute('time', time)

self.check_complicance()

def _add_attribute(self, name, value):
"""Add an attribute to the MediaContent element."""
if value:
if isinstance(value, (int, bool)):
value = str(value)

self.element_attrs[name] = value

def check_complicance(self):
"""Check compliance with Media RSS Specification, Version 1.5.1.

see http://www.rssboard.org/media-rss
Raises AttributeError on error.
"""

if not self.element_attrs.get('url'):
raise AttributeError('thumbnail url must be specified')

if self.element_attrs.get('time'):
try:
parts = self.element_attrs['time'].split(':')
assert len(parts) == 3
except AssertionError:
raise AttributeError('time, if present, must be in the NTP format')

def publish(self, handler):
"""Publish the MediaThumbnail as XML."""
PyRSS2Gen._element(handler, "media:thumbnail", None, self.element_attrs)
17 changes: 17 additions & 0 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# coding=utf-8

""" fixtures """

import pytest
import PyMediaRSS2Gen as mrss

FEED_URL = 'http://nowhere.org/rss.xml'

@pytest.fixture
def feed():
""" fixture creating an empty feed """
return mrss.MediaRSS2(
title = 'Test Feed',
link = 'http://nowhere.org/nopost',
description = 'A testing feed'
)
31 changes: 31 additions & 0 deletions tests/test_content.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# coding=utf-8

"""
tests of MediaContent
"""

import pytest
import PyMediaRSS2Gen as mrss

from fixtures import *

class TestMediaContent(object):

def test_output(self, feed):
""" output of a basic content should look like this """

image = mrss.MediaContent(
type='image',
url='http://nowhere.org/img/hippo.jpg',
)
item = mrss.MediaRSSItem(
title="Item with thumbnail",
media_content=image
)
feed.items = [item]
output = feed.to_xml()

assert output.endswith(
'<media:content url="http://nowhere.org/img/hippo.jpg" type="image"></media:content>'+
'</item></channel></rss>'
)
43 changes: 43 additions & 0 deletions tests/test_mediarss2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# coding=utf-8

"""
tests of the main class -
MediaRSS2
"""

import pytest
import PyMediaRSS2Gen as mrss

from fixtures import *

class Test_EmptyFeed(object):

def test_toXML(self, feed):
""" it is possible to render an empty feed """
output = feed.to_xml()
assert output.startswith('<?xml')
assert '</channel>' in output
assert '<item>' not in output

@pytest.mark.xfail(reason='PyRSS2Gen ignores the attribute')
def test_hasNamespace(self, feed):
""" the feed defines the media module namespace """
output = feed.to_xml()
assert 'xmlns:media="http://search.yahoo.com/mrss/"' in output

class Test_Items(object):

def test_noMedia(self, feed):
"""
it is possible to have an item without media content
in a media-enabled feed

The test simply shouldn't throw an error
"""
feed.items = [
mrss.MediaRSSItem(
title="Item without media content",
description="It has no media content",
)
]
output = feed.to_xml()
67 changes: 67 additions & 0 deletions tests/test_thumbnail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# coding=utf-8

"""
tests of MediaThumbnail
"""

import pytest
import PyMediaRSS2Gen as mrss

from fixtures import *

@pytest.fixture
def itemWithThumbnail():
""" fixture creating an item with thumbnail """
thumb = mrss.MediaThumbnail(
url='http://nowhere.org/img/hippo_tn.jpg',
time='00:15:46',
width=150,
height=652
)
image = mrss.MediaContent(
type='image',
url='http://nowhere.org/img/hippo.jpg',
media_thumbnails=thumb
)
return mrss.MediaRSSItem(
title="Item with thumbnail",
media_content=image
)

class TestMediaThumbnail(object):

def test_withoutUrl(self):
""" url is required """
with pytest.raises(AttributeError):
mrss.MediaThumbnail(url=None)

def test_withoutTime(self):
""" is ok """
mrss.MediaThumbnail(url=FEED_URL)

def test_withInvalidTime(self):
""" time must be in the NTP format """
with pytest.raises(AttributeError):
mrss.MediaThumbnail(url=FEED_URL, time='notime')

def test_withValidTime(self):
""" is ok """
mrss.MediaThumbnail(url=FEED_URL, time='00:05:10')
mrss.MediaThumbnail(url=FEED_URL, time='00:05:10.5')

def test_XMLOutputContainsThumbnail(self, feed, itemWithThumbnail):
""" first output test: the thumbnail element must be in the output """
feed.items = [itemWithThumbnail]
output = feed.to_xml()
assert '<media:thumbnail' in output

def test_publishesCorrectly(self, feed, itemWithThumbnail):
""" the thumbnail element should be output with the desired argument order """
feed.items = [itemWithThumbnail]
output = feed.to_xml()

assert output.endswith(
'<media:thumbnail url="http://nowhere.org/img/hippo_tn.jpg" width="150" height="652" time="00:15:46"></media:thumbnail>' +
'</media:content>' +
'</item></channel></rss>'
)
9 changes: 9 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[tox]
envlist=py26,py27,py34

[testenv]
deps=
pytest
PyRSS2Gen

commands=py.test