def check_dirs_and_files(self): if not os.path.isdir(self.config["local"]["media_dir"]): logger.warning("Local media dir %s does not exist." % self.config["local"]["media_dir"]) try: path.get_or_create_dir(self.config["local"]["data_dir"]) except EnvironmentError as error: logger.warning("Could not create local data dir: %s", encoding.locale_decode(error)) # TODO: replace with data dir? try: path.get_or_create_dir(self.config["local"]["playlists_dir"]) except EnvironmentError as error: logger.warning("Could not create local playlists dir: %s", encoding.locale_decode(error))
def _process(pipeline, timeout_ms): clock = pipeline.get_clock() bus = pipeline.get_bus() timeout = timeout_ms * gst.MSECOND tags, mime, have_audio, missing_description = {}, None, False, None types = ( gst.MESSAGE_ELEMENT | gst.MESSAGE_APPLICATION | gst.MESSAGE_ERROR | gst.MESSAGE_EOS | gst.MESSAGE_ASYNC_DONE | gst.MESSAGE_TAG ) start = clock.get_time() while timeout > 0: message = bus.timed_pop_filtered(timeout, types) if message is None: break elif message.type == gst.MESSAGE_ELEMENT: if gst.pbutils.is_missing_plugin_message(message): missing_description = encoding.locale_decode(_missing_plugin_desc(message)) elif message.type == gst.MESSAGE_APPLICATION: if message.structure.get_name() == "have-type": mime = message.structure["caps"].get_name() if mime.startswith("text/") or mime == "application/xml": return tags, mime, have_audio elif message.structure.get_name() == "have-audio": have_audio = True elif message.type == gst.MESSAGE_ERROR: error = encoding.locale_decode(message.parse_error()[0]) if missing_description: error = "%s (%s)" % (missing_description, error) raise exceptions.ScannerError(error) elif message.type == gst.MESSAGE_EOS: return tags, mime, have_audio elif message.type == gst.MESSAGE_ASYNC_DONE: if message.src == pipeline: return tags, mime, have_audio elif message.type == gst.MESSAGE_TAG: taglist = message.parse_tag() # Note that this will only keep the last tag. tags.update(utils.convert_taglist(taglist)) timeout -= clock.get_time() - start raise exceptions.ScannerError("Timeout after %dms" % timeout_ms)
def test_can_decode_utf8_strings_with_french_content(self, mock): mock.return_value = 'UTF-8' result = locale_decode( b'[Errno 98] Adresse d\xc3\xa9j\xc3\xa0 utilis\xc3\xa9e') self.assertEqual('[Errno 98] Adresse d\xe9j\xe0 utilis\xe9e', result)
def _collect(self): """Polls for messages to collect data.""" start = time.time() timeout_s = self._timeout_ms / float(1000) tags = {} while time.time() - start < timeout_s: if not self._bus.have_pending(): continue message = self._bus.pop() if message.type == gst.MESSAGE_ERROR: raise exceptions.ScannerError( encoding.locale_decode(message.parse_error()[0])) elif message.type == gst.MESSAGE_EOS: return tags elif message.type == gst.MESSAGE_ASYNC_DONE: if message.src == self._pipe: return tags elif message.type == gst.MESSAGE_TAG: # Taglists are not really dicts, hence the lack of .items() and # explicit .keys. We only keep the last tag for each key, as we # assume this is the best, some formats will produce multiple # taglists. Lastly we force everything to lists for conformity. taglist = message.parse_tag() for key in taglist.keys(): value = taglist[key] if not isinstance(value, list): value = [value] tags[key] = value raise exceptions.ScannerError('Timeout after %dms' % self._timeout_ms)
def check_dirs_and_files(self): if not os.path.isdir(self.config['local']['media_dir']): logger.warning('Local media dir %s does not exist.' % self.config['local']['media_dir']) try: path.get_or_create_dir(self.config['local']['playlists_dir']) except EnvironmentError as error: logger.warning('Could not create local playlists dir: %s', encoding.locale_decode(error)) try: path.get_or_create_file(self.config['local']['tag_cache_file']) except EnvironmentError as error: logger.warning('Could not create empty tag cache file: %s', encoding.locale_decode(error))
def __init__(self, config, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(config['mpd']['hostname']) self.hostname = hostname self.port = config['mpd']['port'] self.zeroconf_name = config['mpd']['zeroconf'] self.zeroconf_service = None try: network.Server( self.hostname, self.port, protocol=session.MpdSession, protocol_kwargs={ 'config': config, 'core': core, }, max_connections=config['mpd']['max_connections'], timeout=config['mpd']['connection_timeout']) except IOError as error: logger.error( 'MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', self.hostname, self.port)
def test_can_decode_an_ioerror_with_french_content(self, mock): mock.return_value = 'UTF-8' error = IOError(98, b'Adresse d\xc3\xa9j\xc3\xa0 utilis\xc3\xa9e') result = locale_decode(error) self.assertEquals('[Errno 98] Adresse d\xe9j\xe0 utilis\xe9e', result)
def __init__(self, config, core): super(MpdFrontend, self).__init__() self.hostname = network.format_hostname(config['mpd']['hostname']) self.port = config['mpd']['port'] self.zeroconf_name = config['mpd']['zeroconf'] self.zeroconf_service = None try: network.Server( self.hostname, self.port, protocol=session.MpdSession, protocol_kwargs={ 'config': config, 'core': core, }, max_connections=config['mpd']['max_connections'], timeout=config['mpd']['connection_timeout']) except IOError as error: raise exceptions.FrontendError( 'MPD server startup failed: %s' % encoding.locale_decode(error)) logger.info('MPD server running at [%s]:%s', self.hostname, self.port)
def check_dirs_and_files(self): if not os.path.isdir(self.config['local']['media_dir']): logger.warning('Local media dir %s does not exist.' % self.config['local']['media_dir']) try: path.get_or_create_dir(self.config['local']['data_dir']) except EnvironmentError as error: logger.warning('Could not create local data dir: %s', encoding.locale_decode(error)) # TODO: replace with data dir? try: path.get_or_create_dir(self.config['local']['playlists_dir']) except EnvironmentError as error: logger.warning('Could not create local playlists dir: %s', encoding.locale_decode(error))
def check_dirs_and_files(self): if not os.path.isdir(self.config['local']['media_dir']): logger.warning('Local media dir %s does not exist.' % self.config['local']['media_dir']) try: path.get_or_create_dir(self.config['local']['playlists_dir']) except EnvironmentError as error: logger.warning( 'Could not create local playlists dir: %s', encoding.locale_decode(error)) try: path.get_or_create_file(self.config['local']['tag_cache_file']) except EnvironmentError as error: logger.warning( 'Could not create empty tag cache file: %s', encoding.locale_decode(error))
def _process(pipeline, timeout_ms): clock = pipeline.get_clock() bus = pipeline.get_bus() timeout = timeout_ms * gst.MSECOND tags, mime, have_audio, missing_description = {}, None, False, None types = (gst.MESSAGE_ELEMENT | gst.MESSAGE_APPLICATION | gst.MESSAGE_ERROR | gst.MESSAGE_EOS | gst.MESSAGE_ASYNC_DONE | gst.MESSAGE_TAG) start = clock.get_time() while timeout > 0: message = bus.timed_pop_filtered(timeout, types) if message is None: break elif message.type == gst.MESSAGE_ELEMENT: if gst.pbutils.is_missing_plugin_message(message): missing_description = encoding.locale_decode( _missing_plugin_desc(message)) elif message.type == gst.MESSAGE_APPLICATION: if message.structure.get_name() == 'have-type': mime = message.structure['caps'].get_name() if mime.startswith('text/') or mime == 'application/xml': return tags, mime, have_audio elif message.structure.get_name() == 'have-audio': have_audio = True elif message.type == gst.MESSAGE_ERROR: error = encoding.locale_decode(message.parse_error()[0]) if missing_description: error = '%s (%s)' % (missing_description, error) raise exceptions.ScannerError(error) elif message.type == gst.MESSAGE_EOS: return tags, mime, have_audio elif message.type == gst.MESSAGE_ASYNC_DONE: if message.src == pipeline: return tags, mime, have_audio elif message.type == gst.MESSAGE_TAG: taglist = message.parse_tag() # Note that this will only keep the last tag. tags.update(utils.convert_taglist(taglist)) timeout -= clock.get_time() - start raise exceptions.ScannerError('Timeout after %dms' % timeout_ms)
def _send_broadcast(client, msg): # We could check for client.ws_connection, but we don't really # care why the broadcast failed, we just want the rest of them # to succeed, so catch everything. try: client.write_message(msg) except Exception as e: error_msg = encoding.locale_decode(e) logger.debug('Broadcast of WebSocket message to %s failed: %s', client.request.remote_ip, error_msg)
def check_dirs_and_files(config): if not os.path.isdir(config['local']['media_dir']): logger.warning('Local media dir %s does not exist.' % config['local']['media_dir']) try: path.get_or_create_dir(config['local']['data_dir']) except EnvironmentError as error: logger.warning('Could not create local data dir: %s', encoding.locale_decode(error))
def test_can_decode_an_ioerror_with_french_content(self, mock): mock.return_value = 'UTF-8' error = IOError(98, b'Adresse d\xc3\xa9j\xc3\xa0 utilis\xc3\xa9e') result = locale_decode(error) expected = '[Errno 98] Adresse d\xe9j\xe0 utilis\xe9e' self.assertEqual( expected, result, '%r decoded to %r does not match expected %r' % (error, result, expected))
def __init__(self, frontend, serial_port, serial_bps): super(SerialMonoboxController, self).__init__() try: self.s = serial.Serial(serial_port, serial_bps, timeout=0.5) except Exception as error: raise exceptions.FrontendError('SMC serial connection failed: %s' % encoding.locale_decode(error)) self.frontend = frontend self.buffer = ''
def send(self, data): """Send data to client, return any unsent data.""" try: sent = self.sock.send(data) return data[sent:] except socket.error as e: if e.errno in (errno.EWOULDBLOCK, errno.EINTR): return data self.stop( 'Unexpected client error: %s' % encoding.locale_decode(e)) return b''
def check_dirs_and_files(config): if not os.path.isdir(config['local']['media_dir']): logger.warning( 'Local media dir %s does not exist.' % config['local']['media_dir']) try: path.get_or_create_dir(config['local']['data_dir']) except EnvironmentError as error: logger.warning( 'Could not create local data dir: %s', encoding.locale_decode(error)) # TODO: replace with data dir? try: path.get_or_create_dir(config['local']['playlists_dir']) except EnvironmentError as error: logger.warning( 'Could not create local playlists dir: %s', encoding.locale_decode(error))
def test_can_decode_an_ioerror_with_french_content(self, mock): mock.return_value = 'UTF-8' error = IOError(98, b'Adresse d\xc3\xa9j\xc3\xa0 utilis\xc3\xa9e') result = locale_decode(error) expected = '[Errno 98] Adresse d\xe9j\xe0 utilis\xe9e' self.assertEqual( expected, result, '%r decoded to %r does not match expected %r' % ( error, result, expected))
def try_ipv6_socket(): """Determine if system really supports IPv6""" if not socket.has_ipv6: return False try: socket.socket(socket.AF_INET6).close() return True except IOError as error: logger.debug( 'Platform supports IPv6, but socket creation failed, ' 'disabling: %s', encoding.locale_decode(error)) return False
def try_ipv6_socket(): """Determine if system really supports IPv6""" if not socket.has_ipv6: return False try: socket.socket(socket.AF_INET6).close() return True except IOError as error: logger.debug( "Platform supports IPv6, but socket creation failed, " "disabling: %s", encoding.locale_decode(error) ) return False
def __init__(self, config, audio): super(M3UBackend, self).__init__() self._config = config try: path.get_or_create_dir(config['m3u']['playlists_dir']) except EnvironmentError as error: logger.warning('Could not create M3U playlists dir: %s', encoding.locale_decode(error)) self.playlists = M3UPlaylistsProvider(backend=self) self.library = M3ULibraryProvider(backend=self)
def __init__(self, config, audio): super(M3UBackend, self).__init__() self._config = config try: path.get_or_create_dir(config['m3u']['playlists_dir']) except EnvironmentError as error: logger.warning( 'Could not create M3U playlists dir: %s', encoding.locale_decode(error)) self.playlists = M3UPlaylistsProvider(backend=self) self.library = M3ULibraryProvider(backend=self)
def load_library(json_file): if not os.path.isfile(json_file): logger.info( 'No local library metadata cache found at %s. Please run ' '`mopidy local scan` to index your local music library. ' 'If you do not have a local music collection, you can disable the ' 'local backend to hide this message.', json_file) return {} try: with gzip.open(json_file, 'rb') as fp: return json.load(fp, object_hook=models.model_json_decoder) except (IOError, ValueError) as error: logger.warning('Loading JSON local library failed: %s', encoding.locale_decode(error)) return {}
def create_file_structures_and_config(args, extensions): path.get_or_create_dir(b'$XDG_DATA_DIR/mopidy') path.get_or_create_dir(b'$XDG_CONFIG_DIR/mopidy') # Initialize whatever the last config file is with defaults config_file = args.config_files[-1] if os.path.exists(path.expand_path(config_file)): return try: default = config_lib.format_initial(extensions) path.get_or_create_file(config_file, mkdir=False, content=default) logger.info('Initialized %s with default config', config_file) except IOError as error: logger.warning('Unable to initialize %s with default config: %s', config_file, encoding.locale_decode(error))
def _find_worker(relative, follow, done, work, results, errors): """Worker thread for collecting stat() results. :param str relative: directory to make results relative to :param bool follow: if symlinks should be followed :param threading.Event done: event indicating that all work has been done :param queue.Queue work: queue of paths to process :param dict results: shared dictionary for storing all the stat() results :param dict errors: shared dictionary for storing any per path errors """ while not done.is_set(): try: entry, parents = work.get(block=False) except queue.Empty: continue if relative: path = os.path.relpath(entry, relative) else: path = entry try: if follow: st = os.stat(entry) else: st = os.lstat(entry) if (st.st_dev, st.st_ino) in parents: errors[path] = exceptions.FindError('Sym/hardlink loop found.') continue parents = parents + [(st.st_dev, st.st_ino)] if stat.S_ISDIR(st.st_mode): for e in os.listdir(entry): work.put((os.path.join(entry, e), parents)) elif stat.S_ISREG(st.st_mode): results[path] = st elif stat.S_ISLNK(st.st_mode): errors[path] = exceptions.FindError('Not following symlinks.') else: errors[path] = exceptions.FindError('Not a file or directory.') except OSError as e: errors[path] = exceptions.FindError( encoding.locale_decode(e.strerror), e.errno) finally: work.task_done()
def __init__(self, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(settings.MPD_SERVER_HOSTNAME) port = settings.MPD_SERVER_PORT try: network.Server( hostname, port, protocol=session.MpdSession, protocol_kwargs={'core': core}, max_connections=settings.MPD_SERVER_MAX_CONNECTIONS) except IOError as error: logger.error( 'MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', hostname, port)
def __init__(self, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(settings.MPD_SERVER_HOSTNAME) port = settings.MPD_SERVER_PORT try: network.Server(hostname, port, protocol=session.MpdSession, protocol_kwargs={'core': core}, max_connections=settings.MPD_SERVER_MAX_CONNECTIONS) except IOError as error: logger.error('MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', hostname, port)
def create_file_structures_and_config(args, extensions): path.get_or_create_dir(b'$XDG_DATA_DIR/mopidy') path.get_or_create_dir(b'$XDG_CONFIG_DIR/mopidy') # Initialize whatever the last config file is with defaults config_file = args.config_files[-1] if os.path.exists(path.expand_path(config_file)): return try: default = config_lib.format_initial(extensions) path.get_or_create_file(config_file, mkdir=False, content=default) logger.info('Initialized %s with default config', config_file) except IOError as error: logger.warning( 'Unable to initialize %s with default config: %s', config_file, encoding.locale_decode(error))
def load_library(json_file): if not os.path.isfile(json_file): logger.info( 'No local library metadata cache found at %s. Please run ' '`mopidy local scan` to index your local music library. ' 'If you do not have a local music collection, you can disable the ' 'local backend to hide this message.', json_file) return {} try: with gzip.open(json_file, 'rb') as fp: return json.load(fp, object_hook=models.model_json_decoder) except (IOError, ValueError) as error: logger.warning( 'Loading JSON local library failed: %s', encoding.locale_decode(error)) return {}
def parse_m3u(file_path, media_dir): r""" Convert M3U file list of uris Example M3U data:: # This is a comment Alternative\Band - Song.mp3 Classical\Other Band - New Song.mp3 Stuff.mp3 D:\More Music\Foo.mp3 http://www.example.com:8000/Listen.pls http://www.example.com/~user/Mine.mp3 - Relative paths of songs should be with respect to location of M3U. - Paths are normaly platform specific. - Lines starting with # should be ignored. - m3u files are latin-1. - This function does not bother with Extended M3U directives. """ # TODO: uris as bytes uris = [] try: with open(file_path) as m3u: contents = m3u.readlines() except IOError as error: logger.warning('Couldn\'t open m3u: %s', locale_decode(error)) return uris for line in contents: line = line.strip().decode('latin1') if line.startswith('#'): continue if urlparse.urlsplit(line).scheme: uris.append(line) elif os.path.normpath(line) == os.path.abspath(line): path = path_to_uri(line) uris.append(path) else: path = path_to_uri(os.path.join(media_dir, line)) uris.append(path) return uris
def parse_m3u(file_path, music_folder): r""" Convert M3U file list of uris Example M3U data:: # This is a comment Alternative\Band - Song.mp3 Classical\Other Band - New Song.mp3 Stuff.mp3 D:\More Music\Foo.mp3 http://www.example.com:8000/Listen.pls http://www.example.com/~user/Mine.mp3 - Relative paths of songs should be with respect to location of M3U. - Paths are normaly platform specific. - Lines starting with # should be ignored. - m3u files are latin-1. - This function does not bother with Extended M3U directives. """ uris = [] try: with open(file_path) as m3u: contents = m3u.readlines() except IOError as error: logger.error("Couldn't open m3u: %s", locale_decode(error)) return uris for line in contents: line = line.strip().decode("latin1") if line.startswith("#"): continue # FIXME what about other URI types? if line.startswith("file://"): uris.append(line) else: path = path_to_uri(music_folder, line) uris.append(path) return uris
def parse_m3u(file_path, music_folder): r""" Convert M3U file list of uris Example M3U data:: # This is a comment Alternative\Band - Song.mp3 Classical\Other Band - New Song.mp3 Stuff.mp3 D:\More Music\Foo.mp3 http://www.example.com:8000/Listen.pls http://www.example.com/~user/Mine.mp3 - Relative paths of songs should be with respect to location of M3U. - Paths are normaly platform specific. - Lines starting with # should be ignored. - m3u files are latin-1. - This function does not bother with Extended M3U directives. """ uris = [] try: with open(file_path) as m3u: contents = m3u.readlines() except IOError as error: logger.error('Couldn\'t open m3u: %s', locale_decode(error)) return uris for line in contents: line = line.strip().decode('latin1') if line.startswith('#'): continue # FIXME what about other URI types? if line.startswith('file://'): uris.append(line) else: path = path_to_uri(music_folder, line) uris.append(path) return uris
def __init__(self, config, core): super(HttpFrontend, self).__init__() self.hostname = network.format_hostname(config["http"]["hostname"]) self.port = config["http"]["port"] tornado_hostname = config["http"]["hostname"] if tornado_hostname == "::": tornado_hostname = None try: logger.debug("Starting HTTP server") sockets = tornado.netutil.bind_sockets(self.port, tornado_hostname) self.server = HttpServer(config=config, core=core, sockets=sockets, apps=self.apps, statics=self.statics) except IOError as error: raise exceptions.FrontendError("HTTP server startup failed: %s" % encoding.locale_decode(error)) self.zeroconf_name = config["http"]["zeroconf"] self.zeroconf_http = None self.zeroconf_mopidy_http = None
def __init__(self, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(settings.MPD_SERVER_HOSTNAME) port = settings.MPD_SERVER_PORT # NOTE kwargs dict keys must be bytestrings to work on Python < 2.6.5 # See https://github.com/mopidy/mopidy/issues/302 for details. try: network.Server( hostname, port, protocol=session.MpdSession, protocol_kwargs={b'core': core}, max_connections=settings.MPD_SERVER_MAX_CONNECTIONS, timeout=settings.MPD_SERVER_CONNECTION_TIMEOUT) except IOError as error: logger.error( 'MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', hostname, port)
def __init__(self, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(settings.MPD_SERVER_HOSTNAME) port = settings.MPD_SERVER_PORT # NOTE kwargs dict keys must be bytestrings to work on Python < 2.6.5 # See https://github.com/mopidy/mopidy/issues/302 for details. try: network.Server(hostname, port, protocol=session.MpdSession, protocol_kwargs={b'core': core}, max_connections=settings.MPD_SERVER_MAX_CONNECTIONS, timeout=settings.MPD_SERVER_CONNECTION_TIMEOUT) except IOError as error: logger.error('MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', hostname, port)
def on_message(self, message): if not message: return logger.debug('Received WebSocket message from %s: %r', self.request.remote_ip, message) try: response = self.jsonrpc.handle_json( tornado.escape.native_str(message)) if response and self.write_message(response): logger.debug('Sent WebSocket message to %s: %r', self.request.remote_ip, response) except Exception as e: error_msg = encoding.locale_decode(e) logger.error('WebSocket request error: %s', error_msg) if self.ws_connection: # Tornado 3.2+ checks if self.ws_connection is None before # using it, but not older versions. self.close()
def __init__(self, config, core): super(MpdFrontend, self).__init__() self.hostname = network.format_hostname(config["mpd"]["hostname"]) self.port = config["mpd"]["port"] self.zeroconf_name = config["mpd"]["zeroconf"] self.zeroconf_service = None try: network.Server( self.hostname, self.port, protocol=session.MpdSession, protocol_kwargs={"config": config, "core": core}, max_connections=config["mpd"]["max_connections"], timeout=config["mpd"]["connection_timeout"], ) except IOError as error: raise exceptions.FrontendError("MPD server startup failed: %s" % encoding.locale_decode(error)) logger.info("MPD server running at [%s]:%s", self.hostname, self.port)
def on_message(self, message): if not message: return logger.debug( 'Received WebSocket message from %s: %r', self.request.remote_ip, message) try: response = self.jsonrpc.handle_json( tornado.escape.native_str(message)) if response and self.write_message(response): logger.debug( 'Sent WebSocket message to %s: %r', self.request.remote_ip, response) except Exception as e: error_msg = encoding.locale_decode(e) logger.error('WebSocket request error: %s', error_msg) if self.ws_connection: # Tornado 3.2+ checks if self.ws_connection is None before # using it, but not older versions. self.close()
def __init__(self, config, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(config['mpd']['hostname']) port = config['mpd']['port'] try: network.Server( hostname, port, protocol=session.MpdSession, protocol_kwargs={ 'config': config, 'core': core, }, max_connections=config['mpd']['max_connections'], timeout=config['mpd']['connection_timeout']) except IOError as error: logger.error( 'MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', hostname, port)
def parse_mpd_tag_cache(tag_cache, music_dir=''): """ Converts a MPD tag_cache into a lists of tracks, artists and albums. """ tracks = set() try: with open(tag_cache) as library: contents = library.read() except IOError as error: logger.warning('Could not open tag cache: %s', locale_decode(error)) return tracks current = {} state = None # TODO: uris as bytes for line in contents.split(b'\n'): if line == b'songList begin': state = 'songs' continue elif line == b'songList end': state = None continue elif not state: continue key, value = line.split(b': ', 1) if key == b'key': _convert_mpd_data(current, tracks) current.clear() current[key.lower()] = value.decode('utf-8') _convert_mpd_data(current, tracks) return tracks
def __init__(self, config, core): super(HttpFrontend, self).__init__() self.hostname = network.format_hostname(config['http']['hostname']) self.port = config['http']['port'] tornado_hostname = config['http']['hostname'] if tornado_hostname == '::': tornado_hostname = None try: logger.debug('Starting HTTP server') sockets = tornado.netutil.bind_sockets(self.port, tornado_hostname) self.server = HttpServer( config=config, core=core, sockets=sockets, apps=self.apps, statics=self.statics) except IOError as error: raise exceptions.FrontendError( 'HTTP server startup failed: %s' % encoding.locale_decode(error)) self.zeroconf_name = config['http']['zeroconf'] self.zeroconf_http = None self.zeroconf_mopidy_http = None
def __init__(self, config, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(config['mpd']['hostname']) port = config['mpd']['port'] # NOTE kwargs dict keys must be bytestrings to work on Python < 2.6.5 # See https://github.com/mopidy/mopidy/issues/302 for details. try: network.Server(hostname, port, protocol=session.MpdSession, protocol_kwargs={ b'config': config, b'core': core, }, max_connections=config['mpd']['max_connections'], timeout=config['mpd']['connection_timeout']) except IOError as error: logger.error('MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', hostname, port)
def parse_mpd_tag_cache(tag_cache, music_dir=""): """ Converts a MPD tag_cache into a lists of tracks, artists and albums. """ tracks = set() try: with open(tag_cache) as library: contents = library.read() except IOError as error: logger.error("Could not open tag cache: %s", locale_decode(error)) return tracks current = {} state = None for line in contents.split(b"\n"): if line == b"songList begin": state = "songs" continue elif line == b"songList end": state = None continue elif not state: continue key, value = line.split(b": ", 1) if key == b"key": _convert_mpd_data(current, tracks, music_dir) current.clear() current[key.lower()] = value.decode("utf-8") _convert_mpd_data(current, tracks, music_dir) return tracks
def __init__(self, config, core): super(MpdFrontend, self).__init__() hostname = network.format_hostname(config['mpd']['hostname']) port = config['mpd']['port'] # NOTE kwargs dict keys must be bytestrings to work on Python < 2.6.5 # See https://github.com/mopidy/mopidy/issues/302 for details. try: network.Server( hostname, port, protocol=session.MpdSession, protocol_kwargs={ b'config': config, b'core': core, }, max_connections=config['mpd']['max_connections'], timeout=config['mpd']['connection_timeout']) except IOError as error: logger.error( 'MPD server startup failed: %s', encoding.locale_decode(error)) sys.exit(1) logger.info('MPD server running at [%s]:%s', hostname, port)
def test_does_not_use_locale_to_decode_ascii_bytestrings(self, mock): mock.return_value = 'UTF-8' locale_decode('abc') self.assertFalse(mock.called)
def parse_m3u(file_path, media_dir=None): r""" Convert M3U file list to list of tracks Example M3U data:: # This is a comment Alternative\Band - Song.mp3 Classical\Other Band - New Song.mp3 Stuff.mp3 D:\More Music\Foo.mp3 http://www.example.com:8000/Listen.pls http://www.example.com/~user/Mine.mp3 Example extended M3U data:: #EXTM3U #EXTINF:123, Sample artist - Sample title Sample.mp3 #EXTINF:321,Example Artist - Example title Greatest Hits\Example.ogg #EXTINF:-1,Radio XMP http://mp3stream.example.com:8000/ - Relative paths of songs should be with respect to location of M3U. - Paths are normally platform specific. - Lines starting with # are ignored, except for extended M3U directives. - Track.name and Track.length are set from extended M3U directives. - m3u files are latin-1. """ # TODO: uris as bytes tracks = [] try: with open(file_path) as m3u: contents = m3u.readlines() except IOError as error: logger.warning('Couldn\'t open m3u: %s', locale_decode(error)) return tracks if not contents: return tracks extended = contents[0].decode('latin1').startswith('#EXTM3U') track = Track() for line in contents: line = line.strip().decode('latin1') if line.startswith('#'): if extended and line.startswith('#EXTINF'): track = m3u_extinf_to_track(line) continue if urlparse.urlsplit(line).scheme: tracks.append(track.copy(uri=line)) elif os.path.normpath(line) == os.path.abspath(line): path = path_to_uri(line) tracks.append(track.copy(uri=path)) elif media_dir is not None: path = path_to_uri(os.path.join(media_dir, line)) tracks.append(track.copy(uri=path)) track = Track() return tracks