Merge pull request #4857 from t-nelson/Gotham_13.2_backports
[vuplus_xbmc] / xbmc / music / Artist.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "Artist.h"
22 #include "utils/XMLUtils.h"
23 #include "settings/AdvancedSettings.h"
24
25 using namespace std;
26
27 void CArtist::MergeScrapedArtist(const CArtist& source, bool override /* = true */)
28 {
29   /*
30    We don't merge musicbrainz artist ID so that a refresh of artist information
31    allows a lookup based on name rather than directly (re)using musicbrainz.
32    In future, we may wish to be able to override lookup by musicbrainz so
33    this might be dropped.
34    */
35   //  strMusicBrainzArtistID = source.strMusicBrainzArtistID;
36   if ((override && !source.strArtist.empty()) || strArtist.empty())
37     strArtist = source.strArtist;
38
39   genre = source.genre;
40   strBiography = source.strBiography;
41   styles = source.styles;
42   moods = source.moods;
43   instruments = source.instruments;
44   strBorn = source.strBorn;
45   strFormed = source.strFormed;
46   strDied = source.strDied;
47   strDisbanded = source.strDisbanded;
48   yearsActive = source.yearsActive;
49   thumbURL = source.thumbURL;
50   fanart = source.fanart;
51   discography = source.discography;
52 }
53
54
55 bool CArtist::Load(const TiXmlElement *artist, bool append, bool prioritise)
56 {
57   if (!artist) return false;
58   if (!append)
59     Reset();
60
61   XMLUtils::GetString(artist,                "name", strArtist);
62   XMLUtils::GetString(artist, "musicBrainzArtistID", strMusicBrainzArtistID);
63
64   XMLUtils::GetStringArray(artist,       "genre", genre, prioritise, g_advancedSettings.m_musicItemSeparator);
65   XMLUtils::GetStringArray(artist,       "style", styles, prioritise, g_advancedSettings.m_musicItemSeparator);
66   XMLUtils::GetStringArray(artist,        "mood", moods, prioritise, g_advancedSettings.m_musicItemSeparator);
67   XMLUtils::GetStringArray(artist, "yearsactive", yearsActive, prioritise, g_advancedSettings.m_musicItemSeparator);
68   XMLUtils::GetStringArray(artist, "instruments", instruments, prioritise, g_advancedSettings.m_musicItemSeparator);
69
70   XMLUtils::GetString(artist,      "born", strBorn);
71   XMLUtils::GetString(artist,    "formed", strFormed);
72   XMLUtils::GetString(artist, "biography", strBiography);
73   XMLUtils::GetString(artist,      "died", strDied);
74   XMLUtils::GetString(artist, "disbanded", strDisbanded);
75
76   size_t iThumbCount = thumbURL.m_url.size();
77   CStdString xmlAdd = thumbURL.m_xml;
78
79   const TiXmlElement* thumb = artist->FirstChildElement("thumb");
80   while (thumb)
81   {
82     thumbURL.ParseElement(thumb);
83     if (prioritise)
84     {
85       CStdString temp;
86       temp << *thumb;
87       xmlAdd = temp+xmlAdd;
88     }
89     thumb = thumb->NextSiblingElement("thumb");
90   }
91   // prefix thumbs from nfos
92   if (prioritise && iThumbCount && iThumbCount != thumbURL.m_url.size())
93   {
94     rotate(thumbURL.m_url.begin(),
95            thumbURL.m_url.begin()+iThumbCount, 
96            thumbURL.m_url.end());
97     thumbURL.m_xml = xmlAdd;
98   }
99   const TiXmlElement* node = artist->FirstChildElement("album");
100   while (node)
101   {
102     const TiXmlNode* title = node->FirstChild("title");
103     if (title && title->FirstChild())
104     {
105       CStdString strTitle = title->FirstChild()->Value();
106       CStdString strYear;
107       const TiXmlNode* year = node->FirstChild("year");
108       if (year && year->FirstChild())
109         strYear = year->FirstChild()->Value();
110       discography.push_back(make_pair(strTitle,strYear));
111     }
112     node = node->NextSiblingElement("album");
113   }
114
115   // fanart
116   const TiXmlElement *fanart2 = artist->FirstChildElement("fanart");
117   if (fanart2)
118   {
119     // we prefix to handle mixed-mode nfo's with fanart set
120     if (prioritise)
121     {
122       CStdString temp;
123       temp << *fanart2;
124       fanart.m_xml = temp+fanart.m_xml;
125     }
126     else
127       fanart.m_xml << *fanart2;
128     fanart.Unpack();
129   }
130
131   return true;
132 }
133
134 bool CArtist::Save(TiXmlNode *node, const CStdString &tag, const CStdString& strPath)
135 {
136   if (!node) return false;
137
138   // we start with a <tag> tag
139   TiXmlElement artistElement(tag.c_str());
140   TiXmlNode *artist = node->InsertEndChild(artistElement);
141
142   if (!artist) return false;
143
144   XMLUtils::SetString(artist,                      "name", strArtist);
145   XMLUtils::SetString(artist,       "musicBrainzArtistID", strMusicBrainzArtistID);
146   XMLUtils::SetStringArray(artist,                "genre", genre);
147   XMLUtils::SetStringArray(artist,                "style", styles);
148   XMLUtils::SetStringArray(artist,                 "mood", moods);
149   XMLUtils::SetStringArray(artist,          "yearsactive", yearsActive);
150   XMLUtils::SetStringArray(artist,          "instruments", instruments);
151   XMLUtils::SetString(artist,                      "born", strBorn);
152   XMLUtils::SetString(artist,                    "formed", strFormed);
153   XMLUtils::SetString(artist,                 "biography", strBiography);
154   XMLUtils::SetString(artist,                      "died", strDied);
155   XMLUtils::SetString(artist,                 "disbanded", strDisbanded);
156   if (!thumbURL.m_xml.empty())
157   {
158     CXBMCTinyXML doc;
159     doc.Parse(thumbURL.m_xml);
160     const TiXmlNode* thumb = doc.FirstChild("thumb");
161     while (thumb)
162     {
163       artist->InsertEndChild(*thumb);
164       thumb = thumb->NextSibling("thumb");
165     }
166   }
167   XMLUtils::SetString(artist,        "path", strPath);
168   if (fanart.m_xml.size())
169   {
170     CXBMCTinyXML doc;
171     doc.Parse(fanart.m_xml);
172     artist->InsertEndChild(*doc.RootElement());
173   }
174
175   // albums
176   for (vector< pair<CStdString,CStdString> >::const_iterator it = discography.begin(); it != discography.end(); ++it)
177   {
178     // add a <album> tag
179     TiXmlElement cast("album");
180     TiXmlNode *node = artist->InsertEndChild(cast);
181     TiXmlElement title("title");
182     TiXmlNode *titleNode = node->InsertEndChild(title);
183     TiXmlText name(it->first);
184     titleNode->InsertEndChild(name);
185     TiXmlElement year("year");
186     TiXmlNode *yearNode = node->InsertEndChild(year);
187     TiXmlText name2(it->second);
188     yearNode->InsertEndChild(name2);
189   }
190
191   return true;
192 }
193