def __init__(self, backend, config): super(FileLibraryProvider, self).__init__(backend) self._media_dirs = list(self._get_media_dirs(config)) self._follow_symlinks = config['file']['follow_symlinks'] self._show_dotfiles = config['file']['show_dotfiles'] self._scanner = scan.Scanner( timeout=config['file']['metadata_timeout'])
def __init__(self, config, audio): super(AudioAddictBackend, self).__init__() full_proxy = format_proxy( scheme=config['proxy']['scheme'], username=config['proxy']['username'], password=config['proxy']['password'], hostname=config['proxy']['hostname'], port=config['proxy']['port']) self._config = config self._scanner = scan.Scanner( timeout=config['stream']['timeout'], proxy_config=config['proxy']) self.audioaddict = client.AudioAddict( config['audioaddict']['username'], config['audioaddict']['password'], config['audioaddict']['quality'], config['audioaddict']['difm'], config['audioaddict']['radiotunes'], config['audioaddict']['rockradio'], config['audioaddict']['jazzradio'], config['audioaddict']['frescaradio'], proxy=full_proxy ) self.library = AudioAddictLibrary(backend=self) self.playback = AudioAddictPlayback(audio=audio, backend=self)
def __init__(self, config, audio): logger.debug( 'RadioBrowser: Start backend.RadioBrowserBackend.__init__') super(RadioBrowserBackend, self).__init__() self._session = get_requests_session( proxy_config=config['proxy'], user_agent='%s/%s' % (mopidy_radiobrowser.Extension.dist_name, mopidy_radiobrowser.__version__)) self._timeout = config['radiobrowser']['timeout'] self._encoding = config['radiobrowser']['encoding'].lower() self._wlexact = config['radiobrowser']['whitelist_exact'] self._wltags = config['radiobrowser']['whitelist_tags'] self._wlstates = config['radiobrowser']['whitelist_countries'] self._dlang = config['radiobrowser']['display_languages'] self._drated = config['radiobrowser']['display_toprated'] self._scanner = scan.Scanner(timeout=config['radiobrowser']['timeout'], proxy_config=config['proxy']) self.radiobrowser = RadioBrowser( config['radiobrowser']['timeout'], config['radiobrowser']['encoding'].lower(), config['radiobrowser']['whitelist_exact'], config['radiobrowser']['whitelist_tags'], config['radiobrowser']['whitelist_countries'], config['radiobrowser']['display_languages'], config['radiobrowser']['display_toprated'], self._session) self.library = RadioBrowserLibrary(self) self.playback = RadioBrowserPlayback(audio=audio, backend=self)
def __init__(self, config, audio): super(StreamBackend, self).__init__() self._scanner = scan.Scanner(timeout=config['stream']['timeout'], proxy_config=config['proxy']) self._session = http.get_requests_session( proxy_config=config['proxy'], user_agent='%s/%s' % (stream.Extension.dist_name, stream.Extension.version)) blacklist = config['stream']['metadata_blacklist'] self._blacklist_re = re.compile( r'^(%s)$' % '|'.join(fnmatch.translate(u) for u in blacklist)) self._timeout = config['stream']['timeout'] self.library = StreamLibraryProvider(backend=self) self.playback = StreamPlaybackProvider(audio=audio, backend=self) self.playlists = None self.uri_schemes = audio_lib.supported_uri_schemes( config['stream']['protocols']) if 'file' in self.uri_schemes and config['file']['enabled']: logger.warning( 'The stream/protocols config value includes the "file" ' 'protocol. "file" playback is now handled by Mopidy-File. ' 'Please remove it from the stream/protocols config.') self.uri_schemes -= {'file'}
def __init__(self, config, audio): super().__init__() self._scanner = scan.Scanner(timeout=config["stream"]["timeout"], proxy_config=config["proxy"]) self._session = http.get_requests_session( proxy_config=config["proxy"], user_agent=( f"{stream.Extension.dist_name}/{stream.Extension.version}"), ) blacklist = config["stream"]["metadata_blacklist"] self._blacklist_re = re.compile( r"^(%s)$" % "|".join(fnmatch.translate(u) for u in blacklist)) self._timeout = config["stream"]["timeout"] self.library = StreamLibraryProvider(backend=self) self.playback = StreamPlaybackProvider(audio=audio, backend=self) self.playlists = None self.uri_schemes = audio_lib.supported_uri_schemes( config["stream"]["protocols"]) if "file" in self.uri_schemes and config["file"]["enabled"]: logger.warning( 'The stream/protocols config value includes the "file" ' 'protocol. "file" playback is now handled by Mopidy-File. ' "Please remove it from the stream/protocols config.") self.uri_schemes -= {"file"}
def scan(self, paths): scanner = scan.Scanner() for path in paths: uri = path_to_uri(path) try: self.result[path] = scanner.scan(uri) except exceptions.ScannerError as error: self.errors[path] = error
def scan(self, paths): scanner = scan.Scanner() for path in paths: uri = path_lib.path_to_uri(path) key = uri[len('file://'):] try: self.result[key] = scanner.scan(uri) except exceptions.ScannerError as error: self.errors[key] = error
def scan(self, path): paths = path_lib.find_files(path_to_data_dir(path)) uris = (path_lib.path_to_uri(p) for p in paths) scanner = scan.Scanner() for uri in uris: key = uri[len('file://'):] try: self.data[key] = scanner.scan(uri) except exceptions.ScannerError as error: self.errors[key] = error
def __init__(self, backend, config): super().__init__(backend) self._media_dirs = list(self._get_media_dirs(config)) self._show_dotfiles = config["file"]["show_dotfiles"] self._excluded_file_extensions = tuple( file_ext.lower() for file_ext in config["file"]["excluded_file_extensions"]) self._follow_symlinks = config["file"]["follow_symlinks"] self._scanner = scan.Scanner( timeout=config["file"]["metadata_timeout"])
def __init__(self, backend, config): super(FileLibraryProvider, self).__init__(backend) self._media_dirs = list(self._get_media_dirs(config)) self._show_dotfiles = config['file']['show_dotfiles'] self._excluded_file_extensions = tuple( bytes(file_ext.lower()) for file_ext in config['file']['excluded_file_extensions']) self._follow_symlinks = config['file']['follow_symlinks'] self._scanner = scan.Scanner( timeout=config['file']['metadata_timeout'])
def __init__(self, config, audio): super(PlaylistBackend, self).__init__() self.scanner = scan.Scanner(timeout=config["playlist"]["timeout"], proxy_config=config["proxy"]) self.session = http.get_requests_session( proxy_config=config["proxy"], user_agent=(f"{mopidy_playlist.Extension.dist_name}/" f"{mopidy_playlist.Extension.version}"), ) self.timeout = config["playlist"]["timeout"] self.max_lookups = config["playlist"]["max_lookups"] self.library = PlaylistLibraryProvider(backend=self) self.uri_schemes = {"playlist", "pl"}
def _scan_metadata( self, *, media_dir, file_mtimes, files, library, timeout, flush_threshold, limit ): logger.info("Scanning...") files = sorted(files)[:limit] scanner = scan.Scanner(timeout) progress = _ScanProgress(batch_size=flush_threshold, total=len(files)) for absolute_path in files: try: file_uri = absolute_path.as_uri() result = scanner.scan(file_uri) if not result.playable: logger.warning( f"Failed scanning {file_uri}: No audio found in file" ) elif result.duration is None: logger.warning( f"Failed scanning {file_uri}: " "No duration information found in file" ) elif result.duration < MIN_DURATION_MS: logger.warning( f"Failed scanning {file_uri}: " f"Track shorter than {MIN_DURATION_MS}ms" ) else: local_uri = translator.path_to_local_track_uri( absolute_path, media_dir ) mtime = file_mtimes.get(absolute_path) track = tags.convert_tags_to_track(result.tags).replace( uri=local_uri, length=result.duration, last_modified=mtime ) library.add(track, result.tags, result.duration) logger.debug(f"Added {track.uri}") except Exception as error: logger.warning(f"Failed scanning {file_uri}: {error}") if progress.increment(): progress.log() if library.flush(): logger.debug("Progress flushed") progress.log() logger.info("Done scanning")
def __init__(self, config, audio): super(TuneInBackend, self).__init__() self._session = get_requests_session( proxy_config=config['proxy'], user_agent='%s/%s' % (mopidy_tunein.Extension.dist_name, mopidy_tunein.__version__)) self._timeout = config['tunein']['timeout'] self._scanner = scan.Scanner(timeout=config['tunein']['timeout'], proxy_config=config['proxy']) self.tunein = tunein.TuneIn(config['tunein']['timeout'], self._session) self.library = TuneInLibrary(self) self.playback = TuneInPlayback(audio=audio, backend=self)
def __init__(self, config, audio): super(StreamBackend, self).__init__() self._scanner = scan.Scanner(timeout=config['stream']['timeout'], proxy_config=config['proxy']) self.library = StreamLibraryProvider( backend=self, blacklist=config['stream']['metadata_blacklist']) self.playback = StreamPlaybackProvider(audio=audio, backend=self, config=config) self.playlists = None self.uri_schemes = audio_lib.supported_uri_schemes( config['stream']['protocols'])
def __init__(self, config, audio): super().__init__() self._session = get_requests_session(config["proxy"]) self._timeout = config["tunein"]["timeout"] self._filter = config["tunein"]["filter"] self._scanner = scan.Scanner(timeout=config["tunein"]["timeout"], proxy_config=config["proxy"]) self.tunein = tunein.TuneIn( config["tunein"]["timeout"], config["tunein"]["filter"], self._session, ) self.library = TuneInLibrary(self) self.playback = TuneInPlayback(audio=audio, backend=self)
def __init__(self, config, audio): logger.debug('RadioBrowser: Start backend.RadioBrowserBackend.__init__') super(RadioBrowserBackend, self).__init__() self._session = get_requests_session( proxy_config = config['proxy'], user_agent = '%s/%s' % ( mopidy_radiobrowser.Extension.dist_name, mopidy_radiobrowser.__version__)) self._timeout = config['radiobrowser']['timeout'] self._scanner = scan.Scanner( timeout = config['radiobrowser']['timeout'], proxy_config = config['proxy']) self.radiobrowser = RadioBrowser(config['radiobrowser']['timeout'], self._session) self.library = RadioBrowserLibrary(self) self.playback = RadioBrowserPlayback(audio=audio, backend=self)
def __init__(self, config): ext_config = config[Extension.ext_name] libname = ext_config['library'] try: lib = next(lib for lib in self.libraries if lib.name == libname) self.library = lib(config) except StopIteration: raise ExtensionError('Local library %s not found' % libname) logger.debug('Using %s as the local library', libname) try: self.media_dir = config['local']['media_dir'] except KeyError: raise ExtensionError('Mopidy-Local not enabled') self.base_uri = ext_config['base_uri'] if ext_config['image_dir']: self.image_dir = ext_config['image_dir'] else: self.image_dir = Extension.get_or_create_data_dir(config) self.patterns = list(map(str, ext_config['album_art_files'])) self.scanner = scan.Scanner(config['local']['scan_timeout'])
def __init__(self, config, audio): super(StreamBackend, self).__init__() self._scanner = scan.Scanner(timeout=config['stream']['timeout'], proxy_config=config['proxy']) self.library = StreamLibraryProvider( backend=self, blacklist=config['stream']['metadata_blacklist']) self.playback = StreamPlaybackProvider(audio=audio, backend=self, config=config) self.playlists = None self.uri_schemes = audio_lib.supported_uri_schemes( config['stream']['protocols']) if 'file' in self.uri_schemes and config['file']['enabled']: logger.warning( 'The stream/protocols config value includes the "file" ' 'protocol. "file" playback is now handled by Mopidy-File. ' 'Please remove it from the stream/protocols config.') self.uri_schemes -= {'file'}
def run(self, args, config): media_dir = config['local']['media_dir'] scan_timeout = config['local']['scan_timeout'] flush_threshold = config['local']['scan_flush_threshold'] excluded_file_extensions = config['local']['excluded_file_extensions'] excluded_file_extensions = set( file_ext.lower() for file_ext in excluded_file_extensions) library = _get_library(args, config) uri_path_mapping = {} uris_in_library = set() uris_to_update = set() uris_to_remove = set() num_tracks = library.load() logger.info('Checking %d tracks from library.', num_tracks) for track in library.begin(): uri_path_mapping[track.uri] = translator.local_track_uri_to_path( track.uri, media_dir) try: stat = os.stat(uri_path_mapping[track.uri]) if int(stat.st_mtime) > track.last_modified: uris_to_update.add(track.uri) uris_in_library.add(track.uri) except OSError: logger.debug('Missing file %s', track.uri) uris_to_remove.add(track.uri) logger.info('Removing %d missing tracks.', len(uris_to_remove)) for uri in uris_to_remove: library.remove(uri) logger.info('Checking %s for unknown tracks.', media_dir) for relpath in path.find_files(media_dir): uri = translator.path_to_local_track_uri(relpath) file_extension = os.path.splitext(relpath)[1] if file_extension.lower() in excluded_file_extensions: logger.debug('Skipped %s: File extension excluded.', uri) continue if uri not in uris_in_library: uris_to_update.add(uri) uri_path_mapping[uri] = os.path.join(media_dir, relpath) logger.info('Found %d unknown tracks.', len(uris_to_update)) logger.info('Scanning...') uris_to_update = sorted(uris_to_update)[:args.limit] scanner = scan.Scanner(scan_timeout) progress = _Progress(flush_threshold, len(uris_to_update)) for uri in uris_to_update: try: data = scanner.scan(path.path_to_uri(uri_path_mapping[uri])) track = scan.audio_data_to_track(data).copy(uri=uri) library.add(track) logger.debug('Added %s', track.uri) except exceptions.ScannerError as error: logger.warning('Failed %s: %s', uri, error) if progress.increment(): progress.log() if library.flush(): logger.debug('Progress flushed.') progress.log() library.close() logger.info('Done scanning.') return 0
def run(self, args, config): media_dir = config['local']['media_dir'] scan_timeout = config['local']['scan_timeout'] flush_threshold = config['local']['scan_flush_threshold'] excluded_file_extensions = config['local']['excluded_file_extensions'] excluded_file_extensions = tuple( bytes(file_ext.lower()) for file_ext in excluded_file_extensions) library = _get_library(args, config) file_mtimes, file_errors = path.find_mtimes( media_dir, follow=config['local']['scan_follow_symlinks']) logger.info('Found %d files in media_dir.', len(file_mtimes)) if file_errors: logger.warning('Encountered %d errors while scanning media_dir.', len(file_errors)) for name in file_errors: logger.debug('Scan error %r for %r', file_errors[name], name) num_tracks = library.load() logger.info('Checking %d tracks from library.', num_tracks) uris_to_update = set() uris_to_remove = set() uris_in_library = set() for track in library.begin(): abspath = translator.local_track_uri_to_path(track.uri, media_dir) mtime = file_mtimes.get(abspath) if mtime is None: logger.debug('Missing file %s', track.uri) uris_to_remove.add(track.uri) elif mtime > track.last_modified or args.force: uris_to_update.add(track.uri) uris_in_library.add(track.uri) logger.info('Removing %d missing tracks.', len(uris_to_remove)) for uri in uris_to_remove: library.remove(uri) for abspath in file_mtimes: relpath = os.path.relpath(abspath, media_dir) uri = translator.path_to_local_track_uri(relpath) if b'/.' in relpath: logger.debug('Skipped %s: Hidden directory/file.', uri) elif relpath.lower().endswith(excluded_file_extensions): logger.debug('Skipped %s: File extension excluded.', uri) elif uri not in uris_in_library: uris_to_update.add(uri) logger.info('Found %d tracks which need to be updated.', len(uris_to_update)) logger.info('Scanning...') uris_to_update = sorted(uris_to_update, key=lambda v: v.lower()) uris_to_update = uris_to_update[:args.limit] scanner = scan.Scanner(scan_timeout) progress = _Progress(flush_threshold, len(uris_to_update)) for uri in uris_to_update: try: relpath = translator.local_track_uri_to_path(uri, media_dir) file_uri = path.path_to_uri(os.path.join(media_dir, relpath)) result = scanner.scan(file_uri) tags, duration = result.tags, result.duration if not result.playable: logger.warning('Failed %s: No audio found in file.', uri) elif duration < MIN_DURATION_MS: logger.warning('Failed %s: Track shorter than %dms', uri, MIN_DURATION_MS) else: mtime = file_mtimes.get(os.path.join(media_dir, relpath)) track = utils.convert_tags_to_track(tags).copy( uri=uri, length=duration, last_modified=mtime) if library.add_supports_tags_and_duration: library.add(track, tags=tags, duration=duration) else: library.add(track) logger.debug('Added %s', track.uri) except exceptions.ScannerError as error: logger.warning('Failed %s: %s', uri, error) if progress.increment(): progress.log() if library.flush(): logger.debug('Progress flushed.') progress.log() library.close() logger.info('Done scanning.') return 0
def __init__(self, backend, config): self._backend = backend self._config = config self._scanner = scan.Scanner(min_duration=None, timeout=5000) self._playlists = None
def scanner(): return scan.Scanner(timeout=100, proxy_config={})
def __init__(self, backend, config): super().__init__(backend) self._songs: ContainerClient = backend.songs_container_client self._cache: ContainerClient = backend.cache_container_client self._scanner = scan.Scanner()
def __init__(self, backend, timeout): super(StreamLibraryProvider, self).__init__(backend) self._scanner = scan.Scanner(min_duration=None, timeout=timeout)
def __init__(self, audio, backend, timeout): super(TuneInPlayback, self).__init__(audio, backend) self._scanner = scan.Scanner(timeout=timeout)
def run(self, args, config, extensions): media_dir = config['local']['media_dir'] scan_timeout = config['local']['scan_timeout'] excluded_file_extensions = set( ext.lower() for ext in config['local']['excluded_file_extensions']) updaters = {} for e in extensions: for updater_class in e.get_library_updaters(): if updater_class and 'local' in updater_class.uri_schemes: updaters[e.ext_name] = updater_class if not updaters: logger.error('No usable library updaters found.') return 1 elif len(updaters) > 1: logger.error( 'More than one library updater found. ' 'Provided by: %s', ', '.join(updaters.keys())) return 1 local_updater = updaters.values()[0](config) # TODO: cleanup to consistently use local urls, not a random mix of # local and file uris depending on how the data was loaded. uris_library = set() uris_update = set() uris_remove = set() tracks = local_updater.load() logger.info('Checking %d tracks from library.', len(tracks)) for track in tracks: try: uri = translator.local_to_file_uri(track.uri, media_dir) stat = os.stat(path.uri_to_path(uri)) if int(stat.st_mtime) > track.last_modified: uris_update.add(uri) uris_library.add(uri) except OSError: logger.debug('Missing file %s', track.uri) uris_remove.add(track.uri) logger.info('Removing %d missing tracks.', len(uris_remove)) for uri in uris_remove: local_updater.remove(uri) logger.info('Checking %s for unknown tracks.', media_dir) for uri in path.find_uris(media_dir): file_extension = os.path.splitext(path.uri_to_path(uri))[1] if file_extension.lower() in excluded_file_extensions: logger.debug('Skipped %s: File extension excluded.', uri) continue if uri not in uris_library: uris_update.add(uri) logger.info('Found %d unknown tracks.', len(uris_update)) logger.info('Scanning...') scanner = scan.Scanner(scan_timeout) progress = Progress(len(uris_update)) for uri in sorted(uris_update): try: data = scanner.scan(uri) track = scan.audio_data_to_track(data) local_updater.add(track) logger.debug('Added %s', track.uri) except exceptions.ScannerError as error: logger.warning('Failed %s: %s', uri, error) progress.increment() logger.info('Commiting changes.') local_updater.commit() return 0
def __init__(self, *args, **kwargs): self._scanner = scan.Scanner(min_duration=None, timeout=5000) super(MplayerLibraryProvider, self).__init__(*args, **kwargs)
def __init__(self, backend, timeout, blacklist): super(StreamLibraryProvider, self).__init__(backend) self._scanner = scan.Scanner(min_duration=None, timeout=timeout) self._blacklist_re = re.compile( r'^(%s)$' % '|'.join(fnmatch.translate(u) for u in blacklist))
def run(self, args, config): media_dir = config['local']['media_dir'] scan_timeout = config['local']['scan_timeout'] flush_threshold = config['local']['scan_flush_threshold'] excluded_file_extensions = config['local']['excluded_file_extensions'] excluded_file_extensions = tuple( bytes(file_ext.lower()) for file_ext in excluded_file_extensions) library = _get_library(args, config) uris_to_update = set() uris_to_remove = set() file_mtimes = path.find_mtimes(media_dir) logger.info('Found %d files in media_dir.', len(file_mtimes)) num_tracks = library.load() logger.info('Checking %d tracks from library.', num_tracks) for track in library.begin(): abspath = translator.local_track_uri_to_path(track.uri, media_dir) mtime = file_mtimes.pop(abspath, None) if mtime is None: logger.debug('Missing file %s', track.uri) uris_to_remove.add(track.uri) elif mtime > track.last_modified: uris_to_update.add(track.uri) logger.info('Removing %d missing tracks.', len(uris_to_remove)) for uri in uris_to_remove: library.remove(uri) for abspath in file_mtimes: relpath = os.path.relpath(abspath, media_dir) uri = translator.path_to_local_track_uri(relpath) if relpath.lower().endswith(excluded_file_extensions): logger.debug('Skipped %s: File extension excluded.', uri) continue uris_to_update.add(uri) logger.info('Found %d tracks which need to be updated.', len(uris_to_update)) logger.info('Scanning...') uris_to_update = sorted(uris_to_update, key=lambda v: v.lower()) uris_to_update = uris_to_update[:args.limit] scanner = scan.Scanner(scan_timeout) progress = _Progress(flush_threshold, len(uris_to_update)) for uri in uris_to_update: try: relpath = translator.local_track_uri_to_path(uri, media_dir) file_uri = path.path_to_uri(os.path.join(media_dir, relpath)) data = scanner.scan(file_uri) track = scan.audio_data_to_track(data).copy(uri=uri) library.add(track) logger.debug('Added %s', track.uri) except exceptions.ScannerError as error: logger.warning('Failed %s: %s', uri, error) if progress.increment(): progress.log() if library.flush(): logger.debug('Progress flushed.') progress.log() library.close() logger.info('Done scanning.') return 0