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
;
68 bool CArtist::Load(const TiXmlElement
*artist
, bool append
, bool prioritise
)
70 if (!artist
) return false;
74 const std::string itemSeparator
= CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator
;
76 XMLUtils::GetString(artist
, "name", strArtist
);
77 XMLUtils::GetString(artist
, "musicBrainzArtistID", strMusicBrainzArtistID
);
78 XMLUtils::GetString(artist
, "sortname", strSortName
);
79 XMLUtils::GetString(artist
, "type", strType
);
80 XMLUtils::GetString(artist
, "gender", strGender
);
81 XMLUtils::GetString(artist
, "disambiguation", strDisambiguation
);
82 XMLUtils::GetStringArray(artist
, "genre", genre
, prioritise
, itemSeparator
);
83 XMLUtils::GetStringArray(artist
, "style", styles
, prioritise
, itemSeparator
);
84 XMLUtils::GetStringArray(artist
, "mood", moods
, prioritise
, itemSeparator
);
85 XMLUtils::GetStringArray(artist
, "yearsactive", yearsActive
, prioritise
, itemSeparator
);
86 XMLUtils::GetStringArray(artist
, "instruments", instruments
, prioritise
, itemSeparator
);
88 XMLUtils::GetString(artist
, "born", strBorn
);
89 XMLUtils::GetString(artist
, "formed", strFormed
);
90 XMLUtils::GetString(artist
, "biography", strBiography
);
91 XMLUtils::GetString(artist
, "died", strDied
);
92 XMLUtils::GetString(artist
, "disbanded", strDisbanded
);
94 size_t iThumbCount
= thumbURL
.GetUrls().size();
95 std::string xmlAdd
= thumbURL
.GetData();
97 // Available artist thumbs
98 const TiXmlElement
* thumb
= artist
->FirstChildElement("thumb");
101 thumbURL
.ParseAndAppendUrl(thumb
);
106 xmlAdd
= temp
+xmlAdd
;
108 thumb
= thumb
->NextSiblingElement("thumb");
110 // prefix thumbs from nfos
111 if (prioritise
&& iThumbCount
&& iThumbCount
!= thumbURL
.GetUrls().size())
113 auto thumbUrls
= thumbURL
.GetUrls();
114 rotate(thumbUrls
.begin(), thumbUrls
.begin() + iThumbCount
, thumbUrls
.end());
115 thumbURL
.SetUrls(thumbUrls
);
116 thumbURL
.SetData(xmlAdd
);
120 const TiXmlElement
* node
= artist
->FirstChildElement("album");
125 if (node
->FirstChild())
128 XMLUtils::GetString(node
, "title", album
.strAlbum
);
129 XMLUtils::GetString(node
, "year", album
.strYear
);
130 XMLUtils::GetString(node
, "musicbrainzreleasegroupid", album
.strReleaseGroupMBID
);
131 discography
.push_back(album
);
133 node
= node
->NextSiblingElement("album");
136 // Support old style <fanart></fanart> for backwards compatibility of old nfo files and scrapers
137 const TiXmlElement
*fanart2
= artist
->FirstChildElement("fanart");
141 // we prefix to handle mixed-mode nfo's with fanart set
146 fanart
.m_xml
= temp
+fanart
.m_xml
;
149 fanart
.m_xml
<< *fanart2
;
151 // Append fanart to other image URLs
152 for (unsigned int i
= 0; i
< fanart
.GetNumFanarts(); i
++)
153 thumbURL
.AddParsedUrl(fanart
.GetImageURL(i
), "fanart", fanart
.GetPreviewURL(i
));
156 // Current artwork - thumb, fanart etc. (the chosen art, not the lists of those available)
157 node
= artist
->FirstChildElement("art");
160 const TiXmlNode
*artdetailNode
= node
->FirstChild();
161 while (artdetailNode
&& artdetailNode
->FirstChild())
163 art
.insert(make_pair(artdetailNode
->ValueStr(), artdetailNode
->FirstChild()->ValueStr()));
164 artdetailNode
= artdetailNode
->NextSibling();
171 bool CArtist::Save(TiXmlNode
*node
, const std::string
&tag
, const std::string
& strPath
)
173 if (!node
) return false;
175 // we start with a <tag> tag
176 TiXmlElement
artistElement(tag
.c_str());
177 TiXmlNode
*artist
= node
->InsertEndChild(artistElement
);
179 if (!artist
) return false;
181 XMLUtils::SetString(artist
, "name", strArtist
);
182 XMLUtils::SetString(artist
, "musicBrainzArtistID", strMusicBrainzArtistID
);
183 XMLUtils::SetString(artist
, "sortname", strSortName
);
184 XMLUtils::SetString(artist
, "type", strType
);
185 XMLUtils::SetString(artist
, "gender", strGender
);
186 XMLUtils::SetString(artist
, "disambiguation", strDisambiguation
);
187 XMLUtils::SetStringArray(artist
, "genre", genre
);
188 XMLUtils::SetStringArray(artist
, "style", styles
);
189 XMLUtils::SetStringArray(artist
, "mood", moods
);
190 XMLUtils::SetStringArray(artist
, "yearsactive", yearsActive
);
191 XMLUtils::SetStringArray(artist
, "instruments", instruments
);
192 XMLUtils::SetString(artist
, "born", strBorn
);
193 XMLUtils::SetString(artist
, "formed", strFormed
);
194 XMLUtils::SetString(artist
, "biography", strBiography
);
195 XMLUtils::SetString(artist
, "died", strDied
);
196 XMLUtils::SetString(artist
, "disbanded", strDisbanded
);
197 // Available remote art
198 if (thumbURL
.HasData())
201 doc
.Parse(thumbURL
.GetData());
202 const TiXmlNode
* thumb
= doc
.FirstChild("thumb");
205 artist
->InsertEndChild(*thumb
);
206 thumb
= thumb
->NextSibling("thumb");
209 XMLUtils::SetString(artist
, "path", strPath
);
212 for (const auto& it
: discography
)
215 TiXmlElement
discoElement("album");
216 TiXmlNode
* node
= artist
->InsertEndChild(discoElement
);
217 XMLUtils::SetString(node
, "title", it
.strAlbum
);
218 XMLUtils::SetString(node
, "year", it
.strYear
);
219 XMLUtils::SetString(node
, "musicbrainzreleasegroupid", it
.strReleaseGroupMBID
);
225 void CArtist::SetDateAdded(const std::string
& strDateAdded
)
227 dateAdded
.SetFromDBDateTime(strDateAdded
);
230 void CArtist::SetDateUpdated(const std::string
& strDateUpdated
)
232 dateUpdated
.SetFromDBDateTime(strDateUpdated
);
235 void CArtist::SetDateNew(const std::string
& strDateNew
)
237 dateNew
.SetFromDBDateTime(strDateNew
);