bazarr/libs/knowit/api.py

131 lines
3.8 KiB
Python

import os
import traceback
import typing
from knowit import __version__
from knowit.config import Config
from knowit.provider import Provider
from .providers import (
EnzymeProvider,
FFmpegProvider,
MediaInfoProvider,
MkvMergeProvider,
)
_provider_map = {
'mediainfo': MediaInfoProvider,
'ffmpeg': FFmpegProvider,
'mkvmerge': MkvMergeProvider,
'enzyme': EnzymeProvider,
}
provider_names = _provider_map.keys()
available_providers: typing.Dict[str, Provider] = {}
class KnowitException(Exception):
"""Exception raised when knowit encounters an internal error."""
def initialize(context: typing.Optional[typing.Mapping] = None) -> None:
"""Initialize knowit."""
if not available_providers:
context = context or {}
config = Config.build(context.get('config'))
for name, provider_cls in _provider_map.items():
general_config = getattr(config, 'general', {})
mapping = context.get(name) or general_config.get(name)
available_providers[name] = provider_cls(config, mapping)
def know(
video_path: typing.Union[str, os.PathLike],
context: typing.Optional[typing.MutableMapping] = None
) -> typing.Mapping:
"""Return a mapping of video metadata."""
video_path = os.fspath(video_path)
try:
context = context or {}
context.setdefault('profile', 'default')
initialize(context)
for name, provider in available_providers.items():
if name != (context.get('provider') or name):
continue
if provider.accepts(video_path):
result = provider.describe(video_path, context)
if result:
return result
return {}
except Exception:
raise KnowitException(debug_info(context=context, exc_info=True))
def dependencies(context: typing.Optional[typing.Mapping] = None) -> typing.Mapping:
"""Return all dependencies detected by knowit."""
deps = {}
try:
initialize(context)
for name, provider_cls in _provider_map.items():
if name in available_providers:
deps[name] = available_providers[name].version
else:
deps[name] = {}
except Exception:
pass
return deps
def _centered(value: str) -> str:
value = value[-52:]
return f'| {value:^53} |'
def debug_info(
context: typing.Optional[typing.MutableMapping] = None,
exc_info: bool = False,
) -> str:
lines = [
'+-------------------------------------------------------+',
_centered(f'KnowIt {__version__}'),
'+-------------------------------------------------------+'
]
first = True
for key, info in dependencies(context).items():
if not first:
lines.append(_centered(''))
first = False
for k, v in info.items():
lines.append(_centered(k))
lines.append(_centered(v))
if context:
debug_data = context.pop('debug_data', None)
lines.append('+-------------------------------------------------------+')
for k, v in context.items():
if v:
lines.append(_centered(f'{k}: {v}'))
if debug_data:
lines.append('+-------------------------------------------------------+')
lines.append(debug_data())
if exc_info:
lines.append('+-------------------------------------------------------+')
lines.append(traceback.format_exc())
lines.append('+-------------------------------------------------------+')
lines.append(_centered('Please report any bug or feature request at'))
lines.append(_centered('https://github.com/ratoaq2/knowit/issues.'))
lines.append('+-------------------------------------------------------+')
return '\n'.join(lines)