changed: Split background info loading into a 2 stages
[vuplus_xbmc] / xbmc / music / MusicThumbLoader.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://www.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 "MusicThumbLoader.h"
22 #include "FileItem.h"
23 #include "TextureCache.h"
24 #include "music/tags/MusicInfoTag.h"
25 #include "music/tags/MusicInfoTagLoaderFactory.h"
26 #include "music/infoscanner/MusicInfoScanner.h"
27 #include "music/Artist.h"
28 #include "video/VideoThumbLoader.h"
29
30 using namespace std;
31 using namespace MUSIC_INFO;
32
33 CMusicThumbLoader::CMusicThumbLoader() : CThumbLoader()
34 {
35   m_database = new CMusicDatabase;
36 }
37
38 CMusicThumbLoader::~CMusicThumbLoader()
39 {
40   delete m_database;
41 }
42
43 void CMusicThumbLoader::Initialize()
44 {
45   m_database->Open();
46   m_albumArt.clear();
47 }
48
49 void CMusicThumbLoader::Deinitialize()
50 {
51   m_database->Close();
52   m_albumArt.clear();
53 }
54
55 void CMusicThumbLoader::OnLoaderStart()
56 {
57   Initialize();
58 }
59
60 void CMusicThumbLoader::OnLoaderFinish()
61 {
62   Deinitialize();
63 }
64
65 bool CMusicThumbLoader::LoadItem(CFileItem* pItem)
66 {
67   bool result  = LoadItemCached(pItem);
68        result |= LoadItemLookup(pItem);
69
70   return result;
71 }
72
73 bool CMusicThumbLoader::LoadItemCached(CFileItem* pItem)
74 {
75   if (pItem->m_bIsShareOrDrive)
76     return false;
77
78   if (pItem->HasMusicInfoTag() && pItem->GetArt().empty())
79   {
80     if (FillLibraryArt(*pItem))
81       return true;
82       
83     if (pItem->GetMusicInfoTag()->GetType() == "artist")
84       return false; // No fallback
85   }
86
87   if (pItem->HasVideoInfoTag() && pItem->GetArt().empty())
88   { // music video
89     CVideoThumbLoader loader;
90     if (loader.LoadItemCached(pItem))
91       return true;
92   }
93
94   if (!pItem->HasArt("fanart"))
95   {
96     if (pItem->HasMusicInfoTag() && !pItem->GetMusicInfoTag()->GetArtist().empty())
97     {
98       std::string artist = pItem->GetMusicInfoTag()->GetArtist()[0];
99       m_database->Open();
100       int idArtist = m_database->GetArtistByName(artist);
101       if (idArtist >= 0)
102       {
103         string fanart = m_database->GetArtForItem(idArtist, "artist", "fanart");
104         if (!fanart.empty())
105         {
106           pItem->SetArt("artist.fanart", fanart);
107           pItem->SetArtFallback("fanart", "artist.fanart");
108         }
109       }
110       m_database->Close();
111     }
112   }
113
114   return false;
115 }
116
117 bool CMusicThumbLoader::LoadItemLookup(CFileItem* pItem)
118 {
119   if (pItem->m_bIsShareOrDrive)
120     return false;
121
122   if (pItem->HasMusicInfoTag() && pItem->GetMusicInfoTag()->GetType() == "artist") // No fallback for artist
123     return false;
124
125   if (pItem->HasVideoInfoTag())
126   { // music video
127     CVideoThumbLoader loader;
128     if (loader.LoadItemLookup(pItem))
129       return true;
130   }
131
132   if (!pItem->HasArt("thumb"))
133   {
134     // Look for embedded art
135     if (pItem->HasMusicInfoTag() && !pItem->GetMusicInfoTag()->GetCoverArtInfo().empty())
136     {
137       // The item has got embedded art but user thumbs overrule, so check for those first
138       if (!FillThumb(*pItem, false)) // Check for user thumbs but ignore folder thumbs
139       {
140         // No user thumb, use embedded art
141         CStdString thumb = CTextureCache::GetWrappedImageURL(pItem->GetPath(), "music");
142         pItem->SetArt("thumb", thumb);
143       }
144     }
145     else
146     {
147       // Check for user thumbs
148       FillThumb(*pItem, true);
149     }
150   }
151
152   return true;
153 }
154
155 bool CMusicThumbLoader::FillThumb(CFileItem &item, bool folderThumbs /* = true */)
156 {
157   if (item.HasArt("thumb"))
158     return true;
159   CStdString thumb = GetCachedImage(item, "thumb");
160   if (thumb.IsEmpty())
161   {
162     thumb = item.GetUserMusicThumb(false, folderThumbs);
163     if (!thumb.IsEmpty())
164       SetCachedImage(item, "thumb", thumb);
165   }
166   item.SetArt("thumb", thumb);
167   return !thumb.IsEmpty();
168 }
169
170 bool CMusicThumbLoader::FillLibraryArt(CFileItem &item)
171 {
172   CMusicInfoTag &tag = *item.GetMusicInfoTag();
173   if (tag.GetDatabaseId() > -1 && !tag.GetType().empty())
174   {
175     m_database->Open();
176     map<string, string> artwork;
177     if (m_database->GetArtForItem(tag.GetDatabaseId(), tag.GetType(), artwork))
178       item.SetArt(artwork);
179     else if (tag.GetType() == "song")
180     { // no art for the song, try the album
181       ArtCache::const_iterator i = m_albumArt.find(tag.GetAlbumId());
182       if (i == m_albumArt.end())
183       {
184         m_database->GetArtForItem(tag.GetAlbumId(), "album", artwork);
185         i = m_albumArt.insert(make_pair(tag.GetAlbumId(), artwork)).first;
186       }
187       if (i != m_albumArt.end())
188       {
189         item.AppendArt(i->second, "album");
190         for (map<string, string>::const_iterator j = i->second.begin(); j != i->second.end(); ++j)
191           item.SetArtFallback(j->first, "album." + j->first);
192       }
193     }
194     if (tag.GetType() == "song" || tag.GetType() == "album")
195     { // fanart from the artist
196       string fanart = m_database->GetArtistArtForItem(tag.GetDatabaseId(), tag.GetType(), "fanart");
197       if (!fanart.empty())
198       {
199         item.SetArt("artist.fanart", fanart);
200         item.SetArtFallback("fanart", "artist.fanart");
201       }
202     }
203     m_database->Close();
204   }
205   return !item.GetArt().empty();
206 }
207
208 bool CMusicThumbLoader::GetEmbeddedThumb(const std::string &path, EmbeddedArt &art)
209 {
210   auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(path));
211   CMusicInfoTag tag;
212   if (NULL != pLoader.get())
213     pLoader->Load(path, tag, &art);
214
215   return !art.empty();
216 }