Provider Guide
**************

This guide is going to explain how to add a "Provider" to subliminal.
You are encouraged to take a look at the existing providers, it can be
a nice base to start your own provider.


Requirements
============

When starting a provider you should be able to answer to the following
questions:

* What languages does my provider support?

* What are the language codes for the supported languages?

* Does my provider deliver subtitles for episodes? for movies?

* Does my provider require a video hash?

Each response of these questions will help you set the correct
attributes for your "Provider".


Video Validation
================

Not all providers deliver subtitles for "Episode". Some may require a
hash. The "check()" method does validation against a "Video" object
and will return *False* if the given "Video" isn’t suitable. If you’re
not happy with the default implementation, you can override it.


Configuration
=============

API keys must not be configurable by the user and must remain linked
to subliminal. Hence they must be written in the provider module.

Per-user authentication is allowed and must be configured at
instantiation as keyword arguments. Configuration will be done by the
user through the *provider_configs* argument of the "list_subtitles()"
and "download_best_subtitles()" functions. No network operation must
be done during instantiation, only configuration. Any error in the
configuration must raise a "ConfigurationError".

Beyond this point, if an error occurs, a generic "ProviderError"
exception must be raised. You can also use more explicit exception
classes "AuthenticationError" and "DownloadLimitExceeded".


Initialization / Termination
============================

Actual authentication operations must take place in the "initialize()"
method. If you need anything to be executed when the provider isn’t
used anymore like logout, use "terminate()".


Caching policy
==============

To save bandwidth and improve querying time, intermediate data should
be cached when possible. Typical use case is when a query to retrieve
show ids is required prior to the query to actually search for
subtitles. In that case the function that gets the show id from the
show name must be cached. Expiration time should be
"SHOW_EXPIRATION_TIME" for shows and "EPISODE_EXPIRATION_TIME" for
episodes.


Language
========

To be able to handle various language codes, subliminal makes use of
babelfish Language and converters. You must set the attribute
"languages" with a set of supported "Language".

If you cannot find a suitable converter for your provider, you can
make one of your own.


Querying
========

The "query()" method parameters must include all aspects of provider’s
querying with primary types.


Subtitle
========

A custom "Subtitle" subclass must be created to represent a subtitle
from the provider. It must have relevant attributes that can be used
to compute the matches of the subtitle against a "Video" object.


Score computation
=================

To be able to compare subtitles coming from different providers
between them, the "get_matches()" method must be implemented.


Unittesting
===========

All possible uses of "query()", "list_subtitles()" and
"download_subtitle()" methods must have integration tests. Use vcrpy
for recording and playback of network activity. Other functions must
be unittested. If necessary, you can use "unittest.mock" to mock some
functions.
