fixed browsing item to request ID association

This commit is contained in:
Boernsman 2019-10-21 08:28:27 +02:00
parent ac3ce25b6b
commit 0a388cd012
4 changed files with 72 additions and 54 deletions

View File

@ -1,4 +1,4 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * *
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io * * Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io *
* * * *
@ -95,7 +95,7 @@ void DevicePluginSonos::setupDevice(DeviceSetupInfo *info)
connect(sonos, &Sonos::volumeReceived, this, &DevicePluginSonos::onVolumeReceived); connect(sonos, &Sonos::volumeReceived, this, &DevicePluginSonos::onVolumeReceived);
connect(sonos, &Sonos::actionExecuted, this, &DevicePluginSonos::onActionExecuted); connect(sonos, &Sonos::actionExecuted, this, &DevicePluginSonos::onActionExecuted);
connect(sonos, &Sonos::authenticationStatusChanged, this, &DevicePluginSonos::onAuthenticationStatusChanged); connect(sonos, &Sonos::authenticationStatusChanged, this, &DevicePluginSonos::onAuthenticationStatusChanged);
connect(sonos, &Sonos::favouritesReceived, this, &DevicePluginSonos::onFavouritesReceived); connect(sonos, &Sonos::favoritesReceived, this, &DevicePluginSonos::onFavoritesReceived);
sonos->getAccessTokenFromRefreshToken(refreshToken); sonos->getAccessTokenFromRefreshToken(refreshToken);
m_sonosConnections.insert(device, sonos); m_sonosConnections.insert(device, sonos);
return info->finish(Device::DeviceErrorNoError); return info->finish(Device::DeviceErrorNoError);
@ -343,24 +343,26 @@ void DevicePluginSonos::browseDevice(BrowseResult *result)
{ {
Device *parentDevice = myDevices().findById(result->device()->parentId()); Device *parentDevice = myDevices().findById(result->device()->parentId());
Sonos *sonosConnection = m_sonosConnections.value(parentDevice); Sonos *sonosConnection = m_sonosConnections.value(parentDevice);
if (!sonosConnection) if (!sonosConnection) {
result->finish(Device::DeviceErrorHardwareNotAvailable);
return; return;
}
qDebug(dcSonos()) << "Browse Device" << result->itemId(); qDebug(dcSonos()) << "Browse Device" << result->itemId();
QString householdId = result->device()->paramValue(sonosGroupDeviceHouseholdIdParamTypeId).toString(); QString householdId = result->device()->paramValue(sonosGroupDeviceHouseholdIdParamTypeId).toString();
if (result->itemId().isEmpty()){ if (result->itemId().isEmpty()){
BrowserItem item; BrowserItem item;
item.setId("/favorites"); item.setId(m_browseFavoritesPrefix);
item.setIcon(BrowserItem::BrowserIconFavorites); item.setIcon(BrowserItem::BrowserIconFavorites);
item.setExecutable(false); item.setExecutable(false);
item.setBrowsable(true); item.setBrowsable(true);
item.setDisplayName("Favorites"); item.setDisplayName("Favorites");
result->addItem(item); result->addItem(item);
result->finish(Device::DeviceErrorNoError); result->finish(Device::DeviceErrorNoError);
} else if (result->itemId() == "/favorites") { } else if (result->itemId() == m_browseFavoritesPrefix) {
sonosConnection->getFavorites(householdId); QUuid requestId = sonosConnection->getFavorites(householdId);
m_pendingBrowseResult.insert(householdId, result); m_pendingBrowseResult.insert(requestId, result);
connect(result, &BrowseResult::aborted,[householdId, this](){m_pendingBrowseResult.remove(householdId);}); connect(result, &BrowseResult::aborted,[requestId, this](){m_pendingBrowseResult.remove(requestId);});
} else { } else {
//TODO add media browsing //TODO add media browsing
result->finish(Device::DeviceErrorItemNotFound); result->finish(Device::DeviceErrorItemNotFound);
@ -371,15 +373,20 @@ void DevicePluginSonos::browserItem(BrowserItemResult *result)
{ {
Device *parentDevice = myDevices().findById(result->device()->parentId()); Device *parentDevice = myDevices().findById(result->device()->parentId());
Sonos *sonosConnection = m_sonosConnections.value(parentDevice); Sonos *sonosConnection = m_sonosConnections.value(parentDevice);
if (!sonosConnection) if (!sonosConnection) {
result->finish(Device::DeviceErrorHardwareNotAvailable);
return; return;
}
qCDebug(dcSonos()) << "Browser Item" << result->itemId(); qCDebug(dcSonos()) << "Browser Item" << result->itemId();
QString householdId = result->device()->paramValue(sonosGroupDeviceHouseholdIdParamTypeId).toString(); QString householdId = result->device()->paramValue(sonosGroupDeviceHouseholdIdParamTypeId).toString();
if (result->itemId().startsWith("/favorites")) { if (result->itemId().startsWith(m_browseFavoritesPrefix)) {
sonosConnection->getFavorites(householdId); QUuid requestId = sonosConnection->getFavorites(householdId);
m_pendingBrowserItemResult.insert(householdId, result); m_pendingBrowserItemResult.insert(requestId, result);
connect(result, &BrowserItemResult::aborted,[householdId, this](){m_pendingBrowserItemResult.remove(householdId);}); connect(result, &BrowserItemResult::aborted, [requestId, this](){m_pendingBrowserItemResult.remove(requestId);});
} else {
//TODO add media browsing
result->finish(Device::DeviceErrorItemNotFound);
} }
} }
@ -391,11 +398,15 @@ void DevicePluginSonos::executeBrowserItem(BrowserActionInfo *info)
return; return;
QString groupId = info->device()->paramValue(sonosGroupDeviceGroupIdParamTypeId).toString(); QString groupId = info->device()->paramValue(sonosGroupDeviceGroupIdParamTypeId).toString();
if (info->browserAction().itemId().startsWith("/favorites")) { if (info->browserAction().itemId().startsWith(m_browseFavoritesPrefix)) {
QString favoriteId = info->browserAction().itemId().remove("/favorite/"); QString favoriteId = info->browserAction().itemId().remove(m_browseFavoritesPrefix);
favoriteId.remove('/');
QUuid requestId = sonosConnection->loadFavorite(groupId, favoriteId); QUuid requestId = sonosConnection->loadFavorite(groupId, favoriteId);
m_pendingBrowserExecution.insert(requestId, info); m_pendingBrowserExecution.insert(requestId, info);
connect(info, &BrowserActionInfo::aborted,[requestId, this](){m_pendingBrowserExecution.remove(requestId);}); connect(info, &BrowserActionInfo::aborted,[requestId, this](){m_pendingBrowserExecution.remove(requestId);});
} else {
//TODO add media browsing
info->finish(Device::DeviceErrorItemNotFound);
} }
} }
@ -438,51 +449,54 @@ void DevicePluginSonos::onHouseholdIdsReceived(QList<QString> householdIds)
} }
} }
void DevicePluginSonos::onFavouritesReceived(const QString &householdId, QList<Sonos::FavouriteObject> favourites) void DevicePluginSonos::onFavoritesReceived(QUuid requestId, const QString &householdId, QList<Sonos::FavoriteObject> favorites)
{ {
if (m_pendingBrowseResult.contains(householdId)) { Q_UNUSED(householdId)
BrowseResult *result = m_pendingBrowseResult.take(householdId);
if (m_pendingBrowseResult.contains(requestId)) {
BrowseResult *result = m_pendingBrowseResult.take(requestId);
if (!result) if (!result)
return; return;
foreach(Sonos::FavouriteObject favourite, favourites) { foreach(Sonos::FavoriteObject favorite, favorites) {
MediaBrowserItem item; MediaBrowserItem item;
item.setId(result->itemId() + "/" + favourite.id); item.setId(result->itemId() + "/" + favorite.id);
item.setExecutable(true); item.setExecutable(true);
item.setBrowsable(false); item.setBrowsable(false);
if (!favourite.imageUrl.isEmpty()) { if (!favorite.imageUrl.isEmpty()) {
item.setThumbnail(favourite.imageUrl); item.setThumbnail(favorite.imageUrl);
} else { } else {
item.setIcon(BrowserItem::BrowserIconFavorites); item.setIcon(BrowserItem::BrowserIconFavorites);
} }
item.setDisplayName(favourite.name); item.setDisplayName(favorite.name);
item.setDescription(favourite.description); item.setDescription(favorite.description);
result->addItem(item); result->addItem(item);
qDebug(dcSonos()) << "Favourite: " << favourite.name << favourite.description; qDebug(dcSonos()) << "Favorite: " << favorite.name << favorite.description;
} }
result->finish(Device::DeviceErrorNoError); result->finish(Device::DeviceErrorNoError);
}
if (m_pendingBrowserItemResult.contains(householdId)) { } else if (m_pendingBrowserItemResult.contains(requestId)) {
BrowserItemResult *result = m_pendingBrowserItemResult.take(householdId); BrowserItemResult *result = m_pendingBrowserItemResult.take(requestId);
if (!result) if (!result)
return; return;
QString favoriteId = result->itemId().remove("/favorites/"); QString favoriteId = result->itemId().remove(m_browseFavoritesPrefix);
favoriteId.remove('/');
foreach(Sonos::FavouriteObject favourite, favourites) { foreach(Sonos::FavoriteObject favorite, favorites) {
if (favourite.id == favoriteId) { if (favorite.id == favoriteId) {
MediaBrowserItem item; MediaBrowserItem item;
item.setId(result->itemId()); item.setId(result->itemId());
item.setExecutable(true); item.setExecutable(true);
item.setBrowsable(false); item.setBrowsable(false);
if (!favourite.imageUrl.isEmpty()) { if (!favorite.imageUrl.isEmpty()) {
item.setThumbnail(favourite.imageUrl); item.setThumbnail(favorite.imageUrl);
} else { } else {
item.setIcon(BrowserItem::BrowserIconFavorites); item.setIcon(BrowserItem::BrowserIconFavorites);
} }
item.setDisplayName(favourite.name); item.setDisplayName(favorite.name);
item.setDescription(favourite.description); item.setDescription(favorite.description);
result->finish(item); result->finish(item);
return;
} }
} }
} }

View File

@ -65,17 +65,18 @@ private:
QByteArray m_sonosConnectionRefreshToken; QByteArray m_sonosConnectionRefreshToken;
QHash<QUuid, QPointer<DeviceActionInfo> > m_pendingActions; QHash<QUuid, QPointer<DeviceActionInfo> > m_pendingActions;
QHash<QString, BrowseResult *> m_pendingBrowseResult; QHash<QUuid, BrowseResult *> m_pendingBrowseResult;
QHash<QString, BrowserItemResult *> m_pendingBrowserItemResult; QHash<QUuid, BrowserItemResult *> m_pendingBrowserItemResult;
QHash<QUuid, BrowserActionInfo *> m_pendingBrowserExecution; QHash<QUuid, BrowserActionInfo *> m_pendingBrowserExecution;
const QString m_browseFavoritesPrefix = "/favorites";
private slots: private slots:
void onConnectionChanged(bool connected); void onConnectionChanged(bool connected);
void onAuthenticationStatusChanged(bool authenticated); void onAuthenticationStatusChanged(bool authenticated);
void onHouseholdIdsReceived(QList<QString> householdIds); void onHouseholdIdsReceived(QList<QString> householdIds);
void onFavouritesReceived(const QString &householdId, QList<Sonos::FavouriteObject> favourites); void onFavoritesReceived(QUuid requestId, const QString &householdId, QList<Sonos::FavoriteObject> favorites);
void onPlaylistsReceived(const QString &householdId, QList<Sonos::PlaylistObject> playlists); void onPlaylistsReceived(const QString &householdId, QList<Sonos::PlaylistObject> playlists);
void onPlaylistSummaryReceived(const QString &householdId, Sonos::PlaylistSummaryObject playlistSummary); void onPlaylistSummaryReceived(const QString &householdId, Sonos::PlaylistSummaryObject playlistSummary);

View File

@ -158,15 +158,17 @@ QUuid Sonos::loadFavorite(const QString &groupId, const QString &favouriteId)
return actionId; return actionId;
} }
void Sonos::getFavorites(const QString &householdId) QUuid Sonos::getFavorites(const QString &householdId)
{ {
QNetworkRequest request; QNetworkRequest request;
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json"); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
request.setRawHeader("Authorization", "Bearer " + m_accessToken); request.setRawHeader("Authorization", "Bearer " + m_accessToken);
request.setRawHeader("X-Sonos-Api-Key", m_clientKey); request.setRawHeader("X-Sonos-Api-Key", m_clientKey);
request.setUrl(QUrl(m_baseControlUrl + "/households/" + householdId + "/favorites")); request.setUrl(QUrl(m_baseControlUrl + "/households/" + householdId + "/favorites"));
QUuid requestId = QUuid::createUuid();
QNetworkReply *reply = m_networkManager->get(request); QNetworkReply *reply = m_networkManager->get(request);
connect(reply, &QNetworkReply::finished, this, [reply, householdId, this] { connect(reply, &QNetworkReply::finished, this, [reply, requestId, householdId, this] {
reply->deleteLater(); reply->deleteLater();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -195,20 +197,21 @@ void Sonos::getFavorites(const QString &householdId)
return; return;
QVariantList array = data.toVariant().toMap().value("items").toList(); QVariantList array = data.toVariant().toMap().value("items").toList();
//qDebug(dcSonos()) << "Favourites received:" << data.toJson(); //qDebug(dcSonos()) << "Favorites received:" << data.toJson();
QList<FavouriteObject> favourites; QList<FavoriteObject> favorites;
foreach (const QVariant &variant, array) { foreach (const QVariant &variant, array) {
QVariantMap itemObject = variant.toMap(); QVariantMap itemObject = variant.toMap();
FavouriteObject favourite; FavoriteObject favorite;
favourite.id = itemObject["id"].toString(); favorite.id = itemObject["id"].toString();
favourite.name = itemObject["name"].toString(); favorite.name = itemObject["name"].toString();
favourite.description = itemObject["description"].toString(); favorite.description = itemObject["description"].toString();
favourite.imageUrl = itemObject["imageUrl"].toString(); favorite.imageUrl = itemObject["imageUrl"].toString();
favourites.append(favourite); favorites.append(favorite);
} }
emit favouritesReceived(householdId, favourites); emit favoritesReceived(requestId, householdId, favorites);
}); });
return requestId;
} }

View File

@ -81,7 +81,7 @@ public:
/* /*
* Describes a Sonos favorite in the household. * Describes a Sonos favorite in the household.
* You can see favorites in the My Sonos tab in the app. The following are not considered */ * You can see favorites in the My Sonos tab in the app. The following are not considered */
struct FavouriteObject { struct FavoriteObject {
QString id; QString id;
QString name; QString name;
QString description; QString description;
@ -216,10 +216,10 @@ public:
void getAccessTokenFromAuthorizationCode(const QByteArray &authorizationCode); void getAccessTokenFromAuthorizationCode(const QByteArray &authorizationCode);
void getHouseholds(); void getHouseholds();
void getFavorites(const QString &householdId); QUuid getFavorites(const QString &householdId);
void getGroups(const QString &householdId); void getGroups(const QString &householdId);
QUuid loadFavorite(const QString &groupId, const QString &favouriteId); QUuid loadFavorite(const QString &groupId, const QString &faveriteId);
//Group volume //Group volume
void getGroupVolume(const QString &groupId); //Get the volume and mute state of a group. void getGroupVolume(const QString &groupId); //Get the volume and mute state of a group.
@ -283,7 +283,7 @@ signals:
void authenticationStatusChanged(bool authenticated); void authenticationStatusChanged(bool authenticated);
void householdIdsReceived(QList<QString> householdIds); void householdIdsReceived(QList<QString> householdIds);
void favouritesReceived(const QString &householdId, QList<FavouriteObject> favourites); void favoritesReceived(QUuid requestId, const QString &householdId, QList<FavoriteObject> favorites);
void playlistsReceived(const QString &householdId, QList<PlaylistObject> playlists); void playlistsReceived(const QString &householdId, QList<PlaylistObject> playlists);
void groupsReceived(const QString &householdId, QList<GroupObject> groups); void groupsReceived(const QString &householdId, QList<GroupObject> groups);
void playlistSummaryReceived(const QString &householdId, PlaylistSummaryObject playlistSummary); void playlistSummaryReceived(const QString &householdId, PlaylistSummaryObject playlistSummary);
@ -294,6 +294,6 @@ signals:
void playerVolumeReceived(const QString &playerId, VolumeObject playerVolume); void playerVolumeReceived(const QString &playerId, VolumeObject playerVolume);
void playerSettingsRecieved(const QString &playerId, PlayerSettingsObject playerSettings); void playerSettingsRecieved(const QString &playerId, PlayerSettingsObject playerSettings);
void actionExecuted(QUuid actionId,bool success); void actionExecuted(QUuid actionId, bool success);
}; };
#endif // SONOS_H #endif // SONOS_H