示例#1
0
 def test_parse_strings(self):
     in_data = tags.string_tag('stra', '') + \
               tags.string_tag('strb', 'test string')
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(2, len(parsed))
     self.assertEqual('', parser.first(parsed, 'stra'))
     self.assertEqual('test string', parser.first(parsed, 'strb'))
示例#2
0
 def test_parse_bool(self):
     in_data = tags.bool_tag('bola', True) + \
               tags.bool_tag('bolb', False)
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(2, len(parsed))
     self.assertTrue(parser.first(parsed, 'bola'))
     self.assertFalse(parser.first(parsed, 'bolb'))
示例#3
0
def test_parse_strings():
    in_data = tags.string_tag("stra", "") + tags.string_tag(
        "strb", "test string")
    parsed = parser.parse(in_data, lookup_tag)
    assert 2 == len(parsed)
    assert "" == parser.first(parsed, "stra")
    assert "test string" == parser.first(parsed, "strb")
示例#4
0
 def test_parse_strings(self):
     in_data = tags.string_tag("stra", "") + tags.string_tag(
         "strb", "test string")
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(2, len(parsed))
     self.assertEqual("", parser.first(parsed, "stra"))
     self.assertEqual("test string", parser.first(parsed, "strb"))
示例#5
0
 def test_parse_value_in_container(self):
     in_data = tags.container_tag(
         "cona",
         tags.uint8_tag("uuu8", 36) + tags.uint16_tag("uu16", 13000))
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(1, len(parsed))
     inner = parser.first(parsed, "cona")
     self.assertEqual(2, len(inner))
     self.assertEqual(36, parser.first(inner, "uuu8"))
     self.assertEqual(13000, parser.first(inner, "uu16"))
示例#6
0
def test_parse_value_in_container():
    in_data = tags.container_tag(
        "cona",
        tags.uint8_tag("uuu8", 36) + tags.uint16_tag("uu16", 13000))
    parsed = parser.parse(in_data, lookup_tag)
    assert 1 == len(parsed)
    inner = parser.first(parsed, "cona")
    assert 2 == len(inner)
    assert 36 == parser.first(inner, "uuu8")
    assert 13000 == parser.first(inner, "uu16")
示例#7
0
def test_parse_uint_of_various_lengths():
    in_data = (tags.uint8_tag("uuu8", 12) + tags.uint16_tag("uu16", 37888) +
               tags.uint32_tag("uu32", 305419896) +
               tags.uint64_tag("uu64", 8982983289232))
    parsed = parser.parse(in_data, lookup_tag)
    assert 4 == len(parsed)
    assert 12 == parser.first(parsed, "uuu8")
    assert 37888 == parser.first(parsed, "uu16")
    assert 305419896 == parser.first(parsed, "uu32")
    assert 8982983289232 == parser.first(parsed, "uu64")
示例#8
0
 def test_parse_value_in_container(self):
     in_data = tags.container_tag('cona',
                                  tags.uint8_tag('uuu8', 36) +
                                  tags.uint16_tag('uu16', 13000))
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(1, len(parsed))
     inner = parser.first(parsed, 'cona')
     self.assertEqual(2, len(inner))
     self.assertEqual(36, parser.first(inner, 'uuu8'))
     self.assertEqual(13000, parser.first(inner, 'uu16'))
示例#9
0
 def test_parse_uint_of_various_lengths(self):
     in_data = (tags.uint8_tag("uuu8", 12) +
                tags.uint16_tag("uu16", 37888) +
                tags.uint32_tag("uu32", 305419896) +
                tags.uint64_tag("uu64", 8982983289232))
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(4, len(parsed))
     self.assertEqual(12, parser.first(parsed, "uuu8"))
     self.assertEqual(37888, parser.first(parsed, "uu16"))
     self.assertEqual(305419896, parser.first(parsed, "uu32"))
     self.assertEqual(8982983289232, parser.first(parsed, "uu64"))
示例#10
0
    async def test_succesful_pairing(self):
        await self._start()

        url = self._pairing_url(PAIRING_CODE)
        data, _ = await utils.simple_get(url, self.loop)

        # Verify content returned in pairingresponse
        parsed = parser.parse(data, tag_definitions.lookup_tag)
        self.assertEqual(parser.first(parsed, 'cmpa', 'cmpg'), 1)
        self.assertEqual(parser.first(parsed, 'cmpa', 'cmnm'), REMOTE_NAME)
        self.assertEqual(parser.first(parsed, 'cmpa', 'cmty'), 'iPhone')
示例#11
0
 def handle_set_parameter(self,
                          request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming SET_PARAMETER request."""
     _LOGGER.debug("Received SET_PARAMETER: %s", request)
     if request.headers["Content-Type"] == "application/x-dmap-tagged":
         tags = parser.parse(request.body, lookup_tag)
         self.state.metadata.title = parser.first(tags, "mlit", "minm")
         self.state.metadata.artist = parser.first(tags, "mlit", "asar")
         self.state.metadata.album = parser.first(tags, "mlit", "asal")
     return HttpResponse("RTSP", "1.0", 200, "OK",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#12
0
 def test_parse_uint_of_various_lengths(self):
     in_data = tags.uint8_tag('uuu8', 12) + \
               tags.uint16_tag('uu16', 37888) + \
               tags.uint32_tag('uu32', 305419896) + \
               tags.uint64_tag('uu64', 8982983289232)
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(4, len(parsed))
     self.assertEqual(12, parser.first(parsed, 'uuu8'))
     self.assertEqual(37888, parser.first(parsed, 'uu16'))
     self.assertEqual(305419896, parser.first(parsed, 'uu32'))
     self.assertEqual(8982983289232, parser.first(parsed, 'uu64'))
示例#13
0
async def test_succesful_pairing(mock_pairing):
    pairing, zeroconf, service = await mock_pairing()

    url = pairing_url(zeroconf, PAIRING_CODE)
    data, _ = await utils.simple_get(url)

    await pairing.finish()

    # Verify content returned in pairingresponse
    parsed = parser.parse(data, tag_definitions.lookup_tag)
    assert parser.first(parsed, "cmpa", "cmpg") == 1
    assert parser.first(parsed, "cmpa", "cmnm") == REMOTE_NAME
    assert parser.first(parsed, "cmpa", "cmty") == "iPhone"

    assert service.credentials == PAIRING_GUID
示例#14
0
def test_parse_binary_plist():
    data = {"key": "value"}
    in_data = tags.raw_tag("plst", plistlib.dumps(data,
                                                  fmt=plistlib.FMT_BINARY))
    parsed = parser.parse(in_data, lookup_tag)
    assert 1 == len(parsed)
    assert data, parser.first(parsed, "plst")
示例#15
0
 def test_parse_binary_plist(self):
     data = {"key": "value"}
     in_data = tags.raw_tag("plst",
                            plistlib.dumps(data, fmt=plistlib.FMT_BINARY))
     parsed = parser.parse(in_data, lookup_tag)
     self.assertEqual(1, len(parsed))
     self.assertEqual(data, parser.first(parsed, "plst"))
示例#16
0
    def media_type(self):
        """Type of media is currently playing, e.g. video, music."""
        state = parser.first(self.playstatus, "cmst", "caps")
        if not state:
            return MediaType.Unknown

        mediakind = parser.first(self.playstatus, "cmst", "cmmk")
        if mediakind is not None:
            return daap.media_kind(mediakind)

        # Fallback: if artist or album exists we assume music (not present
        # for video)
        if self.artist or self.album:
            return MediaType.Music

        return MediaType.Video
示例#17
0
    async def perform_pairing(self, remote_name, expected_code, port):
        """Pair with a remote client.

        This will perform a GET-request to the specified port and hand over
        information to the client (pyatv) so that the pairing process can be
        completed.
        """
        server = f"http://127.0.0.1:{port}"
        url = f"{server}/pairing?pairingcode={expected_code}&servicename=test"
        data, _ = await utils.simple_get(url)

        # Verify content returned in pairingresponse
        parsed = parser.parse(data, tag_definitions.lookup_tag)
        assert parser.first(parsed, "cmpa", "cmpg") == 1
        assert parser.first(parsed, "cmpa", "cmnm") == remote_name
        assert parser.first(parsed, "cmpa", "cmty") == "iPhone"
示例#18
0
 def _is_available(self, field: tuple, expected_value=None) -> FeatureState:
     if self.apple_tv.latest_playstatus:
         value = parser.first(self.apple_tv.latest_playstatus, *field)
         if value is not None:
             if not expected_value or expected_value == value:
                 return FeatureState.Available
     return FeatureState.Unavailable
示例#19
0
    def media_type(self):
        """Type of media is currently playing, e.g. video, music."""
        state = parser.first(self.playstatus, 'cmst', 'caps')
        if not state:
            return const.MEDIA_TYPE_UNKNOWN

        mediakind = parser.first(self.playstatus, 'cmst', 'cmmk')
        if mediakind is not None:
            return convert.media_kind(mediakind)

        # Fallback: if artist or album exists we assume music (not present
        # for video)
        if self.artist or self.album:
            return const.MEDIA_TYPE_MUSIC

        return const.MEDIA_TYPE_VIDEO
示例#20
0
    async def perform_pairing(self, pairing_response, port):
        """Pair with a remote client.

        This will perform a GET-request to the specified port and hand over
        information to the client (pyatv) so that the pairing process can be
        completed.
        """
        server = 'http://127.0.0.1:{}'.format(port)
        url = '{}/pairing?pairingcode={}&servicename=test'.format(
            server, pairing_response.pairing_code)
        data, _ = await utils.simple_get(url, self.loop)

        # Verify content returned in pairingresponse
        parsed = parser.parse(data, tag_definitions.lookup_tag)
        self.tc.assertEqual(parser.first(parsed, 'cmpa', 'cmpg'), 1)
        self.tc.assertEqual(parser.first(parsed, 'cmpa', 'cmnm'),
                            pairing_response.remote_name)
        self.tc.assertEqual(parser.first(parsed, 'cmpa', 'cmty'), 'iPhone')
示例#21
0
    def shuffle(self):
        """If shuffle is enabled or not."""
        state = parser.first(self.playstatus, "cmst", "cash")
        if state is None or state == 0:
            return ShuffleState.Off

        # DMAP does not support the "albums" state and will always report
        # "songs" if shuffle is active
        return ShuffleState.Songs
示例#22
0
    async def test_pair_custom_pairing_guid(self):
        await self._start(pin_code=PIN_CODE2, pairing_guid=PAIRING_GUID2)

        url = self._pairing_url(PAIRING_CODE2)
        data, _ = await utils.simple_get(url, self.loop)

        # Verify content returned in pairingresponse
        parsed = parser.parse(data, tag_definitions.lookup_tag)
        self.assertEqual(parser.first(parsed, 'cmpa', 'cmpg'),
                         int(PAIRING_GUID2, 16))
示例#23
0
 def _convert_button(data):
     value = parser.first(data, 'cmbe')
     if value == 'touchUp&time=6&point=20,250':
         return 'up'
     elif value == 'touchUp&time=6&point=20,275':
         return 'down'
     elif value == 'touchUp&time=7&point=50,100':
         return 'left'
     elif value == 'touchUp&time=7&point=75,100':
         return 'right'
     else:
         return value
示例#24
0
    async def playstatus(self, use_revision=False, timeout=None):
        """Request raw data about what is currently playing.

        If use_revision=True, this command will "block" until playstatus
        changes on the device.

        Must be logged in.
        """
        cmd_url = _PSU_CMD.format(
            self.playstatus_revision if use_revision else 0)
        resp = await self.daap.get(cmd_url, timeout=timeout)
        self.playstatus_revision = parser.first(resp, 'cmst', 'cmsr')
        return resp
示例#25
0
    async def login(self):
        """Login to Apple TV using specified login id."""
        # Do not use session.get_data(...) in login as that would end up in
        # an infinite loop.
        def _login_request():
            url = self._mkurl("login?[AUTH]&hasFP=1", session=False, login_id=True)
            _login_request.log_text = "Login request: " + url
            return self.http.get_data(url, headers=_DMAP_HEADERS,)

        resp = await self._do(_login_request, is_login=True)
        self._session_id = parser.first(resp, "mlog", "mlid")

        _LOGGER.info("Logged in and got session id %s", self._session_id)
        return self._session_id
示例#26
0
async def test_pair_custom_pairing_guid(mock_pairing):
    pairing, zeroconf, service = await mock_pairing(pin_code=PIN_CODE2,
                                                    pairing_guid=PAIRING_GUID2)

    url = pairing_url(zeroconf, PAIRING_CODE2)
    data, _ = await utils.simple_get(url)

    await pairing.finish()

    # Verify content returned in pairingresponse
    parsed = parser.parse(data, tag_definitions.lookup_tag)
    assert parser.first(parsed, "cmpa", "cmpg") == int(PAIRING_GUID2, 16)

    assert service.credentials == PAIRING_GUID2
示例#27
0
    def _convert_button(self, data):
        value = parser.first(data, 'cmbe')

        # Consider navigation buttons if six commands have been received
        if self.buttons_press_count == 6:
            if value == 'touchUp&time=6&point=20,250':
                return 'up'
            elif value == 'touchUp&time=6&point=20,275':
                return 'down'
            elif value == 'touchUp&time=7&point=50,100':
                return 'left'
            elif value == 'touchUp&time=7&point=75,100':
                return 'right'

        return value
示例#28
0
    async def login(self):
        """Login to Apple TV using specified login id."""
        # Do not use session.get_data(...) in login as that would end up in
        # an infinte loop.
        def _login_request():
            return self.http.get_data(
                self._mkurl('login?[AUTH]&hasFP=1',
                            session=False, login_id=True),
                headers=_DMAP_HEADERS)

        resp = await self._do(_login_request, is_login=True)
        self._session_id = parser.first(resp, 'mlog', 'mlid')

        _LOGGER.info('Logged in and got session id %s', self._session_id)
        return self._session_id
示例#29
0
    def _convert_button(self, data):
        value = parser.first(data, "cmbe")

        # Consider navigation buttons if six commands have been received
        if self.buttons_press_count == 6:
            if value == "touchUp&time=6&point=20,250":
                return "up"
            elif value == "touchUp&time=6&point=20,275":
                return "down"
            elif value == "touchUp&time=7&point=50,100":
                return "left"
            elif value == "touchUp&time=7&point=75,100":
                return "right"

        return value
示例#30
0
    async def playstatus(self, use_revision=False, timeout=None):
        """Request raw data about what is currently playing.

        If use_revision=True, this command will "block" until playstatus
        changes on the device.

        Must be logged in.
        """
        cmd_url = _PSU_CMD.format(self.playstatus_revision if use_revision else 0)
        resp = await self.daap.get(cmd_url, timeout=timeout)
        self.playstatus_revision = parser.first(resp, "cmst", "cmsr")
        self.latest_playstatus = resp
        self.latest_playing = build_playing_instance(resp)
        self.latest_hash = self.latest_playing.hash
        return self.latest_playing