summaryrefslogtreecommitdiffstats
path: root/xbmc/music/Artist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/music/Artist.cpp')
-rw-r--r--xbmc/music/Artist.cpp239
1 files changed, 239 insertions, 0 deletions
diff --git a/xbmc/music/Artist.cpp b/xbmc/music/Artist.cpp
new file mode 100644
index 0000000..786f7a7
--- /dev/null
+++ b/xbmc/music/Artist.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "Artist.h"
+
+#include "ServiceBroker.h"
+#include "settings/AdvancedSettings.h"
+#include "settings/SettingsComponent.h"
+#include "utils/Fanart.h"
+#include "utils/XMLUtils.h"
+
+#include <algorithm>
+
+void CArtist::MergeScrapedArtist(const CArtist& source, bool override /* = true */)
+{
+ /*
+ Initial scraping of artist information when the mbid is derived from tags is done directly
+ using that ID, otherwise the lookup is based on name and can mis-identify the artist
+ (many have same name). It is useful to store the scraped mbid, but we need to be
+ able to correct any mistakes. Hence a manual refresh of artist information uses either
+ the mbid is derived from tags or the artist name, not any previously scraped mbid.
+
+ A Musicbrainz artist ID derived from music file tags is always taken as accurate and so can
+ not be overwritten by a scraped value. When the artist does not already have an mbid or has
+ a previously scraped mbid, merge the new scraped value, flagging it as being from the
+ scraper rather than derived from music file tags.
+ */
+ if (!source.strMusicBrainzArtistID.empty() && (strMusicBrainzArtistID.empty() || bScrapedMBID))
+ {
+ strMusicBrainzArtistID = source.strMusicBrainzArtistID;
+ bScrapedMBID = true;
+ }
+
+ if ((override && !source.strArtist.empty()) || strArtist.empty())
+ strArtist = source.strArtist;
+
+ if ((override && !source.strSortName.empty()) || strSortName.empty())
+ strSortName = source.strSortName;
+
+ strType = source.strType;
+ strGender = source.strGender;
+ strDisambiguation = source.strDisambiguation;
+ genre = source.genre;
+ strBiography = source.strBiography;
+ styles = source.styles;
+ moods = source.moods;
+ instruments = source.instruments;
+ strBorn = source.strBorn;
+ strFormed = source.strFormed;
+ strDied = source.strDied;
+ strDisbanded = source.strDisbanded;
+ yearsActive = source.yearsActive;
+
+ thumbURL = source.thumbURL; // Available remote art
+ // Current artwork - thumb, fanart etc., to be stored in art table
+ if (!source.art.empty())
+ art = source.art;
+
+ discography = source.discography;
+}
+
+
+bool CArtist::Load(const TiXmlElement *artist, bool append, bool prioritise)
+{
+ if (!artist) return false;
+ if (!append)
+ Reset();
+
+ const std::string itemSeparator = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator;
+
+ XMLUtils::GetString(artist, "name", strArtist);
+ XMLUtils::GetString(artist, "musicBrainzArtistID", strMusicBrainzArtistID);
+ XMLUtils::GetString(artist, "sortname", strSortName);
+ XMLUtils::GetString(artist, "type", strType);
+ XMLUtils::GetString(artist, "gender", strGender);
+ XMLUtils::GetString(artist, "disambiguation", strDisambiguation);
+ XMLUtils::GetStringArray(artist, "genre", genre, prioritise, itemSeparator);
+ XMLUtils::GetStringArray(artist, "style", styles, prioritise, itemSeparator);
+ XMLUtils::GetStringArray(artist, "mood", moods, prioritise, itemSeparator);
+ XMLUtils::GetStringArray(artist, "yearsactive", yearsActive, prioritise, itemSeparator);
+ XMLUtils::GetStringArray(artist, "instruments", instruments, prioritise, itemSeparator);
+
+ XMLUtils::GetString(artist, "born", strBorn);
+ XMLUtils::GetString(artist, "formed", strFormed);
+ XMLUtils::GetString(artist, "biography", strBiography);
+ XMLUtils::GetString(artist, "died", strDied);
+ XMLUtils::GetString(artist, "disbanded", strDisbanded);
+
+ size_t iThumbCount = thumbURL.GetUrls().size();
+ std::string xmlAdd = thumbURL.GetData();
+
+ // Available artist thumbs
+ const TiXmlElement* thumb = artist->FirstChildElement("thumb");
+ while (thumb)
+ {
+ thumbURL.ParseAndAppendUrl(thumb);
+ if (prioritise)
+ {
+ std::string temp;
+ temp << *thumb;
+ xmlAdd = temp+xmlAdd;
+ }
+ thumb = thumb->NextSiblingElement("thumb");
+ }
+ // prefix thumbs from nfos
+ if (prioritise && iThumbCount && iThumbCount != thumbURL.GetUrls().size())
+ {
+ auto thumbUrls = thumbURL.GetUrls();
+ rotate(thumbUrls.begin(), thumbUrls.begin() + iThumbCount, thumbUrls.end());
+ thumbURL.SetUrls(thumbUrls);
+ thumbURL.SetData(xmlAdd);
+ }
+
+ // Discography
+ const TiXmlElement* node = artist->FirstChildElement("album");
+ if (node)
+ discography.clear();
+ while (node)
+ {
+ if (node->FirstChild())
+ {
+ CDiscoAlbum album;
+ XMLUtils::GetString(node, "title", album.strAlbum);
+ XMLUtils::GetString(node, "year", album.strYear);
+ XMLUtils::GetString(node, "musicbrainzreleasegroupid", album.strReleaseGroupMBID);
+ discography.push_back(album);
+ }
+ node = node->NextSiblingElement("album");
+ }
+
+ // Support old style <fanart></fanart> for backwards compatibility of old nfo files and scrapers
+ const TiXmlElement *fanart2 = artist->FirstChildElement("fanart");
+ if (fanart2)
+ {
+ CFanart fanart;
+ // we prefix to handle mixed-mode nfo's with fanart set
+ if (prioritise)
+ {
+ std::string temp;
+ temp << *fanart2;
+ fanart.m_xml = temp+fanart.m_xml;
+ }
+ else
+ fanart.m_xml << *fanart2;
+ fanart.Unpack();
+ // Append fanart to other image URLs
+ for (unsigned int i = 0; i < fanart.GetNumFanarts(); i++)
+ thumbURL.AddParsedUrl(fanart.GetImageURL(i), "fanart", fanart.GetPreviewURL(i));
+ }
+
+ // Current artwork - thumb, fanart etc. (the chosen art, not the lists of those available)
+ node = artist->FirstChildElement("art");
+ if (node)
+ {
+ const TiXmlNode *artdetailNode = node->FirstChild();
+ while (artdetailNode && artdetailNode->FirstChild())
+ {
+ art.insert(make_pair(artdetailNode->ValueStr(), artdetailNode->FirstChild()->ValueStr()));
+ artdetailNode = artdetailNode->NextSibling();
+ }
+ }
+
+ return true;
+}
+
+bool CArtist::Save(TiXmlNode *node, const std::string &tag, const std::string& strPath)
+{
+ if (!node) return false;
+
+ // we start with a <tag> tag
+ TiXmlElement artistElement(tag.c_str());
+ TiXmlNode *artist = node->InsertEndChild(artistElement);
+
+ if (!artist) return false;
+
+ XMLUtils::SetString(artist, "name", strArtist);
+ XMLUtils::SetString(artist, "musicBrainzArtistID", strMusicBrainzArtistID);
+ XMLUtils::SetString(artist, "sortname", strSortName);
+ XMLUtils::SetString(artist, "type", strType);
+ XMLUtils::SetString(artist, "gender", strGender);
+ XMLUtils::SetString(artist, "disambiguation", strDisambiguation);
+ XMLUtils::SetStringArray(artist, "genre", genre);
+ XMLUtils::SetStringArray(artist, "style", styles);
+ XMLUtils::SetStringArray(artist, "mood", moods);
+ XMLUtils::SetStringArray(artist, "yearsactive", yearsActive);
+ XMLUtils::SetStringArray(artist, "instruments", instruments);
+ XMLUtils::SetString(artist, "born", strBorn);
+ XMLUtils::SetString(artist, "formed", strFormed);
+ XMLUtils::SetString(artist, "biography", strBiography);
+ XMLUtils::SetString(artist, "died", strDied);
+ XMLUtils::SetString(artist, "disbanded", strDisbanded);
+ // Available remote art
+ if (thumbURL.HasData())
+ {
+ CXBMCTinyXML doc;
+ doc.Parse(thumbURL.GetData());
+ const TiXmlNode* thumb = doc.FirstChild("thumb");
+ while (thumb)
+ {
+ artist->InsertEndChild(*thumb);
+ thumb = thumb->NextSibling("thumb");
+ }
+ }
+ XMLUtils::SetString(artist, "path", strPath);
+
+ // Discography
+ for (const auto& it : discography)
+ {
+ // add a <album> tag
+ TiXmlElement discoElement("album");
+ TiXmlNode* node = artist->InsertEndChild(discoElement);
+ XMLUtils::SetString(node, "title", it.strAlbum);
+ XMLUtils::SetString(node, "year", it.strYear);
+ XMLUtils::SetString(node, "musicbrainzreleasegroupid", it.strReleaseGroupMBID);
+ }
+
+ return true;
+}
+
+void CArtist::SetDateAdded(const std::string& strDateAdded)
+{
+ dateAdded.SetFromDBDateTime(strDateAdded);
+}
+
+void CArtist::SetDateUpdated(const std::string& strDateUpdated)
+{
+ dateUpdated.SetFromDBDateTime(strDateUpdated);
+}
+
+void CArtist::SetDateNew(const std::string& strDateNew)
+{
+ dateNew.SetFromDBDateTime(strDateNew);
+}
+