Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
'rss/channel/item/pubDate': EpisodeAttr('published', parse_pubdate),
'rss/channel/item/atom:link': AtomLink(),
'rss/channel/item/media:content': Enclosure('fileSize'),
'rss/channel/item/enclosure': Enclosure('length'),
'rss/channel/item/psc:chapters': PodloveChapters(),
'rss/channel/item/psc:chapters/psc:chapter': PodloveChapter(),
# Basic support for Atom feeds
'atom:feed': PodcastItem(),
'atom:feed/atom:title': PodcastAttr('title', squash_whitespace),
'atom:feed/atom:subtitle': PodcastAttr('description', squash_whitespace),
'atom:feed/atom:icon': PodcastAttrRelativeLink('cover_url'),
'atom:feed/atom:link': PodcastAtomLink(),
'atom:feed/atom:entry': EpisodeItem(),
'atom:feed/atom:entry/atom:id': EpisodeAttr('guid'),
'atom:feed/atom:entry/atom:title': EpisodeAttr('title', squash_whitespace),
'atom:feed/atom:entry/atom:link': AtomLink(),
'atom:feed/atom:entry/atom:content': AtomContent(),
'atom:feed/atom:entry/content:encoded': EpisodeAttr('description_html'),
'atom:feed/atom:entry/atom:published': EpisodeAttr('published', parse_pubdate),
'atom:feed/atom:entry/atom:updated': EpisodeAttr('published', parse_pubdate, overwrite=False),
'atom:feed/atom:entry/media:group/media:description': EpisodeAttr('description', squash_whitespace),
'atom:feed/atom:entry/psc:chapters': PodloveChapters(),
'atom:feed/atom:entry/psc:chapters/psc:chapter': PodloveChapter(),
}
# Derive valid root elements from the supported MAPPINGs
VALID_ROOTS = set(path.split('/')[0] for path in MAPPING.keys())
class FeedParseError(sax.SAXParseException, ValueError):
'rss/channel/item/psc:chapters/psc:chapter': PodloveChapter(),
# Basic support for Atom feeds
'atom:feed': PodcastItem(),
'atom:feed/atom:title': PodcastAttr('title', squash_whitespace),
'atom:feed/atom:subtitle': PodcastAttr('description', squash_whitespace),
'atom:feed/atom:icon': PodcastAttrRelativeLink('cover_url'),
'atom:feed/atom:link': PodcastAtomLink(),
'atom:feed/atom:entry': EpisodeItem(),
'atom:feed/atom:entry/atom:id': EpisodeAttr('guid'),
'atom:feed/atom:entry/atom:title': EpisodeAttr('title', squash_whitespace),
'atom:feed/atom:entry/atom:link': AtomLink(),
'atom:feed/atom:entry/atom:content': AtomContent(),
'atom:feed/atom:entry/content:encoded': EpisodeAttr('description_html'),
'atom:feed/atom:entry/atom:published': EpisodeAttr('published', parse_pubdate),
'atom:feed/atom:entry/atom:updated': EpisodeAttr('published', parse_pubdate, overwrite=False),
'atom:feed/atom:entry/media:group/media:description': EpisodeAttr('description', squash_whitespace),
'atom:feed/atom:entry/psc:chapters': PodloveChapters(),
'atom:feed/atom:entry/psc:chapters/psc:chapter': PodloveChapter(),
}
# Derive valid root elements from the supported MAPPINGs
VALID_ROOTS = set(path.split('/')[0] for path in MAPPING.keys())
class FeedParseError(sax.SAXParseException, ValueError):
"""
Exception raised when asked to parse an invalid feed
This exception allows users of this library to catch exceptions
without having to import the XML parsing library themselves.
"""
'rss/channel': PodcastItem(),
'rss/channel/title': PodcastAttr('title', squash_whitespace),
'rss/channel/link': PodcastAttrRelativeLink('link'),
'rss/channel/description': PodcastAttr('description', squash_whitespace),
'rss/channel/image/url': PodcastAttrRelativeLink('cover_url'),
'rss/channel/itunes:image': PodcastAttrFromHref('cover_url'),
'rss/channel/atom:link': PodcastAtomLink(),
'rss/channel/item': EpisodeItem(),
'rss/channel/item/guid': EpisodeGuid('guid'),
'rss/channel/item/title': EpisodeAttr('title', squash_whitespace),
'rss/channel/item/link': EpisodeAttrRelativeLink('link'),
'rss/channel/item/description': RSSItemDescription(),
'rss/channel/item/itunes:summary': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/media:description': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/itunes:subtitle': EpisodeAttr('subtitle', squash_whitespace),
'rss/channel/item/content:encoded': EpisodeAttr('description_html'),
'rss/channel/item/itunes:duration': EpisodeAttr('total_time', parse_time),
'rss/channel/item/pubDate': EpisodeAttr('published', parse_pubdate),
'rss/channel/item/atom:link': AtomLink(),
'rss/channel/item/media:content': Enclosure('fileSize'),
'rss/channel/item/enclosure': Enclosure('length'),
'rss/channel/item/psc:chapters': PodloveChapters(),
'rss/channel/item/psc:chapters/psc:chapter': PodloveChapter(),
# Basic support for Atom feeds
'atom:feed': PodcastItem(),
'atom:feed/atom:title': PodcastAttr('title', squash_whitespace),
'atom:feed/atom:subtitle': PodcastAttr('description', squash_whitespace),
'atom:feed/atom:icon': PodcastAttrRelativeLink('cover_url'),
'atom:feed/atom:link': PodcastAtomLink(),
handler.add_episode()
def end(self, handler, text):
handler.validate_episode()
class EpisodeAttr(Target):
WANT_TEXT = True
def end(self, handler, text):
if not self.overwrite and handler.get_episode_attr(self.key):
return
handler.set_episode_attr(self.key, self.filter_func(text))
class EpisodeAttrRelativeLink(EpisodeAttr):
def end(self, handler, text):
text = urlparse.urljoin(handler.base, text)
super(EpisodeAttrRelativeLink, self).end(handler, text)
class EpisodeGuid(EpisodeAttr):
def start(self, handler, attrs):
if attrs.get('isPermaLink', 'true').lower() == 'true':
handler.set_episode_attr('_guid_is_permalink', True)
else:
handler.set_episode_attr('_guid_is_permalink', False)
def end(self, handler, text):
def filter_func(guid):
guid = guid.strip()
if handler.get_episode_attr('_guid_is_permalink'):
class EpisodeAttr(Target):
WANT_TEXT = True
def end(self, handler, text):
if not self.overwrite and handler.get_episode_attr(self.key):
return
handler.set_episode_attr(self.key, self.filter_func(text))
class EpisodeAttrRelativeLink(EpisodeAttr):
def end(self, handler, text):
text = urlparse.urljoin(handler.base, text)
super(EpisodeAttrRelativeLink, self).end(handler, text)
class EpisodeGuid(EpisodeAttr):
def start(self, handler, attrs):
if attrs.get('isPermaLink', 'true').lower() == 'true':
handler.set_episode_attr('_guid_is_permalink', True)
else:
handler.set_episode_attr('_guid_is_permalink', False)
def end(self, handler, text):
def filter_func(guid):
guid = guid.strip()
if handler.get_episode_attr('_guid_is_permalink'):
return urlparse.urljoin(handler.base, guid)
return guid
self.filter_func = filter_func
EpisodeAttr.end(self, handler, text)
'rss/channel/link': PodcastAttrRelativeLink('link'),
'rss/channel/description': PodcastAttr('description', squash_whitespace),
'rss/channel/image/url': PodcastAttrRelativeLink('cover_url'),
'rss/channel/itunes:image': PodcastAttrFromHref('cover_url'),
'rss/channel/atom:link': PodcastAtomLink(),
'rss/channel/item': EpisodeItem(),
'rss/channel/item/guid': EpisodeGuid('guid'),
'rss/channel/item/title': EpisodeAttr('title', squash_whitespace),
'rss/channel/item/link': EpisodeAttrRelativeLink('link'),
'rss/channel/item/description': RSSItemDescription(),
'rss/channel/item/itunes:summary': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/media:description': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/itunes:subtitle': EpisodeAttr('subtitle', squash_whitespace),
'rss/channel/item/content:encoded': EpisodeAttr('description_html'),
'rss/channel/item/itunes:duration': EpisodeAttr('total_time', parse_time),
'rss/channel/item/pubDate': EpisodeAttr('published', parse_pubdate),
'rss/channel/item/atom:link': AtomLink(),
'rss/channel/item/media:content': Enclosure('fileSize'),
'rss/channel/item/enclosure': Enclosure('length'),
'rss/channel/item/psc:chapters': PodloveChapters(),
'rss/channel/item/psc:chapters/psc:chapter': PodloveChapter(),
# Basic support for Atom feeds
'atom:feed': PodcastItem(),
'atom:feed/atom:title': PodcastAttr('title', squash_whitespace),
'atom:feed/atom:subtitle': PodcastAttr('description', squash_whitespace),
'atom:feed/atom:icon': PodcastAttrRelativeLink('cover_url'),
'atom:feed/atom:link': PodcastAtomLink(),
'atom:feed/atom:entry': EpisodeItem(),
'atom:feed/atom:entry/atom:id': EpisodeAttr('guid'),
'rss/channel/title': PodcastAttr('title', squash_whitespace),
'rss/channel/link': PodcastAttrRelativeLink('link'),
'rss/channel/description': PodcastAttr('description', squash_whitespace),
'rss/channel/image/url': PodcastAttrRelativeLink('cover_url'),
'rss/channel/itunes:image': PodcastAttrFromHref('cover_url'),
'rss/channel/atom:link': PodcastAtomLink(),
'rss/channel/item': EpisodeItem(),
'rss/channel/item/guid': EpisodeGuid('guid'),
'rss/channel/item/title': EpisodeAttr('title', squash_whitespace),
'rss/channel/item/link': EpisodeAttrRelativeLink('link'),
'rss/channel/item/description': RSSItemDescription(),
'rss/channel/item/itunes:summary': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/media:description': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/itunes:subtitle': EpisodeAttr('subtitle', squash_whitespace),
'rss/channel/item/content:encoded': EpisodeAttr('description_html'),
'rss/channel/item/itunes:duration': EpisodeAttr('total_time', parse_time),
'rss/channel/item/pubDate': EpisodeAttr('published', parse_pubdate),
'rss/channel/item/atom:link': AtomLink(),
'rss/channel/item/media:content': Enclosure('fileSize'),
'rss/channel/item/enclosure': Enclosure('length'),
'rss/channel/item/psc:chapters': PodloveChapters(),
'rss/channel/item/psc:chapters/psc:chapter': PodloveChapter(),
# Basic support for Atom feeds
'atom:feed': PodcastItem(),
'atom:feed/atom:title': PodcastAttr('title', squash_whitespace),
'atom:feed/atom:subtitle': PodcastAttr('description', squash_whitespace),
'atom:feed/atom:icon': PodcastAttrRelativeLink('cover_url'),
'atom:feed/atom:link': PodcastAtomLink(),
'atom:feed/atom:entry': EpisodeItem(),
'rss': RSS(),
'rss/channel': PodcastItem(),
'rss/channel/title': PodcastAttr('title', squash_whitespace),
'rss/channel/link': PodcastAttrRelativeLink('link'),
'rss/channel/description': PodcastAttr('description', squash_whitespace),
'rss/channel/image/url': PodcastAttrRelativeLink('cover_url'),
'rss/channel/itunes:image': PodcastAttrFromHref('cover_url'),
'rss/channel/atom:link': PodcastAtomLink(),
'rss/channel/item': EpisodeItem(),
'rss/channel/item/guid': EpisodeGuid('guid'),
'rss/channel/item/title': EpisodeAttr('title', squash_whitespace),
'rss/channel/item/link': EpisodeAttrRelativeLink('link'),
'rss/channel/item/description': RSSItemDescription(),
'rss/channel/item/itunes:summary': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/media:description': EpisodeAttr('description', squash_whitespace),
'rss/channel/item/itunes:subtitle': EpisodeAttr('subtitle', squash_whitespace),
'rss/channel/item/content:encoded': EpisodeAttr('description_html'),
'rss/channel/item/itunes:duration': EpisodeAttr('total_time', parse_time),
'rss/channel/item/pubDate': EpisodeAttr('published', parse_pubdate),
'rss/channel/item/atom:link': AtomLink(),
'rss/channel/item/media:content': Enclosure('fileSize'),
'rss/channel/item/enclosure': Enclosure('length'),
'rss/channel/item/psc:chapters': PodloveChapters(),
'rss/channel/item/psc:chapters/psc:chapter': PodloveChapter(),
# Basic support for Atom feeds
'atom:feed': PodcastItem(),
'atom:feed/atom:title': PodcastAttr('title', squash_whitespace),
'atom:feed/atom:subtitle': PodcastAttr('description', squash_whitespace),
'atom:feed/atom:icon': PodcastAttrRelativeLink('cover_url'),