1# -*- coding: utf-8 -*- 2from __future__ import unicode_literals 3 4import traceback 5 6from . import OrderedDict, __version__ 7from .config import Config 8from .providers import ( 9 EnzymeProvider, 10 FFmpegProvider, 11# MediaInfoProvider, 12) 13 14_provider_map = OrderedDict([ 15# ('mediainfo', MediaInfoProvider), 16 ('ffmpeg', FFmpegProvider), 17 ('enzyme', EnzymeProvider) 18]) 19 20provider_names = _provider_map.keys() 21 22available_providers = OrderedDict([]) 23 24 25class KnowitException(Exception): 26 """Exception raised when knowit fails to perform media info extraction because of an internal error.""" 27 28 29def initialize(context=None): 30 """Initialize knowit.""" 31 if not available_providers: 32 context = context or {} 33 config = Config.build(context.get('config')) 34 for name, provider_cls in _provider_map.items(): 35 available_providers[name] = provider_cls(config, context.get(name) or config.general.get(name)) 36 37 38def know(video_path, context=None): 39 """Return a dict containing the video metadata. 40 41 :param video_path: 42 :type video_path: string 43 :param context: 44 :type context: dict 45 :return: 46 :rtype: dict 47 """ 48 try: 49 # handle path-like objects 50 video_path = video_path.__fspath__() 51 except AttributeError: 52 pass 53 54 try: 55 context = context or {} 56 context.setdefault('profile', 'default') 57 initialize(context) 58 59 for name, provider in available_providers.items(): 60 if name != (context.get('provider') or name): 61 continue 62 63 if provider.accepts(video_path): 64 result = provider.describe(video_path, context) 65 if result: 66 return result 67 68 return {} 69 except Exception: 70 raise KnowitException(debug_info(context=context, exc_info=True)) 71 72 73def dependencies(context=None): 74 """Return all dependencies detected by knowit.""" 75 deps = OrderedDict([]) 76 try: 77 initialize(context) 78 for name, provider_cls in _provider_map.items(): 79 if name in available_providers: 80 deps[name] = available_providers[name].version 81 else: 82 deps[name] = {} 83 except Exception: 84 pass 85 86 return deps 87 88 89def _centered(value): 90 value = value[-52:] 91 return '| {msg:^53} |'.format(msg=value) 92 93 94def debug_info(context=None, exc_info=False): 95 lines = [ 96 '+-------------------------------------------------------+', 97 _centered('KnowIt {0}'.format(__version__)), 98 '+-------------------------------------------------------+' 99 ] 100 101 first = True 102 for key, info in dependencies(context).items(): 103 if not first: 104 lines.append(_centered('')) 105 first = False 106 107 for k, v in info.items(): 108 lines.append(_centered(k)) 109 lines.append(_centered(v)) 110 111 if context: 112 debug_data = context.pop('debug_data', None) 113 114 lines.append('+-------------------------------------------------------+') 115 for k, v in context.items(): 116 if v: 117 lines.append(_centered('{}: {}'.format(k, v))) 118 119 if debug_data: 120 lines.append('+-------------------------------------------------------+') 121 lines.append(debug_data()) 122 123 if exc_info: 124 lines.append('+-------------------------------------------------------+') 125 lines.append(traceback.format_exc()) 126 127 lines.append('+-------------------------------------------------------+') 128 lines.append(_centered('Please report any bug or feature request at')) 129 lines.append(_centered('https://github.com/ratoaq2/knowit/issues.')) 130 lines.append('+-------------------------------------------------------+') 131 132 return '\n'.join(lines) 133