示例#1
0
 def __init__(self):
     super(RootCommand, self).__init__()
     self.set(base_verbosity_level=0)
     self.add_argument(
         '-h', '--help',
         action='help', help='Show this message and exit')
     self.add_argument(
         '--version', action='version',
         version='Mopidy %s' % versioning.get_version())
     self.add_argument(
         '-q', '--quiet',
         action='store_const', const=-1, dest='verbosity_level',
         help='less output (warning level)')
     self.add_argument(
         '-v', '--verbose',
         action='count', dest='verbosity_level', default=0,
         help='more output (repeat up to 3 times for even more)')
     self.add_argument(
         '--save-debug-log',
         action='store_true', dest='save_debug_log',
         help='save debug log to "./mopidy.log"')
     self.add_argument(
         '--config',
         action='store', dest='config_files', type=config_files_type,
         default=DEFAULT_CONFIG, metavar='FILES',
         help='config files to use, colon seperated, later files override')
     self.add_argument(
         '-o', '--option',
         action='append', dest='config_overrides',
         type=config_override_type, metavar='OPTIONS',
         help='`section/key=value` values to override config options')
示例#2
0
 def __init__(self):
     super(RootCommand, self).__init__()
     self.set(base_verbosity_level=0)
     self.add_argument("-h", "--help", action="help", help="Show this message and exit")
     self.add_argument("--version", action="version", version="Mopidy %s" % versioning.get_version())
     self.add_argument(
         "-q", "--quiet", action="store_const", const=-1, dest="verbosity_level", help="less output (warning level)"
     )
     self.add_argument(
         "-v", "--verbose", action="count", dest="verbosity_level", default=0, help="more output (debug level)"
     )
     self.add_argument(
         "--save-debug-log", action="store_true", dest="save_debug_log", help='save debug log to "./mopidy.log"'
     )
     self.add_argument(
         "--config",
         action="store",
         dest="config_files",
         type=config_files_type,
         default=b"$XDG_CONFIG_DIR/mopidy/mopidy.conf",
         metavar="FILES",
         help="config files to use, colon seperated, later files override",
     )
     self.add_argument(
         "-o",
         "--option",
         action="append",
         dest="config_overrides",
         type=config_override_type,
         metavar="OPTIONS",
         help="`section/key=value` values to override config options",
     )
示例#3
0
 def __init__(self):
     super(RootCommand, self).__init__()
     self.set(base_verbosity_level=0)
     self.add_argument(
         '-h', '--help',
         action='help', help='Show this message and exit')
     self.add_argument(
         '--version', action='version',
         version='Mopidy %s' % versioning.get_version())
     self.add_argument(
         '-q', '--quiet',
         action='store_const', const=-1, dest='verbosity_level',
         help='less output (warning level)')
     self.add_argument(
         '-v', '--verbose',
         action='count', dest='verbosity_level', default=0,
         help='more output (repeat up to 3 times for even more)')
     self.add_argument(
         '--save-debug-log',
         action='store_true', dest='save_debug_log',
         help='save debug log to "./mopidy.log"')
     self.add_argument(
         '--config',
         action='store', dest='config_files', type=config_files_type,
         default=DEFAULT_CONFIG, metavar='FILES',
         help='config files to use, colon seperated, later files override')
     self.add_argument(
         '-o', '--option',
         action='append', dest='config_overrides',
         type=config_override_type, metavar='OPTIONS',
         help='`section/key=value` values to override config options')
示例#4
0
文件: scanner.py 项目: rattboi/mopidy
def parse_options():
    parser = optparse.OptionParser(version="Mopidy %s" % versioning.get_version())
    # NOTE First argument to add_option must be bytestrings on Python < 2.6.2
    # See https://github.com/mopidy/mopidy/issues/302 for details
    parser.add_option(
        b"-q", "--quiet", action="store_const", const=0, dest="verbosity_level", help="less output (warning level)"
    )
    parser.add_option(
        b"-v", "--verbose", action="count", default=1, dest="verbosity_level", help="more output (debug level)"
    )
    return parser.parse_args(args=mopidy_args)[0]
示例#5
0
文件: scanner.py 项目: 0xadam/mopidy
def parse_options():
    parser = optparse.OptionParser(
        version='Mopidy %s' % versioning.get_version())
    parser.add_option(
        '-q', '--quiet',
        action='store_const', const=0, dest='verbosity_level',
        help='less output (warning level)')
    parser.add_option(
        '-v', '--verbose',
        action='count', default=1, dest='verbosity_level',
        help='more output (debug level)')
    return parser.parse_args(args=mopidy_args)[0]
示例#6
0
def parse_options():
    parser = optparse.OptionParser(
        version='Mopidy %s' % versioning.get_version())
    # NOTE First argument to add_option must be bytestrings on Python < 2.6.2
    # See https://github.com/mopidy/mopidy/issues/302 for details
    parser.add_option(
        b'-q', '--quiet',
        action='store_const', const=0, dest='verbosity_level',
        help='less output (warning level)')
    parser.add_option(
        b'-v', '--verbose',
        action='count', default=1, dest='verbosity_level',
        help='more output (debug level)')
    return parser.parse_args(args=mopidy_args)[0]
示例#7
0
def parse_options():
    parser = optparse.OptionParser(version='Mopidy %s' %
                                   versioning.get_version())

    # Ugly extension of optparse type checking magic :/
    optparse.Option.TYPES += ('config_override', )
    optparse.Option.TYPE_CHECKER['config_override'] = check_config_override

    # NOTE First argument to add_option must be bytestrings on Python < 2.6.2
    # See https://github.com/mopidy/mopidy/issues/302 for details
    parser.add_option(b'-q',
                      '--quiet',
                      action='store_const',
                      const=0,
                      dest='verbosity_level',
                      help='less output (warning level)')
    parser.add_option(b'-v',
                      '--verbose',
                      action='count',
                      default=1,
                      dest='verbosity_level',
                      help='more output (debug level)')
    parser.add_option(b'--save-debug-log',
                      action='store_true',
                      dest='save_debug_log',
                      help='save debug log to "./mopidy.log"')
    parser.add_option(b'--show-config',
                      action='callback',
                      callback=show_config_callback,
                      help='show current config')
    parser.add_option(b'--show-deps',
                      action='callback',
                      callback=deps.show_deps_optparse_callback,
                      help='show dependencies and their versions')
    parser.add_option(
        b'--config',
        action='store',
        dest='config',
        default=b'$XDG_CONFIG_DIR/mopidy/mopidy.conf',
        help='config files to use, colon seperated, later files override')
    parser.add_option(
        b'-o',
        b'--option',
        action='append',
        dest='overrides',
        type='config_override',
        help='`section/key=value` values to override config options')
    return parser.parse_args(args=mopidy_args)[0]
示例#8
0
def format_initial(extensions):
    config_dir = os.path.dirname(__file__)
    defaults = [read(os.path.join(config_dir, 'default.conf'))]
    defaults.extend(e.get_default_config() for e in extensions)
    raw_config = _load([], defaults, [])

    schemas = _schemas[:]
    schemas.extend(e.get_config_schema() for e in extensions)

    config, errors = _validate(raw_config, schemas)

    versions = ['Mopidy %s' % versioning.get_version()]
    for extension in sorted(extensions, key=lambda ext: ext.dist_name):
        versions.append('%s %s' % (extension.dist_name, extension.version))
    description = _INITIAL_HELP.strip() % {'versions': '\n#   '.join(versions)}
    return description + '\n\n' + _format(config, {}, schemas, False, True)
示例#9
0
def format_initial(extensions):
    config_dir = os.path.dirname(__file__)
    defaults = [read(os.path.join(config_dir, 'default.conf'))]
    defaults.extend(e.get_default_config() for e in extensions)
    raw_config = _load([], defaults, [])

    schemas = _schemas[:]
    schemas.extend(e.get_config_schema() for e in extensions)

    config, errors = _validate(raw_config, schemas)

    versions = ['Mopidy %s' % versioning.get_version()]
    for extension in sorted(extensions, key=lambda ext: ext.dist_name):
        versions.append('%s %s' % (extension.dist_name, extension.version))
    description = _INITIAL_HELP.strip() % {'versions': '\n#   '.join(versions)}
    return description + '\n\n' + _format(config, {}, schemas, False, True)
示例#10
0
文件: scanner.py 项目: eisnerd/mopidy
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--version',
                        action='version',
                        version='Mopidy %s' % versioning.get_version())
    parser.add_argument('-q',
                        '--quiet',
                        action='store_const',
                        const=0,
                        dest='verbosity_level',
                        help='less output (warning level)')
    parser.add_argument('-v',
                        '--verbose',
                        action='count',
                        default=1,
                        dest='verbosity_level',
                        help='more output (debug level)')
    return parser.parse_args(args=mopidy_args)
示例#11
0
def parse_options():
    parser = optparse.OptionParser(version='Mopidy %s' %
                                   versioning.get_version())
    # NOTE First argument to add_option must be bytestrings on Python < 2.6.2
    # See https://github.com/mopidy/mopidy/issues/302 for details
    parser.add_option(b'-q',
                      '--quiet',
                      action='store_const',
                      const=0,
                      dest='verbosity_level',
                      help='less output (warning level)')
    parser.add_option(b'-v',
                      '--verbose',
                      action='count',
                      default=1,
                      dest='verbosity_level',
                      help='more output (debug level)')
    return parser.parse_args(args=mopidy_args)[0]
示例#12
0
def format_initial(extensions):
    config_dir = os.path.dirname(__file__)
    defaults = [read(os.path.join(config_dir, 'default.conf'))]
    defaults.extend(e.get_default_config() for e in extensions)
    raw_config = _load([], defaults, [])

    schemas = _schemas[:]
    schemas.extend(e.get_config_schema() for e in extensions)

    config, errors = _validate(raw_config, schemas)

    versions = ['Mopidy %s' % versioning.get_version()]
    for extension in sorted(extensions, key=lambda ext: ext.dist_name):
        versions.append('%s %s' % (extension.dist_name, extension.version))

    header = _INITIAL_HELP.strip() % {'versions': '\n#   '.join(versions)}
    formatted_config = _format(
        config=config, comments={}, schemas=schemas,
        display=False, disable=True).decode('utf-8')
    return header + '\n\n' + formatted_config
示例#13
0
def parse_options():
    parser = optparse.OptionParser(
        version='Mopidy %s' % versioning.get_version())

    # Ugly extension of optparse type checking magic :/
    optparse.Option.TYPES += ('config_override',)
    optparse.Option.TYPE_CHECKER['config_override'] = check_config_override

    # NOTE First argument to add_option must be bytestrings on Python < 2.6.2
    # See https://github.com/mopidy/mopidy/issues/302 for details
    parser.add_option(
        b'-q', '--quiet',
        action='store_const', const=0, dest='verbosity_level',
        help='less output (warning level)')
    parser.add_option(
        b'-v', '--verbose',
        action='count', default=1, dest='verbosity_level',
        help='more output (debug level)')
    parser.add_option(
        b'--save-debug-log',
        action='store_true', dest='save_debug_log',
        help='save debug log to "./mopidy.log"')
    parser.add_option(
        b'--show-config',
        action='callback', callback=show_config_callback,
        help='show current config')
    parser.add_option(
        b'--show-deps',
        action='callback', callback=deps.show_deps_optparse_callback,
        help='show dependencies and their versions')
    parser.add_option(
        b'--config',
        action='store', dest='config',
        default=b'$XDG_CONFIG_DIR/mopidy/mopidy.conf',
        help='config files to use, colon seperated, later files override')
    parser.add_option(
        b'-o', b'--option',
        action='append', dest='overrides', type='config_override',
        help='`section/key=value` values to override config options')
    return parser.parse_args(args=mopidy_args)[0]
示例#14
0
def parse_options():
    parser = optparse.OptionParser(
        version='Mopidy %s' % versioning.get_version())
    # NOTE First argument to add_option must be bytestrings on Python < 2.6.2
    # See https://github.com/mopidy/mopidy/issues/302 for details
    parser.add_option(
        b'--help-gst',
        action='store_true', dest='help_gst',
        help='show GStreamer help options')
    parser.add_option(
        b'-i', '--interactive',
        action='store_true', dest='interactive',
        help='ask interactively for required settings which are missing')
    parser.add_option(
        b'-q', '--quiet',
        action='store_const', const=0, dest='verbosity_level',
        help='less output (warning level)')
    parser.add_option(
        b'-v', '--verbose',
        action='count', default=1, dest='verbosity_level',
        help='more output (debug level)')
    parser.add_option(
        b'--save-debug-log',
        action='store_true', dest='save_debug_log',
        help='save debug log to "./mopidy.log"')
    parser.add_option(
        b'--list-settings',
        action='callback',
        callback=settings_utils.list_settings_optparse_callback,
        help='list current settings')
    parser.add_option(
        b'--list-deps',
        action='callback', callback=deps.list_deps_optparse_callback,
        help='list dependencies and their versions')
    parser.add_option(
        b'--debug-thread',
        action='store_true', dest='debug_thread',
        help='run background thread that dumps tracebacks on SIGUSR1')
    return parser.parse_args(args=mopidy_args)[0]
示例#15
0
class SpotifySessionManager(process.BaseThread, PyspotifySessionManager):
    cache_location = None
    settings_location = None
    appkey_file = os.path.join(os.path.dirname(__file__), 'spotify_appkey.key')
    user_agent = 'Mopidy %s' % versioning.get_version()

    def __init__(self, config, audio, backend_ref):

        self.cache_location = config['spotify']['cache_dir']
        self.settings_location = config['spotify']['cache_dir']

        PyspotifySessionManager.__init__(
            self,
            config['spotify']['username'],
            config['spotify']['password'],
            proxy=config['proxy']['hostname'],
            proxy_username=config['proxy']['username'],
            proxy_password=config['proxy']['password'])

        process.BaseThread.__init__(self)
        self.name = 'SpotifyThread'

        self.audio = audio
        self.backend = None
        self.backend_ref = backend_ref

        self.bitrate = config['spotify']['bitrate']

        self.connected = threading.Event()
        self.push_audio_data = True
        self.buffer_timestamp = 0

        self.container_manager = None
        self.playlist_manager = None

        self._initial_data_receive_completed = False

    def run_inside_try(self):
        self.backend = self.backend_ref.proxy()
        self.connect()

    def logged_in(self, session, error):
        """Callback used by pyspotify"""
        if error:
            logger.error('Spotify login error: %s', error)
            return

        logger.info('Connected to Spotify')

        # To work with both pyspotify 1.9 and 1.10
        if not hasattr(self, 'session'):
            self.session = session

        logger.debug('Preferred Spotify bitrate is %d kbps', self.bitrate)
        session.set_preferred_bitrate(BITRATES[self.bitrate])

        self.container_manager = SpotifyContainerManager(self)
        self.playlist_manager = SpotifyPlaylistManager(self)

        self.container_manager.watch(session.playlist_container())

        self.connected.set()

    def logged_out(self, session):
        """Callback used by pyspotify"""
        logger.info('Disconnected from Spotify')
        self.connected.clear()

    def metadata_updated(self, session):
        """Callback used by pyspotify"""
        logger.debug('Callback called: Metadata updated')

    def connection_error(self, session, error):
        """Callback used by pyspotify"""
        if error is None:
            logger.info('Spotify connection OK')
        else:
            logger.error('Spotify connection error: %s', error)
            if self.audio.state.get() == audio.PlaybackState.PLAYING:
                self.backend.playback.pause()

    def message_to_user(self, session, message):
        """Callback used by pyspotify"""
        logger.debug('User message: %s', message.strip())

    def music_delivery(self, session, frames, frame_size, num_frames,
                       sample_type, sample_rate, channels):
        """Callback used by pyspotify"""
        # pylint: disable = R0913
        # Too many arguments (8/5)

        if not self.push_audio_data:
            return 0

        assert sample_type == 0, 'Expects 16-bit signed integer samples'
        capabilites = """
            audio/x-raw-int,
            endianness=(int)1234,
            channels=(int)%(channels)d,
            width=(int)16,
            depth=(int)16,
            signed=(boolean)true,
            rate=(int)%(sample_rate)d
        """ % {
            'sample_rate': sample_rate,
            'channels': channels,
        }

        duration = audio.calculate_duration(num_frames, sample_rate)
        buffer_ = audio.create_buffer(bytes(frames),
                                      capabilites=capabilites,
                                      timestamp=self.buffer_timestamp,
                                      duration=duration)

        self.buffer_timestamp += duration

        if self.audio.emit_data(buffer_).get():
            return num_frames
        else:
            return 0

    def play_token_lost(self, session):
        """Callback used by pyspotify"""
        logger.debug('Play token lost')
        self.backend.playback.pause()

    def log_message(self, session, data):
        """Callback used by pyspotify"""
        logger.debug('System message: %s' % data.strip())
        if 'offline-mgr' in data and 'files unlocked' in data:
            # XXX This is a very very fragile and ugly hack, but we get no
            # proper event when libspotify is done with initial data loading.
            # We delay the expensive refresh of Mopidy's playlists until this
            # message arrives. This way, we avoid doing the refresh once for
            # every playlist or other change. This reduces the time from
            # startup until the Spotify backend is ready from 35s to 12s in one
            # test with clean Spotify cache. In cases with an outdated cache
            # the time improvements should be a lot greater.
            if not self._initial_data_receive_completed:
                self._initial_data_receive_completed = True
                self.refresh_playlists()

    def end_of_track(self, session):
        """Callback used by pyspotify"""
        logger.debug('End of data stream reached')
        self.audio.emit_end_of_stream()

    def refresh_playlists(self):
        """Refresh the playlists in the backend with data from Spotify"""
        if not self._initial_data_receive_completed:
            logger.debug('Still getting data; skipped refresh of playlists')
            return
        playlists = []
        for spotify_playlist in self.session.playlist_container():
            playlists.append(
                translator.to_mopidy_playlist(spotify_playlist,
                                              bitrate=self.bitrate,
                                              username=self.username))
        playlists.append(
            translator.to_mopidy_playlist(self.session.starred(),
                                          bitrate=self.bitrate,
                                          username=self.username))
        playlists = filter(None, playlists)
        self.backend.playlists.playlists = playlists
        logger.info('Loaded %d Spotify playlists', len(playlists))
        BackendListener.send('playlists_loaded')

    def logout(self):
        """Log out from spotify"""
        logger.debug('Logging out from Spotify')

        # To work with both pyspotify 1.9 and 1.10
        if getattr(self, 'session', None):
            self.session.logout()
示例#16
0
 def get_version(self):
     """Get version of the Mopidy core API"""
     return versioning.get_version()
示例#17
0
#source_encoding = 'utf-8'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = 'Mopidy'
copyright = '2010-2012, Stein Magnus Jodal and contributors'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The full version, including alpha/beta/rc tags.
from mopidy.utils.versioning import get_version
release = get_version()
# The short X.Y version.
version = '.'.join(release.split('.')[:2])


# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of documents that shouldn't be included in the build.
示例#18
0

def config_override_type(value):
    try:
        section, remainder = value.split(b'/', 1)
        key, value = remainder.split(b'=', 1)
        return (section.strip(), key.strip(), value.strip())
    except ValueError:
        raise argparse.ArgumentTypeError(
            '%s must have the format section/key=value' % value)


parser = argparse.ArgumentParser()
parser.add_argument('--version',
                    action='version',
                    version='Mopidy %s' % versioning.get_version())
parser.add_argument('-q',
                    '--quiet',
                    action='store_const',
                    const=-1,
                    dest='verbosity_level',
                    help='less output (warning level)')
parser.add_argument('-v',
                    '--verbose',
                    action='count',
                    dest='verbosity_level',
                    help='more output (debug level)')
parser.add_argument('--save-debug-log',
                    action='store_true',
                    dest='save_debug_log',
                    help='save debug log to "./mopidy.log"')
示例#19
0
 def test_version(self):
     self.assertEqual(self.core.version, versioning.get_version())
示例#20
0
def main():
    log.bootstrap_delayed_logging()
    logger.info('Starting Mopidy %s', versioning.get_version())

    signal.signal(signal.SIGTERM, process.exit_handler)
    # Windows does not have signal.SIGUSR1
    if hasattr(signal, 'SIGUSR1'):
        signal.signal(signal.SIGUSR1, pykka.debug.log_thread_tracebacks)

    try:
        registry = ext.Registry()

        root_cmd = commands.RootCommand()
        config_cmd = commands.ConfigCommand()
        deps_cmd = commands.DepsCommand()

        root_cmd.set(extension=None, registry=registry)
        root_cmd.add_child('config', config_cmd)
        root_cmd.add_child('deps', deps_cmd)

        installed_extensions = ext.load_extensions()

        for extension in installed_extensions:
            ext_cmd = extension.get_command()
            if ext_cmd:
                ext_cmd.set(extension=extension)
                root_cmd.add_child(extension.ext_name, ext_cmd)

        args = root_cmd.parse(mopidy_args)

        create_file_structures_and_config(args, installed_extensions)
        check_old_locations()

        config, config_errors = config_lib.load(
            args.config_files, installed_extensions, args.config_overrides)

        verbosity_level = args.base_verbosity_level
        if args.verbosity_level:
            verbosity_level += args.verbosity_level

        log.setup_logging(config, verbosity_level, args.save_debug_log)

        extensions = {
            'validate': [], 'config': [], 'disabled': [], 'enabled': []}
        for extension in installed_extensions:
            if not ext.validate_extension(extension):
                config[extension.ext_name] = {'enabled': False}
                config_errors[extension.ext_name] = {
                    'enabled': 'extension disabled by self check.'}
                extensions['validate'].append(extension)
            elif not config[extension.ext_name]['enabled']:
                config[extension.ext_name] = {'enabled': False}
                config_errors[extension.ext_name] = {
                    'enabled': 'extension disabled by user config.'}
                extensions['disabled'].append(extension)
            elif config_errors.get(extension.ext_name):
                config[extension.ext_name]['enabled'] = False
                config_errors[extension.ext_name]['enabled'] = (
                    'extension disabled due to config errors.')
                extensions['config'].append(extension)
            else:
                extensions['enabled'].append(extension)

        log_extension_info(installed_extensions, extensions['enabled'])

        # Config and deps commands are simply special cased for now.
        if args.command == config_cmd:
            return args.command.run(
                config, config_errors, installed_extensions)
        elif args.command == deps_cmd:
            return args.command.run()

        check_config_errors(config, config_errors, extensions)

        if not extensions['enabled']:
            logger.error('No extension enabled, exiting...')
            sys.exit(1)

        # Read-only config from here on, please.
        proxied_config = config_lib.Proxy(config)

        if args.extension and args.extension not in extensions['enabled']:
            logger.error(
                'Unable to run command provided by disabled extension %s',
                args.extension.ext_name)
            return 1

        for extension in extensions['enabled']:
            extension.setup(registry)

        # Anything that wants to exit after this point must use
        # mopidy.utils.process.exit_process as actors can have been started.
        try:
            return args.command.run(args, proxied_config)
        except NotImplementedError:
            print(root_cmd.format_help())
            return 1

    except KeyboardInterrupt:
        pass
    except Exception as ex:
        logger.exception(ex)
        raise
示例#21
0
class SpotifySessionManager(process.BaseThread, PyspotifySessionManager):
    cache_location = settings.SPOTIFY_CACHE_PATH
    settings_location = cache_location
    appkey_file = os.path.join(os.path.dirname(__file__), 'spotify_appkey.key')
    user_agent = 'Mopidy %s' % versioning.get_version()

    def __init__(self, username, password, audio, backend_ref, proxy=None,
                 proxy_username=None, proxy_password=None):
        PyspotifySessionManager.__init__(
            self, username, password, proxy=proxy,
            proxy_username=proxy_username,
            proxy_password=proxy_password)
        process.BaseThread.__init__(self)
        self.name = 'SpotifyThread'

        self.audio = audio
        self.backend = None
        self.backend_ref = backend_ref

        self.connected = threading.Event()
        self.session = None

        self.container_manager = None
        self.playlist_manager = None

        self._initial_data_receive_completed = False

    def run_inside_try(self):
        self.backend = self.backend_ref.proxy()
        self.connect()

    def logged_in(self, session, error):
        """Callback used by pyspotify"""
        if error:
            logger.error('Spotify login error: %s', error)
            return

        logger.info('Connected to Spotify')
        self.session = session

        logger.debug(
            'Preferred Spotify bitrate is %s kbps',
            settings.SPOTIFY_BITRATE)
        self.session.set_preferred_bitrate(BITRATES[settings.SPOTIFY_BITRATE])

        self.container_manager = SpotifyContainerManager(self)
        self.playlist_manager = SpotifyPlaylistManager(self)

        self.container_manager.watch(self.session.playlist_container())

        self.connected.set()

    def logged_out(self, session):
        """Callback used by pyspotify"""
        logger.info('Disconnected from Spotify')

    def metadata_updated(self, session):
        """Callback used by pyspotify"""
        logger.debug('Callback called: Metadata updated')

    def connection_error(self, session, error):
        """Callback used by pyspotify"""
        if error is None:
            logger.info('Spotify connection OK')
        else:
            logger.error('Spotify connection error: %s', error)
            if self.audio.state.get() == audio.PlaybackState.PLAYING:
                self.backend.playback.pause()

    def message_to_user(self, session, message):
        """Callback used by pyspotify"""
        logger.debug('User message: %s', message.strip())

    def music_delivery(self, session, frames, frame_size, num_frames,
                       sample_type, sample_rate, channels):
        """Callback used by pyspotify"""
        # pylint: disable = R0913
        # Too many arguments (8/5)
        assert sample_type == 0, 'Expects 16-bit signed integer samples'
        capabilites = """
            audio/x-raw-int,
            endianness=(int)1234,
            channels=(int)%(channels)d,
            width=(int)16,
            depth=(int)16,
            signed=(boolean)true,
            rate=(int)%(sample_rate)d
        """ % {
            'sample_rate': sample_rate,
            'channels': channels,
        }
        buffer_ = gst.Buffer(bytes(frames))
        buffer_.set_caps(gst.caps_from_string(capabilites))

        if self.audio.emit_data(buffer_).get():
            return num_frames
        else:
            return 0

    def play_token_lost(self, session):
        """Callback used by pyspotify"""
        logger.debug('Play token lost')
        self.backend.playback.pause()

    def log_message(self, session, data):
        """Callback used by pyspotify"""
        logger.debug('System message: %s' % data.strip())
        if 'offline-mgr' in data and 'files unlocked' in data:
            # XXX This is a very very fragile and ugly hack, but we get no
            # proper event when libspotify is done with initial data loading.
            # We delay the expensive refresh of Mopidy's playlists until this
            # message arrives. This way, we avoid doing the refresh once for
            # every playlist or other change. This reduces the time from
            # startup until the Spotify backend is ready from 35s to 12s in one
            # test with clean Spotify cache. In cases with an outdated cache
            # the time improvements should be a lot greater.
            self._initial_data_receive_completed = True
            self.refresh_playlists()

    def end_of_track(self, session):
        """Callback used by pyspotify"""
        logger.debug('End of data stream reached')
        self.audio.emit_end_of_stream()

    def refresh_playlists(self):
        """Refresh the playlists in the backend with data from Spotify"""
        if not self._initial_data_receive_completed:
            logger.debug('Still getting data; skipped refresh of playlists')
            return
        playlists = map(
            translator.to_mopidy_playlist, self.session.playlist_container())
        playlists = filter(None, playlists)
        self.backend.playlists.playlists = playlists
        logger.info('Loaded %d Spotify playlist(s)', len(playlists))
        BackendListener.send('playlists_loaded')

    def search(self, query, queue):
        """Search method used by Mopidy backend"""
        def callback(results, userdata=None):
            # TODO Include results from results.albums(), etc. too
            # TODO Consider launching a second search if results.total_tracks()
            # is larger than len(results.tracks())
            tracks = [
                translator.to_mopidy_track(t) for t in results.tracks()]
            queue.put(tracks)
        self.connected.wait()
        self.session.search(
            query, callback, track_count=100, album_count=0, artist_count=0)

    def logout(self):
        """Log out from spotify"""
        logger.debug('Logging out from Spotify')
        if self.session:
            self.session.logout()
示例#22
0
文件: conf.py 项目: eisnerd/mopidy
#source_encoding = 'utf-8'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = 'Mopidy'
copyright = '2009-2013, Stein Magnus Jodal and contributors'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The full version, including alpha/beta/rc tags.
from mopidy.utils.versioning import get_version
release = get_version()
# The short X.Y version.
version = '.'.join(release.split('.')[:2])

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of documents that shouldn't be included in the build.
#unused_docs = []
示例#23
0
 def test_version(self):
     self.assertEqual(self.core.version, versioning.get_version())
示例#24
0
 def get_version(self):
     """Get version of the Mopidy core API"""
     return versioning.get_version()
示例#25
0
 def get_version(self):
     return versioning.get_version()