2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 #include "ServiceBroker.h"
12 #include "settings/AdvancedSettings.h"
13 #include "settings/SettingsComponent.h"
14 #include "utils/Fanart.h"
15 #include "utils/XMLUtils.h"
19 void CArtist::MergeScrapedArtist(const CArtist
& source
, bool override
/* = true */)
22 Initial scraping of artist information when the mbid is derived from tags is done directly
23 using that ID, otherwise the lookup is based on name and can mis-identify the artist
24 (many have same name). It is useful to store the scraped mbid, but we need to be
25 able to correct any mistakes. Hence a manual refresh of artist information uses either
26 the mbid is derived from tags or the artist name, not any previously scraped mbid.
28 A Musicbrainz artist ID derived from music file tags is always taken as accurate and so can
29 not be overwritten by a scraped value. When the artist does not already have an mbid or has
30 a previously scraped mbid, merge the new scraped value, flagging it as being from the
31 scraper rather than derived from music file tags.
33 if (!source
.strMusicBrainzArtistID
.empty() && (strMusicBrainzArtistID
.empty() || bScrapedMBID
))
35 strMusicBrainzArtistID
= source
.strMusicBrainzArtistID
;
39 if ((override
&& !source
.strArtist
.empty()) || strArtist
.empty())
40 strArtist
= source
.strArtist
;
42 if ((override
&& !source
.strSortName
.empty()) || strSortName
.empty())
43 strSortName
= source
.strSortName
;
45 strType
= source
.strType
;
46 strGender
= source
.strGender
;
47 strDisambiguation
= source
.strDisambiguation
;
49 strBiography
= source
.strBiography
;
50 styles
= source
.styles
;
52 instruments
= source
.instruments
;
53 strBorn
= source
.strBorn
;
54 strFormed
= source
.strFormed
;
55 strDied
= source
.strDied
;
56 strDisbanded
= source
.strDisbanded
;
57 yearsActive
= source
.yearsActive
;
59 thumbURL
= source
.thumbURL
; // Available remote art
60 // Current artwork - thumb, fanart etc., to be stored in art table
61 if (!source
.art
.empty())
64 discography
= source
.discography
;
65 videolinks
= source
.videolinks
;
69 bool CArtist::Load(const TiXmlElement
*artist
, bool append
, bool prioritise
)
71 if (!artist
) return false;
75 const std::string itemSeparator
= CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator
;
77 XMLUtils::GetString(artist
, "name", strArtist
);
78 XMLUtils::GetString(artist
, "musicBrainzArtistID", strMusicBrainzArtistID
);
79 XMLUtils::GetString(artist
, "sortname", strSortName
);
80 XMLUtils::GetString(artist
, "type", strType
);
81 XMLUtils::GetString(artist
, "gender", strGender
);
82 XMLUtils::GetString(artist
, "disambiguation", strDisambiguation
);
83 XMLUtils::GetStringArray(artist
, "genre", genre
, prioritise
, itemSeparator
);
84 XMLUtils::GetStringArray(artist
, "style", styles
, prioritise
, itemSeparator
);
85 XMLUtils::GetStringArray(artist
, "mood", moods
, prioritise
, itemSeparator
);
86 XMLUtils::GetStringArray(artist
, "yearsactive", yearsActive
, prioritise
, itemSeparator
);
87 XMLUtils::GetStringArray(artist
, "instruments", instruments
, prioritise
, itemSeparator
);
89 XMLUtils::GetString(artist
, "born", strBorn
);
90 XMLUtils::GetString(artist
, "formed", strFormed
);
91 XMLUtils::GetString(artist
, "biography", strBiography
);
92 XMLUtils::GetString(artist
, "died", strDied
);
93 XMLUtils::GetString(artist
, "disbanded", strDisbanded
);
95 size_t iThumbCount
= thumbURL
.GetUrls().size();
96 std::string xmlAdd
= thumbURL
.GetData();
98 // Available artist thumbs
99 const TiXmlElement
* thumb
= artist
->FirstChildElement("thumb");
102 thumbURL
.ParseAndAppendUrl(thumb
);
107 xmlAdd
= temp
+xmlAdd
;
109 thumb
= thumb
->NextSiblingElement("thumb");
111 // prefix thumbs from nfos
112 if (prioritise
&& iThumbCount
&& iThumbCount
!= thumbURL
.GetUrls().size())
114 auto thumbUrls
= thumbURL
.GetUrls();
115 rotate(thumbUrls
.begin(), thumbUrls
.begin() + iThumbCount
, thumbUrls
.end());
116 thumbURL
.SetUrls(thumbUrls
);
117 thumbURL
.SetData(xmlAdd
);
121 const TiXmlElement
* node
= artist
->FirstChildElement("album");
126 if (node
->FirstChild())
129 XMLUtils::GetString(node
, "title", album
.strAlbum
);
130 XMLUtils::GetString(node
, "year", album
.strYear
);
131 XMLUtils::GetString(node
, "musicbrainzreleasegroupid", album
.strReleaseGroupMBID
);
132 discography
.push_back(album
);
134 node
= node
->NextSiblingElement("album");
138 const TiXmlElement
* songurls
= artist
->FirstChildElement("videourl");
143 if (songurls
->FirstChild())
145 ArtistVideoLinks videoLink
;
146 XMLUtils::GetString(songurls
, "title", videoLink
.title
);
147 XMLUtils::GetString(songurls
, "musicbrainztrackid", videoLink
.mbTrackID
);
148 XMLUtils::GetString(songurls
, "url", videoLink
.videoURL
);
149 XMLUtils::GetString(songurls
, "thumburl", videoLink
.thumbURL
);
150 videolinks
.emplace_back(std::move(videoLink
));
152 songurls
= songurls
->NextSiblingElement("videourl");
155 // Support old style <fanart></fanart> for backwards compatibility of old nfo files and scrapers
156 const TiXmlElement
*fanart2
= artist
->FirstChildElement("fanart");
160 // we prefix to handle mixed-mode nfo's with fanart set
165 fanart
.m_xml
= temp
+fanart
.m_xml
;
168 fanart
.m_xml
<< *fanart2
;
170 // Append fanart to other image URLs
171 for (unsigned int i
= 0; i
< fanart
.GetNumFanarts(); i
++)
172 thumbURL
.AddParsedUrl(fanart
.GetImageURL(i
), "fanart", fanart
.GetPreviewURL(i
));
175 // Current artwork - thumb, fanart etc. (the chosen art, not the lists of those available)
176 node
= artist
->FirstChildElement("art");
179 const TiXmlNode
*artdetailNode
= node
->FirstChild();
180 while (artdetailNode
&& artdetailNode
->FirstChild())
182 art
.insert(make_pair(artdetailNode
->ValueStr(), artdetailNode
->FirstChild()->ValueStr()));
183 artdetailNode
= artdetailNode
->NextSibling();
190 bool CArtist::Save(TiXmlNode
*node
, const std::string
&tag
, const std::string
& strPath
)
192 if (!node
) return false;
194 // we start with a <tag> tag
195 TiXmlElement
artistElement(tag
.c_str());
196 TiXmlNode
*artist
= node
->InsertEndChild(artistElement
);
198 if (!artist
) return false;
200 XMLUtils::SetString(artist
, "name", strArtist
);
201 XMLUtils::SetString(artist
, "musicBrainzArtistID", strMusicBrainzArtistID
);
202 XMLUtils::SetString(artist
, "sortname", strSortName
);
203 XMLUtils::SetString(artist
, "type", strType
);
204 XMLUtils::SetString(artist
, "gender", strGender
);
205 XMLUtils::SetString(artist
, "disambiguation", strDisambiguation
);
206 XMLUtils::SetStringArray(artist
, "genre", genre
);
207 XMLUtils::SetStringArray(artist
, "style", styles
);
208 XMLUtils::SetStringArray(artist
, "mood", moods
);
209 XMLUtils::SetStringArray(artist
, "yearsactive", yearsActive
);
210 XMLUtils::SetStringArray(artist
, "instruments", instruments
);
211 XMLUtils::SetString(artist
, "born", strBorn
);
212 XMLUtils::SetString(artist
, "formed", strFormed
);
213 XMLUtils::SetString(artist
, "biography", strBiography
);
214 XMLUtils::SetString(artist
, "died", strDied
);
215 XMLUtils::SetString(artist
, "disbanded", strDisbanded
);
216 // Available remote art
217 if (thumbURL
.HasData())
220 doc
.Parse(thumbURL
.GetData());
221 const TiXmlNode
* thumb
= doc
.FirstChild("thumb");
224 artist
->InsertEndChild(*thumb
);
225 thumb
= thumb
->NextSibling("thumb");
228 XMLUtils::SetString(artist
, "path", strPath
);
231 for (const auto& it
: discography
)
234 TiXmlElement
discoElement("album");
235 TiXmlNode
* node
= artist
->InsertEndChild(discoElement
);
236 XMLUtils::SetString(node
, "title", it
.strAlbum
);
237 XMLUtils::SetString(node
, "year", it
.strYear
);
238 XMLUtils::SetString(node
, "musicbrainzreleasegroupid", it
.strReleaseGroupMBID
);
241 for (const auto& it
: videolinks
)
243 TiXmlElement
videolinkElement("videourl");
244 TiXmlNode
* node
= artist
->InsertEndChild(videolinkElement
);
245 XMLUtils::SetString(node
, "title", it
.title
);
246 XMLUtils::SetString(node
, "musicbrainztrackid", it
.mbTrackID
);
247 XMLUtils::SetString(node
, "url", it
.videoURL
);
248 XMLUtils::SetString(node
, "thumburl", it
.thumbURL
);
254 void CArtist::SetDateAdded(const std::string
& strDateAdded
)
256 dateAdded
.SetFromDBDateTime(strDateAdded
);
259 void CArtist::SetDateUpdated(const std::string
& strDateUpdated
)
261 dateUpdated
.SetFromDBDateTime(strDateUpdated
);
264 void CArtist::SetDateNew(const std::string
& strDateNew
)
266 dateNew
.SetFromDBDateTime(strDateNew
);