Example #1
0
async def main():
    print('Jukebox Pi')

    signal.signal(signal.SIGINT, signal_handler)

    client = MPDClient()
    atexit.register(client.disconnect)

    lcd = LCD(make_callback(client))
    lcd.turn_on()
    atexit.register(lcd.stop)

    clock = Clock(lcd)
    atexit.register(clock.stop)

    try:
        await client.connect('localhost', 6600)
    except Exception as e:
        print('Connection to MPD failed:', e)
        return

    print('Connected to MPD version ', client.mpd_version)

    current_status = await get_status(client)
    show_track(lcd, clock, {}, current_status)

    async for _ in client.idle(['player']):
        status = await get_status(client)
        print(status)

        show_track(lcd, clock, current_status, status)
        current_status = status
Example #2
0
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.mpd = MPDClient()

        self._playlist_empty = asyncio.Event()
        self._adding_song = False
Example #3
0
    def __init__(self, server, port, password, name):
        """Initialize the MPD device."""
        self.server = server
        self.port = port
        self._name = name
        self.password = password

        self._status = None
        self._currentsong = None
        self._playlists = None
        self._currentplaylist = None
        self._is_connected = False
        self._muted = False
        self._muted_volume = None
        self._media_position_updated_at = None
        self._media_position = None
        self._media_image_hash = None
        # Track if the song changed so image doesn't have to be loaded every update.
        self._media_image_file = None
        self._commands = None

        # set up MPD client
        self._client = MPDClient()
        self._client.timeout = 30
        self._client.idletimeout = None
Example #4
0
    async def setup_mpd(self, mpd_server: str) -> None:
        self.mpd = MPDClient()
        await self.mpd.connect(mpd_server)

        # get initial state of outputs
        async for output in self.mpd.outputs():
            output = MPDOutput(output)
            self.mpd_outputs[output.name] = output

        # add idle command to to event loop
        self._loop.create_task(self.listen_mpd())
Example #5
0
async def main():
    print("Create MPD client")
    client = MPDClient()
    try:
        await client.connect('localhost', 6600)
    except Exception as e:
        print("Connection failed:", e)
        return

    print("Connected to MPD version", client.mpd_version)

    try:
        status = await client.status()
    except Exception as e:
        print("Status error:", e)
        return
    else:
        print("Status success:", status)

    print(list(await client.commands()))

    import time
    start = time.time()
    for x in await client.listall():
        print("sync:", x)
        print("Time to first sync:", time.time() - start)
        break

    start = time.time()
    async for x in client.listall():
        print("async:", x)
        print("Time to first async:", time.time() - start)
        break

    try:
        await client.addid()
    except Exception as e:
        print("An erroneous command, as expected, raised:", e)

    try:
        async for x in client.plchangesposid():
            print("Why does this work?")
    except Exception as e:
        print("An erroneous asynchronously looped command, as expected, raised:", e)

    i = 0
    async for subsystem in client.idle():
        print("Idle change in", subsystem)
        i += 1
        if i > 5:
            print("Enough changes, quitting")
            break
Example #6
0
async def main():
    print("Create MPD client")
    client = MPDClient()
    try:
        await client.connect('localhost', 6600)
    except Exception as e:
        print("Connection failed:", e)
        return

    print("Connected to MPD version", client.mpd_version)

    try:
        status = await client.status()
    except Exception as e:
        print("Status error:", e)
        return
    else:
        print("Status success:", status)

    print(list(await client.commands()))

    import time
    start = time.time()
    for x in await client.listall():
        print("sync:", x)
        print("Time to first sync:", time.time() - start)
        break

    start = time.time()
    async for x in client.listall():
        print("async:", x)
        print("Time to first async:", time.time() - start)
        break

    try:
        await client.addid()
    except Exception as e:
        print("An erroneous command, as expected, raised:", e)

    try:
        async for x in client.plchangesposid():
            print("Why does this work?")
    except Exception as e:
        print("An erroneous asynchronously looped command, as expected, raised:", e)

    i = 0
    async for subsystem in client.idle():
        print("Idle change in", subsystem)
        i += 1
        if i > 5:
            print("Enough changes, quitting")
            break
Example #7
0
    def __init__(self, sfavs):
        # Do Startup tasks
        super().__init__("Library", "Lib", "Locally Stored Audio")
        self.sfavs = sfavs

        self.mpdc = MPDClient()
        self.loop = asyncio.get_event_loop()
        self.REQ_MET_MPD = False

        self.start_client()

        # This is part of the Streaming hierarchy
        self.component = "library"
        # Local pointers into the radio state and the streaming client
        # Zero the client state on startup
        self.clear_client()

        # Setup the menu items
        self.favs_save_file = "saved/{}_favorites.json".format(self.component)
        self.favorites_node.menu_labels['comment'] = "Library Favorites"
        self.favorites_node.component = self.component
        self.load_favorites()

        self.playlists_node = LibraryMenuList("Playlists", "Pls", "My playlists.")
        self.add_child(self.playlists_node)
        self.genres_node = LibraryMenuList("Genres", "Gnr", "Library By Genre")
        self.add_child(self.genres_node)
        self.artists_node = LibraryMenuList("Artists", "Art", "Library By Artist")
        self.add_child(self.artists_node)
        self.albums_node = LibraryMenuList("Albums", "Alb", "Library By Album")
        self.add_child(self.albums_node)

        # Populate the Library
        asyncio.run_coroutine_threadsafe(self.refresh_library(), self.loop)
Example #8
0
class MPDConnection:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.mpd = MPDClient()

        self._playlist_empty = asyncio.Event()
        self._adding_song = False

    async def start(self):
        await self.mpd.connect(self.host, self.port)
        asyncio.ensure_future(self._event_loop())

    async def wait_for_song(self):
        '''Returns when the playlist is empty'''
        await self._playlist_empty.wait()

    def is_ready(self):
        '''Immediately returns true if the playlist is empty, false otherwise.'''
        return self._playlist_empty.is_set()

    async def add_to_playlist(self, url):
        if self._adding_song:
            raise Exception

        self._adding_song = True
        self._playlist_empty.clear()
        print()
        print(url)
        print()
        try:
            await self.mpd.add(url)
            await self.mpd.play()
        except mpd.CommandError:
            pass
        self._adding_song = False

    async def skip(self):
        await self.mpd.clear()

    async def _event_loop(self):
        while True:
            status = await self.mpd.status()
            if status['playlistlength'] == '0':
                if not self._adding_song:
                    self._playlist_empty.set()
            else:
                self._playlist_empty.clear()

            async for subsystems in self.mpd.idle():
                if 'playlist' in subsystems or 'player' in subsystems:
                    break
Example #9
0
    def __init__(self, server, port, password, name):
        """Initialize the MPD device."""
        self.server = server
        self.port = port
        self._name = name
        self.password = password

        self._status = None
        self._currentsong = None
        self._playlists = None
        self._currentplaylist = None
        self._is_connected = False
        self._muted = False
        self._muted_volume = None
        self._media_position_updated_at = None
        self._media_position = None
        self._commands = None

        # set up MPD client
        self._client = MPDClient()
        self._client.timeout = 30
        self._client.idletimeout = None
Example #10
0
async def main(*, host='127.0.0.1', port=50051):
    client = MPDClient()

    await client.connect('localhost', 6600)

    print(f'mpd version: {client.mpd_version}')

    queue = asyncio.Queue()
    commands_queue = asyncio.Queue()

    task1 = asyncio.create_task(worker(queue))  # TODO: remove
    task2 = asyncio.create_task(notifier(client, commands_queue))

    server = Server([WallboxApi(commands_queue, queue, client)])

    with graceful_exit([server]):
        await server.start(host, port)
        await server.wait_closed()

    task1.cancel()
    task2.cancel()
    client.disconnect()
Example #11
0
class MpdDevice(MediaPlayerEntity):
    """Representation of a MPD server."""

    # pylint: disable=no-member
    def __init__(self, server, port, password, name):
        """Initialize the MPD device."""
        self.server = server
        self.port = port
        self._name = name
        self.password = password

        self._status = None
        self._currentsong = None
        self._playlists = None
        self._currentplaylist = None
        self._is_connected = False
        self._muted = False
        self._muted_volume = None
        self._media_position_updated_at = None
        self._media_position = None
        self._media_image_hash = None
        # Track if the song changed so image doesn't have to be loaded every update.
        self._media_image_file = None
        self._commands = None

        # set up MPD client
        self._client = MPDClient()
        self._client.timeout = 30
        self._client.idletimeout = None

    async def _connect(self):
        """Connect to MPD."""
        try:
            await self._client.connect(self.server, self.port)

            if self.password is not None:
                await self._client.password(self.password)
        except mpd.ConnectionError:
            return

        self._is_connected = True

    def _disconnect(self):
        """Disconnect from MPD."""
        with suppress(mpd.ConnectionError):
            self._client.disconnect()
        self._is_connected = False
        self._status = None

    async def _fetch_status(self):
        """Fetch status from MPD."""
        self._status = await self._client.status()
        self._currentsong = await self._client.currentsong()
        await self._async_update_media_image_hash()

        if (position := self._status.get("elapsed")) is None:
            position = self._status.get("time")

            if isinstance(position, str) and ":" in position:
                position = position.split(":")[0]

        if position is not None and self._media_position != position:
            self._media_position_updated_at = dt_util.utcnow()
            self._media_position = int(float(position))

        await self._update_playlists()
Example #12
0
 def __init__(self, host, port):
     self.host, self.port = host, port
     self.client = MPDClient()
class MpdDevice(MediaPlayerEntity):
    """Representation of a MPD server."""

    # pylint: disable=no-member
    def __init__(self, server, port, password, name):
        """Initialize the MPD device."""
        self.server = server
        self.port = port
        self._name = name
        self.password = password

        self._status = None
        self._currentsong = None
        self._playlists = None
        self._currentplaylist = None
        self._is_connected = False
        self._muted = False
        self._muted_volume = None
        self._media_position_updated_at = None
        self._media_position = None
        self._commands = None

        # set up MPD client
        self._client = MPDClient()
        self._client.timeout = 30
        self._client.idletimeout = None

    async def _connect(self):
        """Connect to MPD."""
        try:
            await self._client.connect(self.server, self.port)

            if self.password is not None:
                await self._client.password(self.password)
        except mpd.ConnectionError:
            return

        self._is_connected = True

    def _disconnect(self):
        """Disconnect from MPD."""
        try:
            self._client.disconnect()
        except mpd.ConnectionError:
            pass
        self._is_connected = False
        self._status = None

    async def _fetch_status(self):
        """Fetch status from MPD."""
        self._status = await self._client.status()
        self._currentsong = await self._client.currentsong()

        position = self._status.get("elapsed")

        if position is None:
            position = self._status.get("time")

            if isinstance(position, str) and ":" in position:
                position = position.split(":")[0]

        if position is not None and self._media_position != position:
            self._media_position_updated_at = dt_util.utcnow()
            self._media_position = int(float(position))

        await self._update_playlists()

    @property
    def available(self):
        """Return true if MPD is available and connected."""
        return self._is_connected

    async def async_update(self):
        """Get the latest data and update the state."""
        try:
            if not self._is_connected:
                await self._connect()
                self._commands = list(await self._client.commands())

            await self._fetch_status()
        except (mpd.ConnectionError, OSError, BrokenPipeError,
                ValueError) as error:
            # Cleanly disconnect in case connection is not in valid state
            _LOGGER.debug("Error updating status: %s", error)
            self._disconnect()

    @property
    def name(self):
        """Return the name of the device."""
        return self._name

    @property
    def state(self):
        """Return the media state."""
        if self._status is None:
            return STATE_OFF
        if self._status["state"] == "play":
            return STATE_PLAYING
        if self._status["state"] == "pause":
            return STATE_PAUSED
        if self._status["state"] == "stop":
            return STATE_OFF

        return STATE_OFF

    @property
    def is_volume_muted(self):
        """Boolean if volume is currently muted."""
        return self._muted

    @property
    def media_content_id(self):
        """Return the content ID of current playing media."""
        return self._currentsong.get("file")

    @property
    def media_content_type(self):
        """Return the content type of current playing media."""
        return MEDIA_TYPE_MUSIC

    @property
    def media_duration(self):
        """Return the duration of current playing media in seconds."""
        # Time does not exist for streams
        return self._currentsong.get("time")

    @property
    def media_position(self):
        """Position of current playing media in seconds.

        This is returned as part of the mpd status rather than in the details
        of the current song.
        """
        return self._media_position

    @property
    def media_position_updated_at(self):
        """Last valid time of media position."""
        return self._media_position_updated_at

    @property
    def media_title(self):
        """Return the title of current playing media."""
        name = self._currentsong.get("name", None)
        title = self._currentsong.get("title", None)
        file_name = self._currentsong.get("file", None)

        if name is None and title is None:
            if file_name is None:
                return "None"
            return os.path.basename(file_name)
        if name is None:
            return title
        if title is None:
            return name

        return f"{name}: {title}"

    @property
    def media_artist(self):
        """Return the artist of current playing media (Music track only)."""
        return self._currentsong.get("artist")

    @property
    def media_album_name(self):
        """Return the album of current playing media (Music track only)."""
        return self._currentsong.get("album")

    @property
    def media_image_hash(self):
        """Hash value for media image."""
        file = self._currentsong.get("file")
        if file:
            return hashlib.sha256(file.encode("utf-8")).hexdigest()[:16]

        return None

    async def async_get_media_image(self):
        """Fetch media image of current playing track."""
        file = self._currentsong.get("file")
        if not file:
            return None, None

        # not all MPD implementations and versions support the `albumart` and `fetchpicture` commands
        can_albumart = "albumart" in self._commands
        can_readpicture = "readpicture" in self._commands

        response = None

        # read artwork embedded into the media file
        if can_readpicture:
            try:
                response = await self._client.readpicture(file)
            except mpd.CommandError as error:
                _LOGGER.warning(
                    "Retrieving artwork through `readpicture` command failed: %s",
                    error,
                )

        # read artwork contained in the media directory (cover.{jpg,png,tiff,bmp}) if none is embedded
        if can_albumart and not response:
            try:
                response = await self._client.albumart(file)
            except mpd.CommandError as error:
                _LOGGER.warning(
                    "Retrieving artwork through `albumart` command failed: %s",
                    error,
                )

        if not response:
            return None, None

        image = bytes(response.get("binary"))
        mime = response.get(
            "type", "image/png")  # readpicture has type, albumart does not
        return (image, mime)

    @property
    def volume_level(self):
        """Return the volume level."""
        if "volume" in self._status:
            return int(self._status["volume"]) / 100
        return None

    @property
    def supported_features(self):
        """Flag media player features that are supported."""
        if self._status is None:
            return 0

        supported = SUPPORT_MPD
        if "volume" in self._status:
            supported |= SUPPORT_VOLUME_SET | SUPPORT_VOLUME_STEP | SUPPORT_VOLUME_MUTE
        if self._playlists is not None:
            supported |= SUPPORT_SELECT_SOURCE

        return supported

    @property
    def source(self):
        """Name of the current input source."""
        return self._currentplaylist

    @property
    def source_list(self):
        """Return the list of available input sources."""
        return self._playlists

    async def async_select_source(self, source):
        """Choose a different available playlist and play it."""
        await self.async_play_media(MEDIA_TYPE_PLAYLIST, source)

    @Throttle(PLAYLIST_UPDATE_INTERVAL)
    async def _update_playlists(self, **kwargs):
        """Update available MPD playlists."""
        try:
            self._playlists = []
            for playlist_data in await self._client.listplaylists():
                self._playlists.append(playlist_data["playlist"])
        except mpd.CommandError as error:
            self._playlists = None
            _LOGGER.warning("Playlists could not be updated: %s:", error)

    async def async_set_volume_level(self, volume):
        """Set volume of media player."""
        if "volume" in self._status:
            await self._client.setvol(int(volume * 100))

    async def async_volume_up(self):
        """Service to send the MPD the command for volume up."""
        if "volume" in self._status:
            current_volume = int(self._status["volume"])

            if current_volume <= 100:
                self._client.setvol(current_volume + 5)

    async def async_volume_down(self):
        """Service to send the MPD the command for volume down."""
        if "volume" in self._status:
            current_volume = int(self._status["volume"])

            if current_volume >= 0:
                await self._client.setvol(current_volume - 5)

    async def async_media_play(self):
        """Service to send the MPD the command for play/pause."""
        if self._status["state"] == "pause":
            await self._client.pause(0)
        else:
            await self._client.play()

    async def async_media_pause(self):
        """Service to send the MPD the command for play/pause."""
        await self._client.pause(1)

    async def async_media_stop(self):
        """Service to send the MPD the command for stop."""
        await self._client.stop()

    async def async_media_next_track(self):
        """Service to send the MPD the command for next track."""
        await self._client.next()

    async def async_media_previous_track(self):
        """Service to send the MPD the command for previous track."""
        await self._client.previous()

    async def async_mute_volume(self, mute):
        """Mute. Emulated with set_volume_level."""
        if "volume" in self._status:
            if mute:
                self._muted_volume = self.volume_level
                await self.async_set_volume_level(0)
            elif self._muted_volume is not None:
                await self.async_set_volume_level(self._muted_volume)
            self._muted = mute

    async def async_play_media(self, media_type, media_id, **kwargs):
        """Send the media player the command for playing a playlist."""
        _LOGGER.debug("Playing playlist: %s", media_id)
        if media_type == MEDIA_TYPE_PLAYLIST:
            if media_id in self._playlists:
                self._currentplaylist = media_id
            else:
                self._currentplaylist = None
                _LOGGER.warning("Unknown playlist name %s", media_id)
            await self._client.clear()
            await self._client.load(media_id)
            await self._client.play()
        else:
            await self._client.clear()
            self._currentplaylist = None
            await self._client.add(media_id)
            await self._client.play()

    @property
    def repeat(self):
        """Return current repeat mode."""
        if self._status["repeat"] == "1":
            if self._status["single"] == "1":
                return REPEAT_MODE_ONE
            return REPEAT_MODE_ALL
        return REPEAT_MODE_OFF

    async def async_set_repeat(self, repeat):
        """Set repeat mode."""
        if repeat == REPEAT_MODE_OFF:
            await self._client.repeat(0)
            await self._client.single(0)
        else:
            await self._client.repeat(1)
            if repeat == REPEAT_MODE_ONE:
                await self._client.single(1)
            else:
                await self._client.single(0)

    @property
    def shuffle(self):
        """Boolean if shuffle is enabled."""
        return bool(int(self._status["random"]))

    async def async_set_shuffle(self, shuffle):
        """Enable/disable shuffle mode."""
        await self._client.random(int(shuffle))

    async def async_turn_off(self):
        """Service to send the MPD the command to stop playing."""
        await self._client.stop()

    async def async_turn_on(self):
        """Service to send the MPD the command to start playing."""
        await self._client.play()
        await self._update_playlists(no_throttle=True)

    async def async_clear_playlist(self):
        """Clear players playlist."""
        await self._client.clear()

    async def async_media_seek(self, position):
        """Send seek command."""
        await self._client.seekcur(position)
Example #14
0
import mpd
from mpd.asyncio import MPDClient

import json

client = MPDClient()

# Переподключение в случае отвала cоединения 
def reconnect(func):
    async def wrapper(*args):
        try:
            return await func(*args)
        except mpd.ConnectionError:
            await client.connect("localhost", 6600)
            return await func(*args)

    return wrapper

############## Базовое управление плеером
@reconnect
async def get_status():
    return await client.status()

@reconnect
async def get_current_song():
    return await client.currentsong()

@reconnect
async def get_start_status():
    data = {
        'song': await client.currentsong(),
Example #15
0
class MpdSnapcastSyncer:
    def __init__(self, loop):
        self._logger = logging.getLogger(self.__class__.__name__)
        self._loop = loop
        self.mpd_outputs = {}

    async def setup(self, snapcast_server: str, mpd_server: str) -> None:
        snapcast_task = asyncio.create_task(self.setup_snapcast(snapcast_server))
        mpd_task = asyncio.create_task(self.setup_mpd(mpd_server))
        await snapcast_task
        await mpd_task

    def snapcast_client_changed(self, client: snapcast.control.client.Snapclient) -> None:
        self._loop.create_task(self.async_snapcast_client_changed(client))

    async def async_snapcast_client_changed(self, client: snapcast.control.client.Snapclient) -> None:
        name = client.friendly_name
        try:
            output = self.mpd_outputs[name]
        except KeyError:
            # there is no output named like this Snapcast client, ignore event
            self._logger.debug('Ignoring change of snapcast client %s: No matching MPD output' % name)
            return

        if output.enabled != client.muted:
            # If the output is not enabled and the client is muted (or vice
            # versa), everything is fine.
            return

        self._logger.info('Turning %s MPD output %s' % (
            'off' if client.muted else 'on',
            name
        ))

        # determine which method to call
        actor = self.mpd.disableoutput if client.muted else self.mpd.enableoutput

        # fake stored state of the output to avoid calling
        # mpd_output_changed() from mpd_outputs_changed() when MPD notifies us
        # about our own change
        self.mpd_outputs[name].enabled = not self.mpd_outputs[name].enabled

        # call actual actor method
        await actor(output.id)

    async def mpd_outputs_changed(self) -> None:
        async for output in self.mpd.outputs():
            output = MPDOutput(output)
            try:
                # find stored data about this output
                old_output = self.mpd_outputs[output.name]
            except KeyError:
                # the output didn't exist before, don't trigger any action
                pass
            else:
                if output.enabled != old_output.enabled:
                    # the output's enabled state changed
                    await self.mpd_output_changed(output)

            # update our stored copy of output data
            self.mpd_outputs[output.name] = output

    async def mpd_output_changed(self, output: dict) -> None:
        for client in self.snapcast.clients:
            if client.friendly_name != output.name:
                continue

            self._logger.info('%s snapcast client %s (%s)' % (
                'Unmuting' if output.enabled else 'Muting',
                output.name,
                client.identifier
            ))
            await client.set_muted(not output.enabled)
            return
        else:
            self._logger.debug('Ignoring change of MPD output %s: No matching snapcast client' % output.name)

    async def setup_snapcast(self, snapcast_server: str) -> None:
        self.snapcast = await snapcast.control.create_server(
            self._loop,
            snapcast_server,
        )

        for client in self.snapcast.clients:
            client.set_callback(self.snapcast_client_changed)
            self._logger.debug('Set callback for snapcast client %s' % client.friendly_name)

    async def setup_mpd(self, mpd_server: str) -> None:
        self.mpd = MPDClient()
        await self.mpd.connect(mpd_server)

        # get initial state of outputs
        async for output in self.mpd.outputs():
            output = MPDOutput(output)
            self.mpd_outputs[output.name] = output

        # add idle command to to event loop
        self._loop.create_task(self.listen_mpd())

    async def listen_mpd(self) -> None:
        async for event in self.mpd.idle(['output']):
            await self.mpd_outputs_changed()
Example #16
0
class StreamingComponent(AudioComponent):
    def __init__(self, sfavs, cpo):
        # Do Startup tasks
        super().__init__("Streaming", "Str", "Streaming Audio Services")

        # We have our own mpd client
        self.mpdc = MPDClient()
        self.loop = asyncio.get_event_loop()
        self.REQ_MET_MPD = False
        # Use a return value here to set up fitness?
        self.start_client()

        # Features
        self.enable_dirble = False

        # This is part of the Streaming hierarchy
        self.component = "streaming"
        # Config parser object
        self.cpo = cpo
        # Zero the client state on startup
        self.mpdc.clear()
        # Super favorites
        self.sfavs = sfavs

        # Set up the areas of the component

        self.favs_save_file = "saved/{}_favorites.json".format(self.component)
        self.favorites_node.menu_labels['comment'] = "Streaming Favorites"
        self.favorites_node.component = self.component
        self.load_favorites()

        self.custom_node = StreamingMenuList("Custom", "Cstm",
                                             "My custom stations")
        self.dirble_node = StreamingMenuList("Dirble", "Drbl",
                                             "Streaming Audio Directory")

        self.add_child(self.custom_node)
        if self.enable_dirble:
            self.add_child(self.dirble_node)

        # Reference Streaming menu in the superfavorites

        # Testing purposes, set up custom stations (backed from where?)
        custom_stations = [
            StreamingOpus("AncientFM",
                          "Early music.",
                          "http://5.152.208.98:8058/",
                          self.mpdc,
                          genre="Classical",
                          subgenre="Early"),
            StreamingOpus("Venice Classsic Radio",
                          "Beautiful classical music.",
                          "http://174.36.206.197:8000/stream",
                          self.mpdc,
                          genre="Classical"),
            StreamingOpus("Bartok Radio",
                          "Hungarian classical radio.",
                          "http://mr-stream.mediaconnect.hu/4741/mr3.mp3",
                          self.mpdc,
                          genre="Classical"),
        ]
        # Populate the custom menu
        for station in custom_stations:
            self.custom_node.add_child(station)

        # When we add an opus to a collection, we want to keep track of the genre/subgenre structure?

    def start_client(self):
        return self.loop.run_until_complete(self.__async__start_client())

    async def __async__start_client(self):
        try:
            await self.mpdc.connect('localhost', 6600)
        except Exception as e:
            print("Connection failed:", e)
            self.REQ_MET_MPD = False
        self.mpdc.consume(0)

    def requirements_met(self):
        # req_met = True
        #
        # if not self.REQ_MET_MPD:
        #     req_met = False

        return True

    def save_favorites(self):
        favs = []
        for fav in self.favorites_node.children:
            favs.append(fav.opus_get_metadata())

        json_favs = json.dumps(favs)

        with open(self.favs_save_file, mode='w', encoding='utf-8') as the_file:
            the_file.write(json_favs)

    def load_favorites(self):
        try:
            with open(self.favs_save_file, mode='r',
                      encoding='utf-8') as the_file:
                favs = json.loads(the_file.read())
                for fav in favs:
                    this_opus = StreamingOpus(fav['name'], fav['comment'],
                                              fav['url'], self.mpdc,
                                              fav['genre'], fav['subgenre'])
                    self.favorites_node.add_child(this_opus)
                self.sfavs.update_one_favorite_menu(self)
        except json.JSONDecodeError:
            pass
        except FileNotFoundError:
            pass
Example #17
0
    # Kill MPD if necessary?
    pass


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Server settings")
    parser.add_argument("--port", type=int)
    args = vars(parser.parse_args())

    logger.info("Starting up..")

    cp = ConfigParser()

    cp.read('opuscule-config.ini')

    mpdc = MPDClient()

    op = OpusculeController(cp)

    connected_clients = []

    startup()

    op_port = cp.get('main', 'port')

    if args['port']:
        op_port = args['port']

    loop = asyncio.get_event_loop()

    start_mpd_client()
Example #18
0
 def __init__(self):
     self.host, self.port = settings.MPD_HOST, settings.MPD_PORT
     self.client = MPDClient()
Example #19
0
    def __init__(self, sfavs, cpo):
        # Do Startup tasks
        super().__init__("Streaming", "Str", "Streaming Audio Services")

        # We have our own mpd client
        self.mpdc = MPDClient()
        self.loop = asyncio.get_event_loop()
        self.REQ_MET_MPD = False
        # Use a return value here to set up fitness?
        self.start_client()

        # Features
        self.enable_dirble = False

        # This is part of the Streaming hierarchy
        self.component = "streaming"
        # Config parser object
        self.cpo = cpo
        # Zero the client state on startup
        self.mpdc.clear()
        # Super favorites
        self.sfavs = sfavs

        # Set up the areas of the component

        self.favs_save_file = "saved/{}_favorites.json".format(self.component)
        self.favorites_node.menu_labels['comment'] = "Streaming Favorites"
        self.favorites_node.component = self.component
        self.load_favorites()

        self.custom_node = StreamingMenuList("Custom", "Cstm",
                                             "My custom stations")
        self.dirble_node = StreamingMenuList("Dirble", "Drbl",
                                             "Streaming Audio Directory")

        self.add_child(self.custom_node)
        if self.enable_dirble:
            self.add_child(self.dirble_node)

        # Reference Streaming menu in the superfavorites

        # Testing purposes, set up custom stations (backed from where?)
        custom_stations = [
            StreamingOpus("AncientFM",
                          "Early music.",
                          "http://5.152.208.98:8058/",
                          self.mpdc,
                          genre="Classical",
                          subgenre="Early"),
            StreamingOpus("Venice Classsic Radio",
                          "Beautiful classical music.",
                          "http://174.36.206.197:8000/stream",
                          self.mpdc,
                          genre="Classical"),
            StreamingOpus("Bartok Radio",
                          "Hungarian classical radio.",
                          "http://mr-stream.mediaconnect.hu/4741/mr3.mp3",
                          self.mpdc,
                          genre="Classical"),
        ]
        # Populate the custom menu
        for station in custom_stations:
            self.custom_node.add_child(station)