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.
9 #include "RecentlyAddedJob.h"
12 #include "ServiceBroker.h"
13 #include "guilib/GUIComponent.h"
14 #include "guilib/GUIWindow.h"
15 #include "guilib/GUIWindowManager.h"
16 #include "guilib/WindowIDs.h"
17 #include "music/MusicDatabase.h"
18 #include "music/MusicDbUrl.h"
19 #include "music/MusicThumbLoader.h"
20 #include "music/tags/MusicInfoTag.h"
21 #include "settings/AdvancedSettings.h"
22 #include "settings/Settings.h"
23 #include "settings/SettingsComponent.h"
24 #include "utils/StringUtils.h"
25 #include "utils/log.h"
26 #include "video/VideoDatabase.h"
27 #include "video/VideoInfoTag.h"
28 #include "video/VideoThumbLoader.h"
30 #if defined(TARGET_DARWIN_TVOS)
31 #include "platform/darwin/tvos/TVOSTopShelf.h"
36 CRecentlyAddedJob::CRecentlyAddedJob(int flag
)
41 bool CRecentlyAddedJob::UpdateVideo()
43 auto home
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow(WINDOW_HOME
);
45 if ( home
== nullptr )
48 CLog::Log(LOGDEBUG
, "CRecentlyAddedJob::UpdateVideos() - Running RecentlyAdded home screen update");
52 CVideoDatabase videodatabase
;
53 CVideoThumbLoader loader
;
54 loader
.OnLoaderStart();
58 if (videodatabase
.GetRecentlyAddedMoviesNav("videodb://recentlyaddedmovies/", items
, NUM_ITEMS
))
60 for (; i
< items
.Size(); ++i
)
62 auto item
= items
.Get(i
);
63 std::string value
= std::to_string(i
+ 1);
64 std::string strRating
=
65 StringUtils::Format("{:.1f}", item
->GetVideoInfoTag()->GetRating().rating
);
67 home
->SetProperty("LatestMovie." + value
+ ".Title" , item
->GetLabel());
68 home
->SetProperty("LatestMovie." + value
+ ".Rating" , strRating
);
69 home
->SetProperty("LatestMovie." + value
+ ".Year" , item
->GetVideoInfoTag()->GetYear());
70 home
->SetProperty("LatestMovie." + value
+ ".Plot" , item
->GetVideoInfoTag()->m_strPlot
);
71 home
->SetProperty("LatestMovie." + value
+ ".RunningTime" , item
->GetVideoInfoTag()->GetDuration() / 60);
72 home
->SetProperty("LatestMovie." + value
+ ".Path" , item
->GetVideoInfoTag()->m_strFileNameAndPath
);
73 home
->SetProperty("LatestMovie." + value
+ ".Trailer" , item
->GetVideoInfoTag()->m_strTrailer
);
75 if (!item
->HasArt("thumb"))
76 loader
.LoadItem(item
.get());
78 home
->SetProperty("LatestMovie." + value
+ ".Thumb" , item
->GetArt("thumb"));
79 home
->SetProperty("LatestMovie." + value
+ ".Fanart" , item
->GetArt("fanart"));
80 home
->SetProperty("LatestMovie." + value
+ ".Poster" , item
->GetArt("poster"));
83 for (; i
< NUM_ITEMS
; ++i
)
85 std::string value
= std::to_string(i
+ 1);
86 home
->SetProperty("LatestMovie." + value
+ ".Title" , "");
87 home
->SetProperty("LatestMovie." + value
+ ".Thumb" , "");
88 home
->SetProperty("LatestMovie." + value
+ ".Rating" , "");
89 home
->SetProperty("LatestMovie." + value
+ ".Year" , "");
90 home
->SetProperty("LatestMovie." + value
+ ".Plot" , "");
91 home
->SetProperty("LatestMovie." + value
+ ".RunningTime" , "");
92 home
->SetProperty("LatestMovie." + value
+ ".Path" , "");
93 home
->SetProperty("LatestMovie." + value
+ ".Trailer" , "");
94 home
->SetProperty("LatestMovie." + value
+ ".Fanart" , "");
95 home
->SetProperty("LatestMovie." + value
+ ".Poster" , "");
99 CFileItemList TVShowItems
;
101 if (videodatabase
.GetRecentlyAddedEpisodesNav("videodb://recentlyaddedepisodes/", TVShowItems
, NUM_ITEMS
))
103 for (; i
< TVShowItems
.Size(); ++i
)
105 auto item
= TVShowItems
.Get(i
);
106 int EpisodeSeason
= item
->GetVideoInfoTag()->m_iSeason
;
107 int EpisodeNumber
= item
->GetVideoInfoTag()->m_iEpisode
;
108 std::string EpisodeNo
= StringUtils::Format("s{:02}e{:02}", EpisodeSeason
, EpisodeNumber
);
109 std::string value
= std::to_string(i
+ 1);
110 std::string strRating
=
111 StringUtils::Format("{:.1f}", item
->GetVideoInfoTag()->GetRating().rating
);
113 home
->SetProperty("LatestEpisode." + value
+ ".ShowTitle" , item
->GetVideoInfoTag()->m_strShowTitle
);
114 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeTitle" , item
->GetVideoInfoTag()->m_strTitle
);
115 home
->SetProperty("LatestEpisode." + value
+ ".Rating" , strRating
);
116 home
->SetProperty("LatestEpisode." + value
+ ".Plot" , item
->GetVideoInfoTag()->m_strPlot
);
117 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeNo" , EpisodeNo
);
118 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeSeason" , EpisodeSeason
);
119 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeNumber" , EpisodeNumber
);
120 home
->SetProperty("LatestEpisode." + value
+ ".Path" , item
->GetVideoInfoTag()->m_strFileNameAndPath
);
122 if (!item
->HasArt("thumb"))
123 loader
.LoadItem(item
.get());
125 std::string seasonThumb
;
126 if (item
->GetVideoInfoTag()->m_iIdSeason
> 0)
127 seasonThumb
= videodatabase
.GetArtForItem(item
->GetVideoInfoTag()->m_iIdSeason
, MediaTypeSeason
, "thumb");
129 home
->SetProperty("LatestEpisode." + value
+ ".Thumb" , item
->GetArt("thumb"));
130 home
->SetProperty("LatestEpisode." + value
+ ".ShowThumb" , item
->GetArt("tvshow.thumb"));
131 home
->SetProperty("LatestEpisode." + value
+ ".SeasonThumb" , seasonThumb
);
132 home
->SetProperty("LatestEpisode." + value
+ ".Fanart" , item
->GetArt("fanart"));
135 for (; i
< NUM_ITEMS
; ++i
)
137 std::string value
= std::to_string(i
+ 1);
138 home
->SetProperty("LatestEpisode." + value
+ ".ShowTitle" , "");
139 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeTitle" , "");
140 home
->SetProperty("LatestEpisode." + value
+ ".Rating" , "");
141 home
->SetProperty("LatestEpisode." + value
+ ".Plot" , "");
142 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeNo" , "");
143 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeSeason" , "");
144 home
->SetProperty("LatestEpisode." + value
+ ".EpisodeNumber" , "");
145 home
->SetProperty("LatestEpisode." + value
+ ".Path" , "");
146 home
->SetProperty("LatestEpisode." + value
+ ".Thumb" , "");
147 home
->SetProperty("LatestEpisode." + value
+ ".ShowThumb" , "");
148 home
->SetProperty("LatestEpisode." + value
+ ".SeasonThumb" , "");
149 home
->SetProperty("LatestEpisode." + value
+ ".Fanart" , "");
152 #if defined(TARGET_DARWIN_TVOS)
153 // Add recently added Movies and TvShows items on tvOS Kodi TopShelf
154 CTVOSTopShelf::GetInstance().SetTopShelfItems(items
, TVOSTopShelfItemsCategory::MOVIES
);
155 CTVOSTopShelf::GetInstance().SetTopShelfItems(TVShowItems
, TVOSTopShelfItemsCategory::TV_SHOWS
);
159 CFileItemList MusicVideoItems
;
161 if (videodatabase
.GetRecentlyAddedMusicVideosNav("videodb://recentlyaddedmusicvideos/", MusicVideoItems
, NUM_ITEMS
))
163 for (; i
< MusicVideoItems
.Size(); ++i
)
165 auto item
= MusicVideoItems
.Get(i
);
166 std::string value
= std::to_string(i
+ 1);
168 home
->SetProperty("LatestMusicVideo." + value
+ ".Title" , item
->GetLabel());
169 home
->SetProperty("LatestMusicVideo." + value
+ ".Year" , item
->GetVideoInfoTag()->GetYear());
170 home
->SetProperty("LatestMusicVideo." + value
+ ".Plot" , item
->GetVideoInfoTag()->m_strPlot
);
171 home
->SetProperty("LatestMusicVideo." + value
+ ".RunningTime" , item
->GetVideoInfoTag()->GetDuration() / 60);
172 home
->SetProperty("LatestMusicVideo." + value
+ ".Path" , item
->GetVideoInfoTag()->m_strFileNameAndPath
);
173 home
->SetProperty("LatestMusicVideo." + value
+ ".Artist" , StringUtils::Join(item
->GetVideoInfoTag()->m_artist
, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator
));
175 if (!item
->HasArt("thumb"))
176 loader
.LoadItem(item
.get());
178 home
->SetProperty("LatestMusicVideo." + value
+ ".Thumb" , item
->GetArt("thumb"));
179 home
->SetProperty("LatestMusicVideo." + value
+ ".Fanart" , item
->GetArt("fanart"));
182 for (; i
< NUM_ITEMS
; ++i
)
184 std::string value
= std::to_string(i
+ 1);
185 home
->SetProperty("LatestMusicVideo." + value
+ ".Title" , "");
186 home
->SetProperty("LatestMusicVideo." + value
+ ".Thumb" , "");
187 home
->SetProperty("LatestMusicVideo." + value
+ ".Year" , "");
188 home
->SetProperty("LatestMusicVideo." + value
+ ".Plot" , "");
189 home
->SetProperty("LatestMusicVideo." + value
+ ".RunningTime" , "");
190 home
->SetProperty("LatestMusicVideo." + value
+ ".Path" , "");
191 home
->SetProperty("LatestMusicVideo." + value
+ ".Artist" , "");
192 home
->SetProperty("LatestMusicVideo." + value
+ ".Fanart" , "");
195 videodatabase
.Close();
199 bool CRecentlyAddedJob::UpdateMusic()
201 auto home
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow(WINDOW_HOME
);
203 if ( home
== nullptr )
206 CLog::Log(LOGDEBUG
, "CRecentlyAddedJob::UpdateMusic() - Running RecentlyAdded home screen update");
209 CFileItemList musicItems
;
210 CMusicDatabase musicdatabase
;
211 CMusicThumbLoader loader
;
212 loader
.OnLoaderStart();
214 musicdatabase
.Open();
216 if (musicdatabase
.GetRecentlyAddedAlbumSongs("musicdb://songs/", musicItems
, NUM_ITEMS
))
219 std::string strAlbumThumb
;
220 std::string strAlbumFanart
;
221 for (; i
< musicItems
.Size(); ++i
)
223 auto item
= musicItems
.Get(i
);
224 std::string value
= std::to_string(i
+ 1);
226 std::string strRating
;
227 std::string strAlbum
= item
->GetMusicInfoTag()->GetAlbum();
228 std::string strArtist
= item
->GetMusicInfoTag()->GetArtistString();
230 if (idAlbum
!= item
->GetMusicInfoTag()->GetAlbumId())
232 strAlbumThumb
.clear();
233 strAlbumFanart
.clear();
234 idAlbum
= item
->GetMusicInfoTag()->GetAlbumId();
236 if (loader
.LoadItem(item
.get()))
238 strAlbumThumb
= item
->GetArt("thumb");
239 strAlbumFanart
= item
->GetArt("fanart");
243 strRating
= std::to_string(item
->GetMusicInfoTag()->GetUserrating());
245 home
->SetProperty("LatestSong." + value
+ ".Title" , item
->GetMusicInfoTag()->GetTitle());
246 home
->SetProperty("LatestSong." + value
+ ".Year" , item
->GetMusicInfoTag()->GetYear());
247 home
->SetProperty("LatestSong." + value
+ ".Artist" , strArtist
);
248 home
->SetProperty("LatestSong." + value
+ ".Album" , strAlbum
);
249 home
->SetProperty("LatestSong." + value
+ ".Rating" , strRating
);
250 home
->SetProperty("LatestSong." + value
+ ".Path" , item
->GetMusicInfoTag()->GetURL());
251 home
->SetProperty("LatestSong." + value
+ ".Thumb" , strAlbumThumb
);
252 home
->SetProperty("LatestSong." + value
+ ".Fanart" , strAlbumFanart
);
255 for (; i
< NUM_ITEMS
; ++i
)
257 std::string value
= std::to_string(i
+ 1);
258 home
->SetProperty("LatestSong." + value
+ ".Title" , "");
259 home
->SetProperty("LatestSong." + value
+ ".Year" , "");
260 home
->SetProperty("LatestSong." + value
+ ".Artist" , "");
261 home
->SetProperty("LatestSong." + value
+ ".Album" , "");
262 home
->SetProperty("LatestSong." + value
+ ".Rating" , "");
263 home
->SetProperty("LatestSong." + value
+ ".Path" , "");
264 home
->SetProperty("LatestSong." + value
+ ".Thumb" , "");
265 home
->SetProperty("LatestSong." + value
+ ".Fanart" , "");
271 if (musicdatabase
.GetRecentlyAddedAlbums(albums
, NUM_ITEMS
))
274 for (; j
< albums
.size(); ++j
)
276 auto& album
=albums
[j
];
277 std::string value
= std::to_string(j
+ 1);
278 std::string strThumb
;
279 std::string strFanart
;
280 bool artfound
= false;
281 std::vector
<ArtForThumbLoader
> art
;
282 // Get album thumb and fanart for first album artist
283 artfound
= musicdatabase
.GetArtForItem(-1, album
.idAlbum
, -1, true, art
);
286 for (const auto& artitem
: art
)
288 if (artitem
.mediaType
== MediaTypeAlbum
&& artitem
.artType
== "thumb")
289 strThumb
= artitem
.url
;
290 else if (artitem
.mediaType
== MediaTypeArtist
&& artitem
.artType
== "fanart")
291 strFanart
= artitem
.url
;
295 std::string strDBpath
= StringUtils::Format("musicdb://albums/{}/", album
.idAlbum
);
297 home
->SetProperty("LatestAlbum." + value
+ ".Title" , album
.strAlbum
);
298 home
->SetProperty("LatestAlbum." + value
+ ".Year" , album
.strReleaseDate
);
299 home
->SetProperty("LatestAlbum." + value
+ ".Artist" , album
.GetAlbumArtistString());
300 home
->SetProperty("LatestAlbum." + value
+ ".Rating" , album
.fRating
);
301 home
->SetProperty("LatestAlbum." + value
+ ".Path" , strDBpath
);
302 home
->SetProperty("LatestAlbum." + value
+ ".Thumb" , strThumb
);
303 home
->SetProperty("LatestAlbum." + value
+ ".Fanart" , strFanart
);
307 for (; i
< NUM_ITEMS
; ++i
)
309 std::string value
= std::to_string(i
+ 1);
310 home
->SetProperty("LatestAlbum." + value
+ ".Title" , "");
311 home
->SetProperty("LatestAlbum." + value
+ ".Year" , "");
312 home
->SetProperty("LatestAlbum." + value
+ ".Artist" , "");
313 home
->SetProperty("LatestAlbum." + value
+ ".Rating" , "");
314 home
->SetProperty("LatestAlbum." + value
+ ".Path" , "");
315 home
->SetProperty("LatestAlbum." + value
+ ".Thumb" , "");
316 home
->SetProperty("LatestAlbum." + value
+ ".Fanart" , "");
319 musicdatabase
.Close();
323 bool CRecentlyAddedJob::UpdateTotal()
325 auto home
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow(WINDOW_HOME
);
327 if ( home
== nullptr )
330 CLog::Log(LOGDEBUG
, "CRecentlyAddedJob::UpdateTotal() - Running RecentlyAdded home screen update");
332 CVideoDatabase videodatabase
;
333 CMusicDatabase musicdatabase
;
335 musicdatabase
.Open();
337 CMusicDbUrl musicUrl
;
338 musicUrl
.FromString("musicdb://artists/");
339 musicUrl
.AddOption("albumartistsonly", !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MUSICLIBRARY_SHOWCOMPILATIONARTISTS
));
342 CDatabase::Filter filter
;
343 musicdatabase
.GetArtistsByWhere(musicUrl
.ToString(), filter
, items
, SortDescription(), true);
344 int MusArtistTotals
= 0;
345 if (items
.Size() == 1 && items
.Get(0)->HasProperty("total"))
346 MusArtistTotals
= static_cast<int>(items
.Get(0)->GetProperty("total").asInteger());
348 int MusSongTotals
= atoi(musicdatabase
.GetSingleValue("songview" , "count(1)").c_str());
349 int MusAlbumTotals
= atoi(musicdatabase
.GetSingleValue("songview" , "count(distinct strAlbum)").c_str());
350 musicdatabase
.Close();
352 videodatabase
.Open();
353 int tvShowCount
= atoi(videodatabase
.GetSingleValue("tvshow_view" , "count(1)").c_str());
354 int movieTotals
= atoi(videodatabase
.GetSingleValue("movie_view" , "count(1)").c_str());
355 int movieWatched
= atoi(videodatabase
.GetSingleValue("movie_view" , "count(playCount)").c_str());
356 int MusVidTotals
= atoi(videodatabase
.GetSingleValue("musicvideo_view" , "count(1)").c_str());
357 int MusVidWatched
= atoi(videodatabase
.GetSingleValue("musicvideo_view" , "count(playCount)").c_str());
358 int EpWatched
= atoi(videodatabase
.GetSingleValue("tvshow_view" , "sum(watchedcount)").c_str());
359 int EpCount
= atoi(videodatabase
.GetSingleValue("tvshow_view" , "sum(totalcount)").c_str());
360 int TvShowsWatched
= atoi(videodatabase
.GetSingleValue("tvshow_view" , "sum(watchedcount = totalcount)").c_str());
361 videodatabase
.Close();
363 home
->SetProperty("TVShows.Count" , tvShowCount
);
364 home
->SetProperty("TVShows.Watched" , TvShowsWatched
);
365 home
->SetProperty("TVShows.UnWatched" , tvShowCount
- TvShowsWatched
);
366 home
->SetProperty("Episodes.Count" , EpCount
);
367 home
->SetProperty("Episodes.Watched" , EpWatched
);
368 home
->SetProperty("Episodes.UnWatched" , EpCount
-EpWatched
);
369 home
->SetProperty("Movies.Count" , movieTotals
);
370 home
->SetProperty("Movies.Watched" , movieWatched
);
371 home
->SetProperty("Movies.UnWatched" , movieTotals
- movieWatched
);
372 home
->SetProperty("MusicVideos.Count" , MusVidTotals
);
373 home
->SetProperty("MusicVideos.Watched" , MusVidWatched
);
374 home
->SetProperty("MusicVideos.UnWatched" , MusVidTotals
- MusVidWatched
);
375 home
->SetProperty("Music.SongsCount" , MusSongTotals
);
376 home
->SetProperty("Music.AlbumsCount" , MusAlbumTotals
);
377 home
->SetProperty("Music.ArtistsCount" , MusArtistTotals
);
383 bool CRecentlyAddedJob::DoWork()
387 ret
&= UpdateMusic();
390 ret
&= UpdateVideo();
393 ret
&= UpdateTotal();