Example #1
0
    def get_soap_header(self):
        """ Generate the SOAP authentication header for the related service.

        This header contains all the necessary authentication details.

        Returns:
            (str): A string representation of the XML content of the SOAP
                header

        """

        # According to the SONOS SMAPI, this header must be sent with all
        # SOAP requests. Building this is an expensive operation (though
        # occasionally necessary), so f we have a cached value, return it
        if self._cached_soap_header is not None:
            return self._cached_soap_header
        music_service = self.music_service
        credentials_header = XML.Element(
            "credentials", {'xmlns': "http://www.sonos.com/Services/1.1"})
        device_id = XML.SubElement(credentials_header, 'deviceId')
        device_id.text = self._device_id
        device_provider = XML.SubElement(credentials_header, 'deviceProvider')
        device_provider.text = 'Sonos'
        if music_service.account.oa_device_id:
            # OAuth account credentials are present. We must use them to
            # authenticate.
            login_token = XML.Element('loginToken')
            token = XML.SubElement(login_token, 'token')
            token.text = music_service.account.oa_device_id
            key = XML.SubElement(login_token, 'key')
            key.text = music_service.account.key
            household_id = XML.SubElement(login_token, 'householdId')
            household_id.text = self._device.household_id
            credentials_header.append(login_token)

        # otherwise, perhaps use DeviceLink or UserId auth
        elif music_service.auth_type in ['DeviceLink', 'UserId']:
            # We need a session ID from Sonos
            session_id = self._device.musicServices.GetSessionId([
                ('ServiceId', music_service.service_id),
                ('Username', music_service.account.username)
            ])['SessionId']
            session_elt = XML.Element('sessionId')
            session_elt.text = session_id
            credentials_header.append(session_elt)

        # Anonymous auth. No need for anything further.
        self._cached_soap_header = XML.tostring(credentials_header)
        return self._cached_soap_header
Example #2
0
    def test_add_item_to_sonos_playlist(self, moco):
        moco.contentDirectory.reset_mock()

        playlist = mock.Mock()
        playlist.item_id = 7

        ressource = mock.Mock()
        ressource.uri = 'fake_uri'
        track = mock.Mock()
        track.resources = [ressource]
        track.uri = 'fake_uri'
        track.to_element.return_value = XML.Element('a')

        update_id = 100

        moco.contentDirectory.Browse.return_value = {
            'NumberReturned': '0',
            'Result':
            '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"></DIDL-Lite>',
            'TotalMatches': '0',
            'UpdateID': update_id
        }

        moco.add_item_to_sonos_playlist(track, playlist)
        moco.contentDirectory.Browse.assert_called_once_with([
            ('ObjectID', playlist.item_id),
            ('BrowseFlag', 'BrowseDirectChildren'), ('Filter', '*'),
            ('StartingIndex', 0), ('RequestedCount', 1), ('SortCriteria', '')
        ])
        moco.avTransport.AddURIToSavedQueue.assert_called_once_with([
            ('InstanceID', 0), ('UpdateID', update_id),
            ('ObjectID', playlist.item_id), ('EnqueuedURI', track.uri),
            ('EnqueuedURIMetaData', to_didl_string(track)),
            ('AddAtIndex', 4294967295)
        ])
Example #3
0
    def get_soap_header(self):
        if self._session_id is None:
            return ''

        if self._cached_soap_header is not None:
            return self._cached_soap_header

        credentials_header = XML.Element(
            "credentials", {'xmlns': "http://www.sonos.com/Services/1.1"})

        if self.music_service.auth_type in ['UserId']:
            session_elt = XML.Element('sessionId')
            session_elt.text = self._session_id
            credentials_header.append(session_elt)
        else:
            raise Exception('unknown auth_type = ' +
                            self.music_service.auth_type)

        self._cached_soap_header = XML.tostring(
            credentials_header, encoding='utf-8').decode(encoding='utf-8')
        return self._cached_soap_header
Example #4
0
    def test_add_item_to_sonos_playlist(self, moco):
        playlist = mock.Mock()
        playlist.item_id = 7

        track = mock.Mock()
        track.uri = 'fake_uri'
        track.didl_metadata = XML.Element('a')

        update_id = 100
        moco._music_lib_search = mock.Mock(return_value=(
            {'UpdateID': update_id},
            None))

        moco.add_item_to_sonos_playlist(track, playlist)
        moco._music_lib_search.assert_called_once_with(playlist.item_id, 0, 1)
        moco.avTransport.AddURIToSavedQueue.assert_called_once_with(
            [('InstanceID', 0),
             ('UpdateID', update_id),
             ('ObjectID', playlist.item_id),
             ('EnqueuedURI', track.uri),
             ('EnqueuedURIMetaData', XML.tostring(track.didl_metadata)),
             ('AddAtIndex', 4294967295)]
        )