JSONRPC_STATUS CAddonsOperations::ExecuteAddon(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { std::string id = parameterObject["addonid"].asString(); AddonPtr addon; if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon) || addon.get() == NULL || addon->Type() < ADDON_VIZ || addon->Type() >= ADDON_MAX) return InvalidParams; std::string argv; CVariant params = parameterObject["params"]; if (params.isObject()) { for (CVariant::const_iterator_map it = params.begin_map(); it != params.end_map(); it++) { if (it != params.begin_map()) argv += ","; argv += it->first + "=" + it->second.asString(); } } else if (params.isArray()) { for (CVariant::const_iterator_array it = params.begin_array(); it != params.end_array(); it++) { if (it != params.begin_array()) argv += ","; argv += StringUtils::Paramify(it->asString()); } } else if (params.isString()) { if (!params.empty()) argv = StringUtils::Paramify(params.asString()); } std::string cmd; if (params.empty()) cmd = StringUtils::Format("RunAddon(%s)", id.c_str()); else cmd = StringUtils::Format("RunAddon(%s, %s)", id.c_str(), argv.c_str()); if (params["wait"].asBoolean()) CApplicationMessenger::GetInstance().SendMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, cmd); else CApplicationMessenger::GetInstance().PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, cmd); return ACK; }
bool CJSONVariantWriter::InternalWrite(yajl_gen g, const CVariant &value) { bool success = false; switch (value.type()) { case CVariant::VariantTypeInteger: success = yajl_gen_status_ok == yajl_gen_integer(g, (long long int)value.asInteger()); break; case CVariant::VariantTypeUnsignedInteger: success = yajl_gen_status_ok == yajl_gen_integer(g, (long long int)value.asUnsignedInteger()); break; case CVariant::VariantTypeDouble: success = yajl_gen_status_ok == yajl_gen_double(g, value.asDouble()); break; case CVariant::VariantTypeBoolean: success = yajl_gen_status_ok == yajl_gen_bool(g, value.asBoolean() ? 1 : 0); break; case CVariant::VariantTypeString: success = yajl_gen_status_ok == yajl_gen_string(g, (const unsigned char*)value.c_str(), (size_t)value.size()); break; case CVariant::VariantTypeArray: success = yajl_gen_status_ok == yajl_gen_array_open(g); for (CVariant::const_iterator_array itr = value.begin_array(); itr != value.end_array() && success; ++itr) success &= InternalWrite(g, *itr); if (success) success = yajl_gen_status_ok == yajl_gen_array_close(g); break; case CVariant::VariantTypeObject: success = yajl_gen_status_ok == yajl_gen_map_open(g); for (CVariant::const_iterator_map itr = value.begin_map(); itr != value.end_map() && success; ++itr) { success &= yajl_gen_status_ok == yajl_gen_string(g, (const unsigned char*)itr->first.c_str(), (size_t)itr->first.length()); if (success) success &= InternalWrite(g, itr->second); } if (success) success &= yajl_gen_status_ok == yajl_gen_map_close(g); break; case CVariant::VariantTypeConstNull: case CVariant::VariantTypeNull: default: success = yajl_gen_status_ok == yajl_gen_null(g); break; } return success; }
TEST(TestVariant, iterator_map) { CVariant a; a["key1"] = "string"; a["key2"] = "string"; a["key3"] = "string"; a["key4"] = "string"; EXPECT_TRUE(a.isObject()); EXPECT_EQ(CVariant::VariantTypeObject, a.type()); CVariant::iterator_map it; for (it = a.begin_map(); it != a.end_map(); it++) { EXPECT_STREQ("string", it->second.c_str()); } CVariant::const_iterator_map const_it; for (const_it = a.begin_map(); const_it != a.end_map(); const_it++) { EXPECT_STREQ("string", const_it->second.c_str()); } }
void CVideoLibrary::UpdateVideoTag(const CVariant ¶meterObject, CVideoInfoTag& details, std::map<std::string, std::string> &artwork, std::set<std::string> &removedArtwork, std::set<std::string> &updatedDetails) { if (ParameterNotNull(parameterObject, "title")) details.SetTitle(parameterObject["title"].asString()); if (ParameterNotNull(parameterObject, "playcount")) details.m_playCount = (int)parameterObject["playcount"].asInteger(); if (ParameterNotNull(parameterObject, "runtime")) details.m_duration = (int)parameterObject["runtime"].asInteger(); std::vector<std::string> director(details.m_director); UpdateVideoTagField(parameterObject, "director", director, updatedDetails); details.SetDirector(director); std::vector<std::string> studio(details.m_studio); UpdateVideoTagField(parameterObject, "studio", studio, updatedDetails); details.SetStudio(studio); if (ParameterNotNull(parameterObject, "year")) details.m_iYear = (int)parameterObject["year"].asInteger(); if (ParameterNotNull(parameterObject, "plot")) details.SetPlot(parameterObject["plot"].asString()); if (ParameterNotNull(parameterObject, "album")) details.SetAlbum(parameterObject["album"].asString()); std::vector<std::string> artist(details.m_artist); UpdateVideoTagField(parameterObject, "artist", artist, updatedDetails); details.SetArtist(artist); std::vector<std::string> genre(details.m_genre); UpdateVideoTagField(parameterObject, "genre", genre, updatedDetails); details.SetGenre(genre); if (ParameterNotNull(parameterObject, "track")) details.m_iTrack = (int)parameterObject["track"].asInteger(); if (ParameterNotNull(parameterObject, "rating")) { details.SetRating(parameterObject["rating"].asFloat()); updatedDetails.insert("ratings"); } if (ParameterNotNull(parameterObject, "votes")) { details.SetVotes(StringUtils::ReturnDigits(parameterObject["votes"].asString())); updatedDetails.insert("ratings"); //Votes and ratings both need updates now, this will trigger those } if (ParameterNotNull(parameterObject, "ratings")) { CVariant ratings = parameterObject["ratings"]; for (CVariant::const_iterator_map rIt = ratings.begin_map(); rIt != ratings.end_map(); rIt++) { if (rIt->second.isArray() && ParameterNotNull(rIt->second, "name") && ParameterNotNull(rIt->second, "rating")) { details.SetRating(rIt->second["rating"].asFloat(), rIt->second["name"].asString()); if (ParameterNotNull(rIt->second, "votes")) details.SetVotes(StringUtils::ReturnDigits(parameterObject["votes"].asString()), rIt->second["name"].asString()); } } updatedDetails.insert("ratings"); } if (ParameterNotNull(parameterObject, "userrating")) details.m_iUserRating = parameterObject["userrating"].asInteger(); if (ParameterNotNull(parameterObject, "mpaa")) details.SetMPAARating(parameterObject["mpaa"].asString()); if (ParameterNotNull(parameterObject, "imdbnumber")) details.SetIMDBNumber(parameterObject["imdbnumber"].asString()); if (ParameterNotNull(parameterObject, "premiered")) SetFromDBDate(parameterObject["premiered"], details.m_premiered); if (ParameterNotNull(parameterObject, "lastplayed")) SetFromDBDateTime(parameterObject["lastplayed"], details.m_lastPlayed); if (ParameterNotNull(parameterObject, "firstaired")) SetFromDBDate(parameterObject["firstaired"], details.m_firstAired); if (ParameterNotNull(parameterObject, "productioncode")) details.SetProductionCode(parameterObject["productioncode"].asString()); if (ParameterNotNull(parameterObject, "season")) details.m_iSeason = (int)parameterObject["season"].asInteger(); if (ParameterNotNull(parameterObject, "episode")) details.m_iEpisode = (int)parameterObject["episode"].asInteger(); if (ParameterNotNull(parameterObject, "originaltitle")) details.SetOriginalTitle(parameterObject["originaltitle"].asString()); if (ParameterNotNull(parameterObject, "trailer")) details.SetTrailer(parameterObject["trailer"].asString()); if (ParameterNotNull(parameterObject, "tagline")) details.SetTagLine(parameterObject["tagline"].asString()); if (ParameterNotNull(parameterObject, "plotoutline")) details.SetPlotOutline(parameterObject["plotoutline"].asString()); std::vector<std::string> credits(details.m_writingCredits); UpdateVideoTagField(parameterObject, "writer", credits, updatedDetails); details.SetWritingCredits(credits); std::vector<std::string> country(details.m_country); UpdateVideoTagField(parameterObject, "country", country, updatedDetails); details.SetCountry(country); if (ParameterNotNull(parameterObject, "top250")) details.m_iTop250 = (int)parameterObject["top250"].asInteger(); if (ParameterNotNull(parameterObject, "sorttitle")) details.SetSortTitle(parameterObject["sorttitle"].asString()); if (ParameterNotNull(parameterObject, "episodeguide")) details.SetEpisodeGuide(parameterObject["episodeguide"].asString()); if (ParameterNotNull(parameterObject, "set")) { details.SetSet(parameterObject["set"].asString()); updatedDetails.insert("set"); } std::vector<std::string> showLink(details.m_showLink); UpdateVideoTagField(parameterObject, "showlink", showLink, updatedDetails); details.SetShowLink(showLink); std::vector<std::string> tags(details.m_tags); UpdateVideoTagField(parameterObject, "tag", tags, updatedDetails); details.SetTags(tags); if (ParameterNotNull(parameterObject, "thumbnail")) { std::string value = parameterObject["thumbnail"].asString(); artwork["thumb"] = StringUtils::Trim(value); updatedDetails.insert("art.altered"); } if (ParameterNotNull(parameterObject, "fanart")) { std::string value = parameterObject["fanart"].asString(); artwork["fanart"] = StringUtils::Trim(value); updatedDetails.insert("art.altered"); } if (ParameterNotNull(parameterObject, "art")) { CVariant art = parameterObject["art"]; for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++) { if (artIt->second.isString() && !artIt->second.asString().empty()) { artwork[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString()); updatedDetails.insert("art.altered"); } else if (artIt->second.isNull()) { artwork.erase(artIt->first); removedArtwork.insert(artIt->first); } } } }
void CVideoLibrary::UpdateVideoTag(const CVariant ¶meterObject, CVideoInfoTag& details, std::map<std::string, std::string> &artwork, std::set<std::string> &removedArtwork, std::set<std::string> &updatedDetails) { if (ParameterNotNull(parameterObject, "title")) details.m_strTitle = parameterObject["title"].asString(); if (ParameterNotNull(parameterObject, "playcount")) details.m_playCount = (int)parameterObject["playcount"].asInteger(); if (ParameterNotNull(parameterObject, "runtime")) details.m_duration = (int)parameterObject["runtime"].asInteger(); UpdateVideoTagField(parameterObject, "director", details.m_director, updatedDetails); UpdateVideoTagField(parameterObject, "studio", details.m_studio, updatedDetails); if (ParameterNotNull(parameterObject, "year")) details.m_iYear = (int)parameterObject["year"].asInteger(); if (ParameterNotNull(parameterObject, "plot")) details.m_strPlot = parameterObject["plot"].asString(); if (ParameterNotNull(parameterObject, "album")) details.m_strAlbum = parameterObject["album"].asString(); UpdateVideoTagField(parameterObject, "artist", details.m_artist, updatedDetails); UpdateVideoTagField(parameterObject, "genre", details.m_genre, updatedDetails); if (ParameterNotNull(parameterObject, "track")) details.m_iTrack = (int)parameterObject["track"].asInteger(); if (ParameterNotNull(parameterObject, "rating")) details.m_fRating = parameterObject["rating"].asFloat(); if (ParameterNotNull(parameterObject, "mpaa")) details.m_strMPAARating = parameterObject["mpaa"].asString(); if (ParameterNotNull(parameterObject, "imdbnumber")) details.m_strIMDBNumber = parameterObject["imdbnumber"].asString(); if (ParameterNotNull(parameterObject, "premiered")) SetFromDBDate(parameterObject["premiered"], details.m_premiered); if (ParameterNotNull(parameterObject, "votes")) details.m_strVotes = parameterObject["votes"].asString(); if (ParameterNotNull(parameterObject, "lastplayed")) SetFromDBDateTime(parameterObject["lastplayed"], details.m_lastPlayed); if (ParameterNotNull(parameterObject, "firstaired")) SetFromDBDateTime(parameterObject["firstaired"], details.m_firstAired); if (ParameterNotNull(parameterObject, "productioncode")) details.m_strProductionCode = parameterObject["productioncode"].asString(); if (ParameterNotNull(parameterObject, "season")) details.m_iSeason = (int)parameterObject["season"].asInteger(); if (ParameterNotNull(parameterObject, "episode")) details.m_iEpisode = (int)parameterObject["episode"].asInteger(); if (ParameterNotNull(parameterObject, "originaltitle")) details.m_strOriginalTitle = parameterObject["originaltitle"].asString(); if (ParameterNotNull(parameterObject, "trailer")) details.m_strTrailer = parameterObject["trailer"].asString(); if (ParameterNotNull(parameterObject, "tagline")) details.m_strTagLine = parameterObject["tagline"].asString(); if (ParameterNotNull(parameterObject, "plotoutline")) details.m_strPlotOutline = parameterObject["plotoutline"].asString(); UpdateVideoTagField(parameterObject, "writer", details.m_writingCredits, updatedDetails); UpdateVideoTagField(parameterObject, "country", details.m_country, updatedDetails); if (ParameterNotNull(parameterObject, "top250")) details.m_iTop250 = (int)parameterObject["top250"].asInteger(); if (ParameterNotNull(parameterObject, "sorttitle")) details.m_strSortTitle = parameterObject["sorttitle"].asString(); if (ParameterNotNull(parameterObject, "episodeguide")) details.m_strEpisodeGuide = parameterObject["episodeguide"].asString(); if (ParameterNotNull(parameterObject, "set")) { details.m_strSet = parameterObject["set"].asString(); updatedDetails.insert("set"); } UpdateVideoTagField(parameterObject, "showlink", details.m_showLink, updatedDetails); UpdateVideoTagField(parameterObject, "tag", details.m_tags, updatedDetails); if (ParameterNotNull(parameterObject, "thumbnail")) { artwork["thumb"] = parameterObject["thumbnail"].asString(); updatedDetails.insert("art.altered"); } if (ParameterNotNull(parameterObject, "fanart")) { artwork["fanart"] = parameterObject["fanart"].asString(); updatedDetails.insert("art.altered"); } if (ParameterNotNull(parameterObject, "art")) { CVariant art = parameterObject["art"]; for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++) { if (artIt->second.isString() && !artIt->second.asString().empty()) { artwork[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString()); updatedDetails.insert("art.altered"); } else if (artIt->second.isNull()) { artwork.erase(artIt->first); removedArtwork.insert(artIt->first); } } } }
JSONRPC_STATUS CAudioLibrary::SetSongDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["songid"].asInteger(); CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; CSong song; if (!musicdatabase.GetSong(id, song) || song.idSong != id) return InvalidParams; if (ParameterNotNull(parameterObject, "title")) song.strTitle = parameterObject["title"].asString(); if (ParameterNotNull(parameterObject, "displayartist")) song.strArtistDesc = parameterObject["displayartist"].asString(); // Set album sort string before processing artist credits if (ParameterNotNull(parameterObject, "sortartist")) song.strArtistSort = parameterObject["sortartist"].asString(); // Match up artist names and mbids to make new artist credits // Mbid values only apply if there are names bool updateartists = false; if (ParameterNotNull(parameterObject, "artist")) { std::vector<std::string> artists, mbids; updateartists = true; CopyStringArray(parameterObject["artist"], artists); // Check for Musicbrainz ids if (ParameterNotNull(parameterObject, "musicbrainzartistid")) CopyStringArray(parameterObject["musicbrainzartistid"], mbids); // When display artist is not provided and yet artists is changing make by concatenation if (!ParameterNotNull(parameterObject, "displayartist")) song.strArtistDesc = StringUtils::Join(artists, g_advancedSettings.m_musicItemSeparator); song.SetArtistCredits(artists, std::vector<std::string>(), mbids); } if (ParameterNotNull(parameterObject, "genre")) CopyStringArray(parameterObject["genre"], song.genre); if (ParameterNotNull(parameterObject, "year")) song.iYear = (int)parameterObject["year"].asInteger(); if (ParameterNotNull(parameterObject, "rating")) song.rating = parameterObject["rating"].asFloat(); if (ParameterNotNull(parameterObject, "userrating")) song.userrating = parameterObject["userrating"].asInteger(); if (ParameterNotNull(parameterObject, "track")) song.iTrack = (song.iTrack & 0xffff0000) | ((int)parameterObject["track"].asInteger() & 0xffff); if (ParameterNotNull(parameterObject, "disc")) song.iTrack = (song.iTrack & 0xffff) | ((int)parameterObject["disc"].asInteger() << 16); if (ParameterNotNull(parameterObject, "duration")) song.iDuration = (int)parameterObject["duration"].asInteger(); if (ParameterNotNull(parameterObject, "comment")) song.strComment = parameterObject["comment"].asString(); if (ParameterNotNull(parameterObject, "musicbrainztrackid")) song.strMusicBrainzTrackID = parameterObject["musicbrainztrackid"].asString(); if (ParameterNotNull(parameterObject, "playcount")) song.iTimesPlayed = static_cast<int>(parameterObject["playcount"].asInteger()); if (ParameterNotNull(parameterObject, "lastplayed")) song.lastPlayed.SetFromDBDateTime(parameterObject["lastplayed"].asString()); if (ParameterNotNull(parameterObject, "mood")) song.strAlbum = parameterObject["mood"].asString(); // Update existing art. Any existing artwork that isn't specified in this request stays as is. // If the value is null then the existing art with that type is removed. if (ParameterNotNull(parameterObject, "art")) { // Get current artwork std::map<std::string, std::string> artwork; musicdatabase.GetArtForItem(song.idSong, MediaTypeSong, artwork); std::set<std::string> removedArtwork; CVariant art = parameterObject["art"]; for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++) { if (artIt->second.isString() && !artIt->second.asString().empty()) artwork[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString()); else if (artIt->second.isNull()) { artwork.erase(artIt->first); removedArtwork.insert(artIt->first); } } //Update artwork, not done in update song musicdatabase.SetArtForItem(song.idSong, MediaTypeSong, artwork); if (!musicdatabase.RemoveArtForItem(song.idSong, MediaTypeSong, removedArtwork)) return InternalError; } // Update song (not including artwork) if (!musicdatabase.UpdateSong(song, updateartists)) return InternalError; CJSONRPCUtils::NotifyItemUpdated(); return ACK; }
JSONRPC_STATUS CAudioLibrary::SetAlbumDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["albumid"].asInteger(); CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; CAlbum album; // Get current album details, but not songs as we do not want to update them here if (!musicdatabase.GetAlbum(id, album, false) || album.idAlbum <= 0) return InvalidParams; if (ParameterNotNull(parameterObject, "title")) album.strAlbum = parameterObject["title"].asString(); if (ParameterNotNull(parameterObject, "displayartist")) album.strArtistDesc = parameterObject["displayartist"].asString(); // Set album sort string before processing artist credits if (ParameterNotNull(parameterObject, "sortartist")) album.strArtistSort = parameterObject["sortartist"].asString(); // Match up artist names and mbids to make new artist credits // Mbid values only apply if there are names if (ParameterNotNull(parameterObject, "artist")) { std::vector<std::string> artists; std::vector<std::string> mbids; CopyStringArray(parameterObject["artist"], artists); // Check for Musicbrainz ids if (ParameterNotNull(parameterObject, "musicbrainzalbumartistid")) CopyStringArray(parameterObject["musicbrainzalbumartistid"], mbids); // When display artist is not provided and yet artists is changing make by concatenation if (!ParameterNotNull(parameterObject, "displayartist")) album.strArtistDesc = StringUtils::Join(artists, g_advancedSettings.m_musicItemSeparator); album.SetArtistCredits(artists, std::vector<std::string>(), mbids); // On updatealbum artists will be changed album.bArtistSongMerge = true; } if (ParameterNotNull(parameterObject, "description")) album.strReview = parameterObject["description"].asString(); if (ParameterNotNull(parameterObject, "genre")) CopyStringArray(parameterObject["genre"], album.genre); if (ParameterNotNull(parameterObject, "theme")) CopyStringArray(parameterObject["theme"], album.themes); if (ParameterNotNull(parameterObject, "mood")) CopyStringArray(parameterObject["mood"], album.moods); if (ParameterNotNull(parameterObject, "style")) CopyStringArray(parameterObject["style"], album.styles); if (ParameterNotNull(parameterObject, "type")) album.strType = parameterObject["type"].asString(); if (ParameterNotNull(parameterObject, "albumlabel")) album.strLabel = parameterObject["albumlabel"].asString(); if (ParameterNotNull(parameterObject, "rating")) album.fRating = parameterObject["rating"].asFloat(); if (ParameterNotNull(parameterObject, "userrating")) album.iUserrating = parameterObject["userrating"].asInteger(); if (ParameterNotNull(parameterObject, "votes")) album.iVotes = parameterObject["votes"].asInteger(); if (ParameterNotNull(parameterObject, "year")) album.iYear = (int)parameterObject["year"].asInteger(); if (ParameterNotNull(parameterObject, "musicbrainzalbumid")) album.strMusicBrainzAlbumID = parameterObject["musicbrainzalbumid"].asString(); if (ParameterNotNull(parameterObject, "musicbrainzreleasegroupid")) album.strReleaseGroupMBID = parameterObject["musicbrainzreleasegroupid"].asString(); // Update existing art. Any existing artwork that isn't specified in this request stays as is. // If the value is null then the existing art with that type is removed. if (ParameterNotNull(parameterObject, "art")) { // Get current artwork musicdatabase.GetArtForItem(album.idAlbum, MediaTypeAlbum, album.art); std::set<std::string> removedArtwork; CVariant art = parameterObject["art"]; for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++) { if (artIt->second.isString() && !artIt->second.asString().empty()) album.art[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString()); else if (artIt->second.isNull()) { album.art.erase(artIt->first); removedArtwork.insert(artIt->first); } } // Remove null art now, as not done by update if (!musicdatabase.RemoveArtForItem(album.idAlbum, MediaTypeAlbum, removedArtwork)) return InternalError; } // Update artist including adding or replacing (but not removing) art if (!musicdatabase.UpdateAlbum(album)) return InternalError; CJSONRPCUtils::NotifyItemUpdated(); return ACK; }
JSONRPC_STATUS CAudioLibrary::SetArtistDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["artistid"].asInteger(); CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; CArtist artist; if (!musicdatabase.GetArtist(id, artist) || artist.idArtist <= 0) return InvalidParams; if (ParameterNotNull(parameterObject, "artist")) artist.strArtist = parameterObject["artist"].asString(); if (ParameterNotNull(parameterObject, "instrument")) CopyStringArray(parameterObject["instrument"], artist.instruments); if (ParameterNotNull(parameterObject, "style")) CopyStringArray(parameterObject["style"], artist.styles); if (ParameterNotNull(parameterObject, "mood")) CopyStringArray(parameterObject["mood"], artist.moods); if (ParameterNotNull(parameterObject, "born")) artist.strBorn = parameterObject["born"].asString(); if (ParameterNotNull(parameterObject, "formed")) artist.strFormed = parameterObject["formed"].asString(); if (ParameterNotNull(parameterObject, "description")) artist.strBiography = parameterObject["description"].asString(); if (ParameterNotNull(parameterObject, "genre")) CopyStringArray(parameterObject["genre"], artist.genre); if (ParameterNotNull(parameterObject, "died")) artist.strDied = parameterObject["died"].asString(); if (ParameterNotNull(parameterObject, "disbanded")) artist.strDisbanded = parameterObject["disbanded"].asString(); if (ParameterNotNull(parameterObject, "yearsactive")) CopyStringArray(parameterObject["yearsactive"], artist.yearsActive); if (ParameterNotNull(parameterObject, "musicbrainzartistid")) artist.strMusicBrainzArtistID = parameterObject["musicbrainzartistid"].asString(); if (ParameterNotNull(parameterObject, "sortname")) artist.strSortName = parameterObject["sortname"].asString(); if (ParameterNotNull(parameterObject, "type")) artist.strType = parameterObject["type"].asString(); if (ParameterNotNull(parameterObject, "gender")) artist.strGender = parameterObject["gender"].asString(); if (ParameterNotNull(parameterObject, "disambiguation")) artist.strDisambiguation = parameterObject["disambiguation"].asString(); // Update existing art. Any existing artwork that isn't specified in this request stays as is. // If the value is null then the existing art with that type is removed. if (ParameterNotNull(parameterObject, "art")) { // Get current artwork musicdatabase.GetArtForItem(artist.idArtist, MediaTypeArtist, artist.art); std::set<std::string> removedArtwork; CVariant art = parameterObject["art"]; for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++) { if (artIt->second.isString() && !artIt->second.asString().empty()) artist.art[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString()); else if (artIt->second.isNull()) { artist.art.erase(artIt->first); removedArtwork.insert(artIt->first); } } // Remove null art now, as not done by update if (!musicdatabase.RemoveArtForItem(artist.idArtist, MediaTypeArtist, removedArtwork)) return InternalError; } // Update artist including adding or replacing (but not removing) art if (!musicdatabase.UpdateArtist(artist)) return InternalError; CJSONRPCUtils::NotifyItemUpdated(); return ACK; }