Mopidy-Podcast

Mopidy-Podcast is a Mopidy extension for searching and browsing podcasts.

Mopidy-Podcast extends Mopidy’s browsing and searching capabilities to the podcasting domain by integrating podcasts and their episodes with Mopidy’s native data model. More specifically, podcasts are mapped to albums, while individual podcast episodes are shown as tracks in Mopidy. Podcast and episode metadata is retained and converted to Mopidy’s native types where applicable. An episode’s audio stream is then played using Mopidy’s streaming extension.

To use Mopidy-Podcast, you first have to configure how to find and access podcasts:

  • If you already have some favorite podcasts published as RSS feeds, you can subscribe to them by adding their feed URLs to podcast/feeds. RSS feeds will get updated on a regular basis, so you can always browse and search for the latest episodes.
  • You can also install one of several – well, actually two, at the time – Mopidy-Podcast Extensions, which let you access external podcast directory services such as the Apple iTunes Store.

Note that both methods can be combined, i.e. you can configure a list of your favorite RSS feeds for regular – and potentially faster – access, while also installing one or more extensions for exploring.

Installation

Mopidy-Podcast can be installed using pip by running:

pip install Mopidy-Podcast

Configuration

This section describes the configuration values that affect Mopidy-Podcast’s core functions and the bundled feeds directory provider. For configuring external extensions, please refer to their respective documentation.

General Configuration Values

podcast/browse_limit

The maximum number of browse results and podcast episodes to show.

podcast/search_limit

The maximum number of search results to show.

podcast/search_details

Whether to return fully detailed search results. If set to off (the default), only a podcast’s or episode’s name and URI will appear in search results, similar to what is shown when browsing. If set to on, search results will also include meta information such as author name, track counts and lengths, publication dates and images, if available. However, this will slow down searching tremendously, so if you enable this you might consider decreasing podcast/search_limit.

podcast/update_interval

The directory update interval in seconds, i.e. how often locally stored information should be refreshed.

Feeds Directory Configuration Values

This section lists configuration values specific to the feeds podcast directory provider that is bundled with Mopidy-Podcast. If you do not plan to use the feeds directory, these can be safely ignored.

podcast/feeds

A list of podcast RSS feed URLs to subscribe to. Individual URLs must be seperated by either newlines or commas, with newlines preferred.

To subscribe to some podcasts from NPR‘s highly recommended All Songs Considered program:

feeds =
    http://www.npr.org/rss/podcast.php?id=510019
    http://www.npr.org/rss/podcast.php?id=510253
    http://www.npr.org/rss/podcast.php?id=510306
podcast/feeds_root_name

The directory name shown for browsing subscribed feeds.

podcast/feeds_cache_size

The maximum number of podcast RSS feeds that should be cached.

podcast/feeds_cache_ttl

The feeds cache time to live, i.e. the number of seconds after which a cached feed expires and needs to be reloaded.

podcast/feeds_timeout

The HTTP request timeout when retrieving RSS feeds, in seconds.

Default Configuration

For reference, this is the default configuration shipped with Mopidy-Podcast release 1.1.0:

[podcast]
enabled = true

# maximum number of browse results
browse_limit = 100

# maximum number of search results
search_limit = 20

# whether to return fully detailed search results; if set to "off",
# only name and URI will be returned for increased performance
search_details = off

# directory update interval in seconds
update_interval = 86400

# an optional list of podcast RSS feed URLs to subscribe to; URLs need
# to be seperated by commas or newlines
feeds =

# user-friendly name for browsing subscribed RSS feeds
feeds_root_name = Subscribed Feeds

# number of RSS feeds to cache
feeds_cache_size = 32

# feeds cache time-to-live in seconds
feeds_cache_ttl = 3600

# HTTP request timeout in seconds
feeds_timeout = 10

Mopidy-Podcast Extensions

Here you can find a list of external packages that extend Mopidy-Podcast with additional functionality.

Mopidy-Podcast-iTunes

https://github.com/tkem/mopidy-podcast-itunes

Mopidy-Podcast-iTunes is a Mopidy-Podcast extension for searching and browsing podcasts on the Apple iTunes Store.

Mopidy-Podcast-gpodder.net

https://github.com/tkem/mopidy-podcast-gpodder

Mopidy-Podcast-gpodder.net is a Mopidy-Podcast extension for searching and browsing podcasts using the gpodder.net Web service.

Mopidy-Podcast API reference

Mopidy-Podcast extensions that wish to provide alternate podcast directory services need to subclass mopidy_podcast.directory.PodcastDirectory and install and configure it with a Mopidy extension. Directory subclasses need to be added to Mopidy’s registry with key podcast:directory, e.g.:

class MyPodcastExtension(ext.Extension):
    def setup(self, registry):
        registry.add('podcast:directory', MyPodcastDirectory)

Mopidy-Podcast Data Models

Mopidy-Podcast extends Mopidy’s data model by providing additional domain-specific types. These immutable data models are used for all data transfer between Mopidy-Podcast extensions and the Mopidy-Podcast core module. The intricacies of converting from/to Mopidy’s native data models are left to the Mopidy-Podcast module, so extension developers can work solely with domain objects.

These models are based on Apple’s – rather informal – podcast specification, which in turn is based on RSS 2.0.

class mopidy_podcast.models.Podcast(*args, **kwargs)

Mopidy model type to represent a podcast.

Parameters:
  • uri (string) – podcast URI
  • title (string) – podcast title
  • link (string) – Web site URI
  • copyright (string) – copyright notice
  • language (string) – ISO two-letter language code
  • pubdate (datetime.datetime) – publication date and time
  • author (string) – author name
  • block (boolean) – prevent the podcast from appearing
  • category (string) – main category
  • image (Image) – podcast image
  • explicit (boolean) – whether the podcast contains explicit material
  • complete (boolean) – whether the podcast is complete
  • newfeedurl (string) – new feed location
  • subtitle (string) – short description
  • summary (string) – long description
  • episodes (list of Episode) – podcast episodes
author = None

The podcast’s author’s name.

block = None

Prevent a podcast from appearing in the directory.

category = None

The main category of the podcast.

complete = None

Indicates completion of the podcast.

copyright = None

The podcast’s copyright notice.

episodes = ()

The podcast’s episodes as a read-only tuple of Episode instances.

explicit = None

Indicates whether the podcast contains explicit material.

image = None

An image to be displayed with the podcast as an instance of Image.

language = None

The podcast’s ISO two-letter language code.

The URL of the HTML website corresponding to the podcast.

newfeedurl = None

Used to inform of new feed URL location.

pubdate = None

The podcast’s publication date and time as an instance of datetime.datetime.

subtitle = None

A short description of the podcast.

summary = None

A description of the podcast, up to 4000 characters long.

title = None

The podcast’s title.

uri = None

The podcast URI.

For podcasts distributed as RSS feeds, the podcast URI is the URL from which the RSS feed can be retrieved.

To distinguish between podcast and episode URIs, the podcast URI MUST NOT contain a fragment identifier.

class mopidy_podcast.models.Episode(*args, **kwargs)

Mopidy model type to represent a podcast episode.

Parameters:
  • uri (string) – episode URI
  • title (string) – episode title
  • guid (string) – globally unique identifier
  • pubdate (datetime.datetime) – publication date and time
  • author (string) – author name
  • block (boolean) – prevent the episode from appearing
  • image (Image) – episode image
  • duration (datetime.timedelta) – episode duration
  • explicit (boolean) – whether the podcast contains explicit material
  • order (integer) – override default ordering
  • subtitle (string) – short description
  • summary (Enclosure) – long description
  • enclosure – media object
author = None

The episode’s author’s name.

block = None

Prevent an episode from appearing in the directory.

duration = None

The episode’s duration as an instance of datetime.timedelta.

enclosure = None

The media object, e.g. the audio stream, attached to the episode as an instance of Enclosure.

explicit = None

Indicates whether the episode contains explicit material.

guid = None

A string that uniquely identifies the episode.

image = None

An image to be displayed with the episode as an instance of Image.

order = None

Overrides the default ordering of episodes.

pubdate = None

The episode’s publication date and time as an instance of datetime.datetime.

subtitle = None

A short description of the episode.

summary = None

A description of the episode, up to 4000 characters long.

title = None

The episode’s title.

uri = None

The episode URI.

If the episode contains an enclosure, the episode URI MUST consist of the associated podcast URI with the enclosure URL appended as a fragment identifier.

class mopidy_podcast.models.Image(*args, **kwargs)

Mopidy model type to represent a podcast’s image.

Parameters:
  • uri (string) – image URI
  • title – image title
  • width (integer or None) – image width in pixels
  • height (integer or None) – image height in pixels
height = None

The image’s height in pixels.

title = None

The image’s title.

uri = None

The image’s URI.

width = None

The image’s width in pixels.

class mopidy_podcast.models.Enclosure(*args, **kwargs)

Mopidy model type to represent an episode’s media object.

Parameters:
  • uri (string) – enclosure URI
  • length (integer) – enclosure file size in bytes
  • type (string) – enclosure MIME type
length = None

The enclosure’s file size in bytes.

type = None

The MIME type of the enclosure, e.g. audio/mpeg.

uri = None

The URI of the media object.

class mopidy_podcast.models.Ref(*args, **kwargs)

Extends mopidy.models.Ref to provide factory methods and type constants for Podcast and Episode.

Parameters:
  • uri (string) – object URI
  • name (string) – object name
  • type (string) – object type
EPISODE = u'episode'

Constant used for comparison with the type field.

PODCAST = u'podcast'

Constant used for comparison with the type field.

classmethod episode(**kwargs)

Create a Ref with type EPISODE.

classmethod podcast(**kwargs)

Create a Ref with type PODCAST.

Mopidy-Podcast Directory Provider

A PodcastDirectory provides access to collections (also termed directories in Mopidy), podcasts and episodes, possibly via an external directory service. Each PodcastDirectory instance manages its own private namespace of URI references, all starting with an absolute path and optionally containg a query string and fragment identifier. The URI reference / specifies the root of a podcast directory, and any two podcast directories may use the same URI reference, e.g. /Music?topPodcasts, for different resources.

A PodcastDirectory may also register one or more URI schemes via the uri_schemes attribute. For example, the feeds directory bundled with Mopidy-Podcast already registers the file, ftp, http and https schemes, assuming URIs with these schemes point to podcast RSS feeds. By returning an absolute URI with one of these schemes, a podcast directory actually delegates retrieving and parsing the respective resource to the feeds directory.

class mopidy_podcast.directory.PodcastDirectory(config)

Podcast directory provider.

name = None

Name of the podcast directory implementation.

Subclasses must override this attribute with a string starting with an ASCII character and consisting solely of ASCII characters, digits and hyphens (-).

root_name = None

Name of the root directory for browsing.

Subclasses must override this attribute if they implement the browse() method.

uri_schemes = []

List of URI schemes the directory can handle.

Subclasses that provide support for additional URI schemes must implement the get() method for the specified schemes, and must also support absolute URIs in their browse() and search() methods.

Note that the file, ftp, http and https schemes are already handled by the feeds directory implementation.

get(uri)

Return a podcast for the given uri.

uri is an absolute URI corresponding to one of the configured uri_schemes.

If a subclass does not override uri_schemes, this method need not be implemented.

Parameters:uri (string) – podcast URI
Return type:mopidy_podcast.models.Podcast
browse(uri, limit=None)

Browse directories, podcasts and episodes at the given uri.

uri may be either a URI reference starting with /, or an absolute URI with one of the configured uri_schemes.

limit specifies the maximum number of objects to return, or None if no such limit is given.

Returns a list of mopidy_podcast.models.Ref objects for the directories, podcasts and episodes at the given uri.

Parameters:
  • uri (string) – browse URI
  • limit (int) – browse limit
Return type:

mopidy_podcast.models.Ref iterable

search(uri, terms, attr=None, type=None, limit=None)

Search podcasts and episodes at the given uri for terms.

uri may be either a URI reference starting with /, or an absolute URI with one of the configured uri_schemes.

terms is a list of strings specifying search terms.

attr may be an attribute name which must be matched, or None if any attribute may match terms.

type, if given, specifies the type of items to search for, and must be either mopidy_podcast.models.Ref.PODCAST or mopidy_podcast.models.Ref.EPISODE.

limit specifies the maximum number of objects to return, or None if no such limit is given.

Returns a list of mopidy_podcast.models.Ref objects for the matching podcasts and episodes found at the given uri.

Parameters:
  • uri (string) – browse URI
  • terms (list of strings) – search terms
  • attr (string) – search attribute
  • type (string) – search result type
  • limit (int) – search limit
Return type:

mopidy_podcast.models.Ref iterable

refresh(uri=None)

Refresh the podcast directory.

This method is called right after __init__() and should be used to perform potentially time-consuming initialization, such as retrieving data from a Web site.

This method may also be called periodically as a request to update any locally cached data.

Parameters:uri (string) – refresh URI

License

Mopidy-Podcast is Copyright (c) 2014 Thomas Kemmer.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this software except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.