Example #1
0
    def __init__(
        self,
        loop,
        session_manager: ClientSessionManager,
        config: conf.AppleTV,
        airplay: Stream,
    ) -> None:
        """Initialize a new Apple TV."""
        super().__init__()
        self._session_manager = session_manager
        self._config = config
        self._dmap_service = config.get_service(Protocol.DMAP)
        assert self._dmap_service is not None
        daap_http = net.HttpSession(
            session_manager.session,
            f"http://{config.address}:{self._dmap_service.port}/",
        )
        self._requester = DaapRequester(daap_http,
                                        self._dmap_service.credentials)

        self._apple_tv = BaseDmapAppleTV(self._requester)
        self._dmap_remote = DmapRemoteControl(self._apple_tv)
        self._dmap_metadata = DmapMetadata(config.identifier, self._apple_tv)
        self._dmap_power = DmapPower()
        self._dmap_push_updater = DmapPushUpdater(loop, self._apple_tv, self)
        self._dmap_features = DmapFeatures(config, self._apple_tv)
        self._airplay = airplay
Example #2
0
class DmapAppleTV(AppleTV):
    """Implementation of API support for Apple TV."""

    # This is a container class so it's OK with many attributes
    # pylint: disable=too-many-instance-attributes
    def __init__(self, loop, session, config, airplay):
        """Initialize a new Apple TV."""
        super().__init__()
        self._session = session

        self._dmap_service = config.get_service(Protocol.DMAP)
        daap_http = HttpSession(
            session, 'http://{0}:{1}/'.format(config.address,
                                              self._dmap_service.port))
        self._requester = DaapRequester(daap_http,
                                        self._dmap_service.credentials)

        self._apple_tv = BaseDmapAppleTV(self._requester)
        self._dmap_remote = DmapRemoteControl(self._apple_tv)
        self._dmap_metadata = DmapMetadata(config.identifier, self._apple_tv)
        self._dmap_push_updater = DmapPushUpdater(loop, self._apple_tv, self)
        self._airplay = airplay

    def connect(self):
        """Initiate connection to device.

        No need to call it yourself, it's done automatically.
        """
        return self._requester.login()

    async def close(self):
        """Close connection and release allocated resources."""
        if net.is_custom_session(self._session):
            await self._session.close()

    @property
    def service(self):
        """Return service used to connect to the Apple TV.."""
        return self._dmap_service

    @property
    def remote_control(self):
        """Return API for controlling the Apple TV."""
        return self._dmap_remote

    @property
    def metadata(self):
        """Return API for retrieving metadata from Apple TV."""
        return self._dmap_metadata

    @property
    def push_updater(self):
        """Return API for handling push update from the Apple TV."""
        return self._dmap_push_updater

    @property
    def airplay(self):
        """Return API for working with AirPlay."""
        return self._airplay
Example #3
0
    def __init__(self, loop, session, config, airplay):
        """Initialize a new Apple TV."""
        super().__init__()
        self._session = session

        self._dmap_service = config.get_service(Protocol.DMAP)
        daap_http = HttpSession(
            session,
            'http://{0}:{1}/'.format(config.address, self._dmap_service.port))
        self._requester = DaapRequester(
            daap_http, self._dmap_service.credentials)

        self._apple_tv = BaseDmapAppleTV(self._requester)
        self._dmap_remote = DmapRemoteControl(self._apple_tv)
        self._dmap_metadata = DmapMetadata(config.identifier, self._apple_tv)
        self._dmap_push_updater = DmapPushUpdater(loop, self._apple_tv, self)
        self._airplay = airplay
Example #4
0
    def __init__(self, loop, session, details, airplay):
        """Initialize a new Apple TV."""
        super().__init__()
        self._session = session

        self._dmap_service = details.get_service(const.PROTOCOL_DMAP)
        daap_http = HttpSession(
            session, 'http://{0}:{1}/'.format(details.address,
                                              self._dmap_service.port))
        self._requester = DaapRequester(daap_http,
                                        self._dmap_service.device_credentials)

        self._apple_tv = BaseDmapAppleTV(self._requester)
        self._dmap_remote = DmapRemoteControl(self._apple_tv)
        self._dmap_metadata = DmapMetadata(self._apple_tv, daap_http)
        self._dmap_push_updater = DmapPushUpdater(loop, self._apple_tv)
        self._dmap_pairing = pairing.DmapPairingHandler(loop)
        self._airplay = airplay
Example #5
0
def setup(
    loop: asyncio.AbstractEventLoop,
    config: conf.AppleTV,
    interfaces: Dict[Any, Relayer],
    device_listener: StateProducer,
    session_manager: ClientSessionManager,
) -> Optional[
    Tuple[Callable[[], Awaitable[None]], Callable[[], None], Set[FeatureName]]
]:
    """Set up a new DMAP service."""
    service = config.get_service(Protocol.DMAP)
    assert service is not None

    daap_http = HttpSession(
        session_manager.session,
        f"http://{config.address}:{service.port}/",
    )
    requester = DaapRequester(daap_http, service.credentials)
    apple_tv = BaseDmapAppleTV(requester)
    push_updater = DmapPushUpdater(loop, apple_tv, device_listener)
    metadata = DmapMetadata(config.identifier, apple_tv)

    interfaces[RemoteControl].register(DmapRemoteControl(apple_tv), Protocol.DMAP)
    interfaces[Metadata].register(metadata, Protocol.DMAP)
    interfaces[Power].register(DmapPower(), Protocol.DMAP)
    interfaces[PushUpdater].register(push_updater, Protocol.DMAP)
    interfaces[Features].register(DmapFeatures(config, apple_tv), Protocol.DMAP)

    async def _connect() -> None:
        await requester.login()

    def _close() -> None:
        push_updater.stop()
        device_listener.listener.connection_closed()

    # Features managed by this protocol
    features = set([FeatureName.VolumeDown, FeatureName.VolumeUp])
    features.update(_AVAILABLE_FEATURES)
    features.update(_UNKNOWN_FEATURES)
    features.update(_FIELD_FEATURES.keys())

    return _connect, _close, features
Example #6
0
class DmapAppleTV(AppleTV):
    """Implementation of API support for Apple TV."""

    # This is a container class so it's OK with many attributes
    # pylint: disable=too-many-instance-attributes
    def __init__(self, loop, session, details, airplay):
        """Initialize a new Apple TV."""
        super().__init__()
        self._session = session

        self._dmap_service = details.get_service(const.PROTOCOL_DMAP)
        daap_http = HttpSession(
            session, 'http://{0}:{1}/'.format(details.address,
                                              self._dmap_service.port))
        self._requester = DaapRequester(daap_http,
                                        self._dmap_service.device_credentials)

        self._apple_tv = BaseDmapAppleTV(self._requester)
        self._dmap_remote = DmapRemoteControl(self._apple_tv)
        self._dmap_metadata = DmapMetadata(self._apple_tv, daap_http)
        self._dmap_push_updater = DmapPushUpdater(loop, self._apple_tv)
        self._dmap_pairing = pairing.DmapPairingHandler(loop)
        self._airplay = airplay

    def login(self):
        """Perform an explicit login.

        Not needed as login is performed automatically.
        """
        return self._requester.login()

    async def logout(self):
        """Perform an explicit logout.

        Must be done when session is no longer needed to not leak resources.
        """
        await self._session.close()

    @property
    def service(self):
        """Return service used to connect to the Apple TV.."""
        return self._dmap_service

    @property
    def pairing(self):
        """Return API for pairing with the Apple TV."""
        return self._dmap_pairing

    @property
    def remote_control(self):
        """Return API for controlling the Apple TV."""
        return self._dmap_remote

    @property
    def metadata(self):
        """Return API for retrieving metadata from Apple TV."""
        return self._dmap_metadata

    @property
    def push_updater(self):
        """Return API for handling push update from the Apple TV."""
        return self._dmap_push_updater

    @property
    def airplay(self):
        """Return API for working with AirPlay."""
        return self._airplay