Source code for timeside.core.provider
from .component import Component, MetaComponent, abstract
from .component import implements, implementations, interfacedoc
from .api import IProvider
from .exceptions import Error, PIDError, ApiError
from .tools.parameters import HasParam
import re
import youtube_dl
from requests import get
import os
_providers = {}
[docs]class MetaProvider(MetaComponent):
"""Metaclass of the Provider class, used mainly for ensuring
that provider id's are wellformed and unique"""
valid_id = re.compile("^[a-z][_a-z0-9]*$")
def __new__(cls, name, bases, d):
new_class = super(MetaProvider, cls).__new__(cls, name, bases, d)
if new_class in implementations(IProvider):
id = str(new_class.id())
if id in _providers:
# Doctest test can duplicate a provider
# This can be identify by the conditon "module == '__main__'"
new_path = os.path.realpath(inspect.getfile(new_class))
id_path = os.path.realpath(inspect.getfile(_provider[id]))
if new_class.__module__ == '__main__':
new_class = _provider[id]
elif _provider[id].__module__ == '__main__':
pass
elif new_path == id_path:
new_class = _provider[id]
else:
raise ApiError("%s at %s and %s at %s have the same id: '%s'"
% (new_class.__name__, new_path,
_provider[id].__name__, id_path,
id))
if not MetaProvider.valid_id.match(id):
raise ApiError("%s has a malformed id: '%s'"
% (new_class.__name__, id))
_providers[id] = new_class
return new_class
[docs]class Provider(Component, metaclass=MetaProvider):
"""Base component class of all providers"""
abstract()
implements(IProvider)
def __init__(self):
super(Provider, self).__init__()
@interfacedoc
@classmethod
def description(self):
try:
descr = self.__doc__.lstrip().split('\n')[0]
except AttributeError:
return '*** NO DESCRIPTION FOR THIS PROVIDER ***'
return descr
[docs]def providers(interface=IProvider, recurse=True):
"""Returns the providers implementing a given interface and, if recurse,
any of the descendants of this interface."""
return implementations(interface, recurse)
[docs]def get_provider(provider_id):
"""Return a provider by its pid"""
if not provider_id in _providers:
raise PIDError("No provider registered with id: '%s'"
% provider_id)
return _providers[provider_id]
def list_providers(interface=IProvider):
lst = interface.__name__ + "\n"
lst += '=' * len(interface.__name__) + "\n"
provs = providers(interface, False)
for p in provs:
lst += f" * {p.id()} :" + "\n"
lst += f" \t\t{p.name()}" + "\n"
return lst
def list_providers_rst(interface=IProvider):
lst = '\n' + interface.__name__ + '\n'
lst += '=' * len(interface.__name__) + '\n'
provs = providers(interface, False)
for p in provs:
lst += f" * **{p.id()}** : {p.name()}" + '\n'
return lst