Esempio n. 1
0
    def get_feature(  # pylint: disable=too-many-return-statements
            self, feature_name: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature_name == FeatureName.StreamFile:
            return FeatureInfo(FeatureState.Available)

        metadata = EMPTY_METADATA
        if self.playback_manager.playback_info:
            metadata = self.playback_manager.playback_info.metadata

        if feature_name == FeatureName.Title:
            return self._availability(metadata.title)
        if feature_name == FeatureName.Artist:
            return self._availability(metadata.artist)
        if feature_name == FeatureName.Album:
            return self._availability(metadata.album)
        if feature_name in [FeatureName.Position, FeatureName.TotalTime]:
            return self._availability(metadata.duration)

        # As far as known, volume controls are always supported
        if feature_name in [
                FeatureName.SetVolume,
                FeatureName.Volume,
                FeatureName.VolumeDown,
                FeatureName.VolumeUp,
        ]:
            return FeatureInfo(FeatureState.Available)

        if feature_name in [FeatureName.Stop, FeatureName.Pause]:
            is_streaming = self.playback_manager.raop is not None
            return FeatureInfo(FeatureState.Available
                               if is_streaming else FeatureState.Unavailable)

        return FeatureInfo(FeatureState.Unavailable)
Esempio n. 2
0
    def get_feature(self, feature_name: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        has_credentials = self.service.credentials
        if feature_name == FeatureName.PlayUrl and has_credentials:
            return FeatureInfo(FeatureState.Available)

        return FeatureInfo(FeatureState.Unavailable)
Esempio n. 3
0
    def get_feature(self, feature_name: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature_name == FeatureName.PlayUrl and (
                AirPlayFlags.SupportsAirPlayVideoV1 in self._features
                or AirPlayFlags.SupportsAirPlayVideoV2 in self._features):
            return FeatureInfo(FeatureState.Available)

        return FeatureInfo(FeatureState.Unavailable)
Esempio n. 4
0
    def get_feature(self, feature_name: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature_name in MEDIA_CONTROL_MAP:
            is_available = MEDIA_CONTROL_MAP[feature_name] & self._control_flags
            return FeatureInfo(FeatureState.Available
                               if is_available else FeatureState.Unavailable)

        # Just assume these are available for now if the protocol is configured,
        # we don't have any way to verify it anyways.
        if feature_name in SUPPORTED_FEATURES:
            return FeatureInfo(FeatureState.Available)

        return FeatureInfo(FeatureState.Unavailable)
Esempio n. 5
0
    def get_feature(self, feature_name: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature_name == FeatureName.StreamFile:
            return FeatureInfo(FeatureState.Available)

        metadata = self.state_manager.metadata or EMPTY_METADATA
        if feature_name == FeatureName.Title:
            return self._availability(metadata.title)
        if feature_name == FeatureName.Artist:
            return self._availability(metadata.artist)
        if feature_name == FeatureName.Album:
            return self._availability(metadata.album)

        return FeatureInfo(FeatureState.Unavailable)
Esempio n. 6
0
    def get_feature(self, feature_name: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        # Credentials are needed, so cannot be available without them
        if self.service.credentials is not None:
            # Just assume these are available for now if the protocol is configured,
            # we don't have any way to verify it anyways.
            if feature_name in [
                    FeatureName.AppList,
                    FeatureName.LaunchApp,
                    FeatureName.TurnOn,
                    FeatureName.TurnOff,
            ]:
                return FeatureInfo(FeatureState.Available)

        return FeatureInfo(FeatureState.Unavailable)
Esempio n. 7
0
    def get_feature(self, feature: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature in _AVAILABLE_FEATURES:
            return FeatureInfo(state=FeatureState.Available)
        if feature in _UNKNOWN_FEATURES:
            return FeatureInfo(state=FeatureState.Unknown)
        if feature in _FIELD_FEATURES:
            available = self._is_available(_FIELD_FEATURES[feature])
            return FeatureInfo(state=FeatureState.Available
                               if available else FeatureState.Unavailable)
        if feature == FeatureName.PlayUrl:
            if self.config.get_service(Protocol.AirPlay) is not None:
                return FeatureInfo(state=FeatureState.Available)

        return FeatureInfo(state=FeatureState.Unsupported)
Esempio n. 8
0
 def get_feature(self, feature: FeatureName) -> FeatureInfo:
     """Return current state of a feature."""
     if feature not in self.feature_map:
         state = FeatureState.Unsupported
     else:
         state = self.feature_map[feature]
     return FeatureInfo(state=state)
Esempio n. 9
0
    def get_feature(  # pylint: disable=too-many-return-statements
        self, feature_name: FeatureName
    ) -> FeatureInfo:
        """Return current state of a feature."""
        if feature_name in _AVAILABLE_FEATURES:
            return FeatureInfo(state=FeatureState.Available)
        if feature_name in _UNKNOWN_FEATURES:
            return FeatureInfo(state=FeatureState.Unknown)
        if feature_name in _FIELD_FEATURES:
            return FeatureInfo(state=self._is_available(_FIELD_FEATURES[feature_name]))
        if feature_name == FeatureName.VolumeUp:
            return FeatureInfo(state=self._is_available(("cmst", "cavc"), True))
        if feature_name == FeatureName.VolumeDown:
            return FeatureInfo(state=self._is_available(("cmst", "cavc"), True))

        return FeatureInfo(state=FeatureState.Unsupported)
Esempio n. 10
0
    def get_feature(self, feature: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature in _FEATURES_SUPPORTED:
            return FeatureInfo(state=FeatureState.Available)
        if feature == FeatureName.Artwork:
            metadata = self.psm.playing.metadata
            if metadata and metadata.artworkAvailable:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)
        if feature == FeatureName.PlayUrl:
            if self.config.get_service(Protocol.AirPlay) is not None:
                return FeatureInfo(state=FeatureState.Available)

        field_name = _FIELD_FEATURES.get(feature)
        if field_name:
            available = self.psm.playing.metadata_field(field_name) is not None
            return FeatureInfo(state=FeatureState.Available
                               if available else FeatureState.Unavailable)

        # Special case for PlayPause emulation. Based on the behavior in the Youtube
        # app, only the "opposite" feature to current state is available. E.g. if
        # something is playing, then pause will be available but not play. So take that
        # into consideration here.
        if feature == FeatureName.PlayPause:
            playback_state = self.psm.playing.playback_state
            if playback_state == ssm.Playing and self.in_state(
                    FeatureState.Available, FeatureName.Pause):
                return FeatureInfo(state=FeatureState.Available)
            if playback_state == ssm.Paused and self.in_state(
                    FeatureState.Available, FeatureName.Play):
                return FeatureInfo(state=FeatureState.Available)

        cmd_id = _FEATURE_COMMAND_MAP.get(feature)
        if cmd_id:
            cmd = self.psm.playing.command_info(cmd_id)
            if cmd and cmd.enabled:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        if feature == FeatureName.App:
            player_path = self.psm.playing.player_path
            if player_path and player_path.client:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        if feature in [FeatureName.VolumeDown, FeatureName.VolumeUp]:
            if self.psm.volume_controls_available:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        return FeatureInfo(state=FeatureState.Unsupported)
Esempio n. 11
0
 def get_feature(self, feature_name: FeatureName) -> FeatureInfo:
     return FeatureInfo(self.feature_state if feature_name ==
                        self.feature_name else FeatureState.Unsupported)
Esempio n. 12
0
 def _availability(value):
     return FeatureInfo(
         FeatureState.Available if value else FeatureState.Unavailable)
Esempio n. 13
0
 def get_feature(self, feature: FeatureName) -> FeatureInfo:
     """Return current state of a feature."""
     return FeatureInfo(state=self.state)
Esempio n. 14
0
    def get_feature(self, feature: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature in _FEATURES_SUPPORTED:
            return FeatureInfo(state=FeatureState.Available)
        if feature == FeatureName.Artwork:
            metadata = self.psm.playing.metadata
            if metadata and metadata.artworkAvailable:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)
        if feature == FeatureName.PlayUrl:
            if self.config.get_service(Protocol.AirPlay) is not None:
                return FeatureInfo(state=FeatureState.Available)

        field_name = _FIELD_FEATURES.get(feature)
        if field_name:
            available = self.psm.playing.metadata_field(field_name) is not None
            return FeatureInfo(state=FeatureState.Available
                               if available else FeatureState.Unavailable)

        cmd_id = _FEATURE_COMMAND_MAP.get(feature)
        if cmd_id:
            cmd = self.psm.playing.command_info(cmd_id)
            if cmd and cmd.enabled:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        if feature == FeatureName.App:
            if self.psm.playing.client:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        if feature in [FeatureName.VolumeDown, FeatureName.VolumeUp]:
            if self.psm.volume_controls_available is None:
                return FeatureInfo(state=FeatureState.Unknown)
            if self.psm.volume_controls_available:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        return FeatureInfo(state=FeatureState.Unsupported)
Esempio n. 15
0
    def get_feature(  # pylint: disable=too-many-return-statements,too-many-branches
            self, feature_name: FeatureName) -> FeatureInfo:
        """Return current state of a feature."""
        if feature_name in _FEATURES_SUPPORTED:
            return FeatureInfo(state=FeatureState.Available)
        if feature_name == FeatureName.Artwork:
            metadata = self.psm.playing.metadata
            if metadata and metadata.artworkAvailable:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        field_name = _FIELD_FEATURES.get(feature_name)
        if field_name:
            available = self.psm.playing.metadata_field(field_name) is not None
            return FeatureInfo(state=FeatureState.Available
                               if available else FeatureState.Unavailable)

        # Special case for PlayPause emulation. Based on the behavior in the Youtube
        # app, only the "opposite" feature to current state is available. E.g. if
        # something is playing, then pause will be available but not play. So take that
        # into consideration here.
        if feature_name == FeatureName.PlayPause:
            playback_state = self.psm.playing.playback_state
            if playback_state == PlaybackState.Playing and self.in_state(
                    FeatureState.Available, FeatureName.Pause):
                return FeatureInfo(state=FeatureState.Available)
            if playback_state == PlaybackState.Paused and self.in_state(
                    FeatureState.Available, FeatureName.Play):
                return FeatureInfo(state=FeatureState.Available)

        cmd_id = _FEATURE_COMMAND_MAP.get(feature_name)
        if cmd_id:
            cmd = self.psm.playing.command_info(cmd_id)
            if cmd and cmd.enabled:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        if feature_name == FeatureName.App:
            if self.psm.client:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        if feature_name in [
                FeatureName.VolumeDown,
                FeatureName.VolumeUp,
                FeatureName.Volume,
                FeatureName.SetVolume,
        ]:
            if self.audio.is_available:
                return FeatureInfo(state=FeatureState.Available)
            return FeatureInfo(state=FeatureState.Unavailable)

        return FeatureInfo(state=FeatureState.Unsupported)