pyatv.interface — pyatv 0.0.1 documentation

# Source code for pyatv.interface

    """API exposed by the library."""

    import re
    import inspect

    from abc import (ABCMeta, abstractmethod, abstractproperty)

    from pyatv import exceptions

    # TODO: make these methods more pretty and safe
    def _get_first_sentence_in_pydoc(obj):
        doc = obj.__doc__
        index = doc.find('.')
        if index == -1:
            # Here we have no leading . so return everything
            return doc
        else:
            # Try to find the first complete sentence and respect
            # abbreviations correctly
            match = re.findall(r'(.*\.[^A-Z]*)\.(?: [A-Z].*|)', doc)
            if len(match) == 1:
                return match[0]
            else:
                return doc[0:index]

    def retrieve_commands(obj, developer=False):
        """Retrieve all commands and help texts from an API object."""
        commands = {}  # Name and help
        for member in [obj]+obj.__class__.mro():
            for func in member.__dict__:
                if not inspect.isfunction(member.__dict__[func]) and \
                   not isinstance(member.__dict__[func], property):
                    continue
                if func.startswith('_'):
                    continue
                if func.startswith('dev_') and not developer:
                    continue
                commands[func] = _get_first_sentence_in_pydoc(
                    member.__dict__[func])
        return commands

    class RemoteControl(object):
        """Base class for API used to control an Apple TV."""

        __metaclass__ = ABCMeta

        # pylint: disable=invalid-name
        @abstractmethod
        def up(self):
            """Press key up."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def down(self):
            """Press key down."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def left(self):
            """Press key left."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def right(self):
            """Press key right."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def play(self):
            """Press key play."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def pause(self):
            """Press key play."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def next(self):
            """Press key next."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def previous(self):
            """Press key previous."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def select(self):
            """Press key select."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def menu(self):
            """Press key menu."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def topmenu(self):
            """Go to main menu (long press menu)."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def set_position(self, pos):
            """Seek in the current playing media."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def play_url(self, url, start_position=0, port=7000):
            """Play media from an URL on the device."""
            raise exceptions.NotSupportedError

    class Playing(object):
        """Base class for retrieving what is currently playing."""

        __metaclass__ = ABCMeta

        @abstractproperty
        def media_type(self):
            """What type of media is currently playing, e.g. video, music."""
            raise exceptions.NotSupportedError

        @abstractproperty
        def play_state(self):
            """Current play state, e.g. playing or paused."""
            raise exceptions.NotSupportedError

        @abstractproperty
        def title(self):
            """Title of the current media, e.g. movie or song name."""
            raise exceptions.NotSupportedError

        @abstractproperty
        def artist(self):
            """Artist of the currently playing song."""
            raise exceptions.NotSupportedError

        @abstractproperty
        def album(self):
            """Album of the currently playing song."""
            raise exceptions.NotSupportedError

        @abstractproperty
        def total_time(self):
            """Total play time in seconds."""
            raise exceptions.NotSupportedError

        @abstractproperty
        def position(self):
            """Current position in the playing media (seconds)."""
            raise exceptions.NotSupportedError

    # pylint: disable=too-few-public-methods
    class Metadata(object):
        """Base class for retrieving metadata from an Apple TV."""

        __metaclass__ = ABCMeta

        @abstractmethod
        def artwork(self):
            """Return artwork for what is currently playing (or None)."""
            raise exceptions.NotSupportedError

        @abstractmethod
        def playing(self):
            """Return what is currently playing."""
            raise exceptions.NotSupportedError

    class AppleTV(object):
        """Base class representing an Apple TV."""

        __metaclass__ = ABCMeta

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

            Not needed as login is performed automatically.
            """
            raise exceptions.NotSupportedError

        @abstractmethod
        def logout(self):
            """Perform an explicit logout.

            Must be done when session is no longer needed to not leak resources.
            """
            raise exceptions.NotSupportedError

        @abstractproperty
        def remote_control(self):
            """Return API for controlling the Apple TV."""
            raise exceptions.NotSupportedError

        @abstractproperty
        def metadata(self):
            """Return API for retrieving metadata from the Apple TV."""
            raise exceptions.NotSupportedError