2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
21 #include "VideoLibrary.h"
22 #include "ApplicationMessenger.h"
23 #include "TextureCache.h"
25 #include "utils/URIUtils.h"
26 #include "video/VideoDatabase.h"
28 using namespace JSONRPC;
30 JSONRPC_STATUS CVideoLibrary::GetMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
32 CVideoDatabase videodatabase;
33 if (!videodatabase.Open())
36 SortDescription sorting;
37 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
38 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
42 videoUrl.FromString("videodb://1/2/");
43 int genreID = -1, year = -1, setID = 0;
44 const CVariant &filter = parameterObject["filter"];
45 if (filter.isMember("genreid"))
46 genreID = (int)filter["genreid"].asInteger();
47 else if (filter.isMember("genre"))
48 videoUrl.AddOption("genre", filter["genre"].asString());
49 else if (filter.isMember("year"))
50 year = (int)filter["year"].asInteger();
51 else if (filter.isMember("actor"))
52 videoUrl.AddOption("actor", filter["actor"].asString());
53 else if (filter.isMember("director"))
54 videoUrl.AddOption("director", filter["director"].asString());
55 else if (filter.isMember("studio"))
56 videoUrl.AddOption("studio", filter["studio"].asString());
57 else if (filter.isMember("country"))
58 videoUrl.AddOption("country", filter["country"].asString());
59 else if (filter.isMember("setid"))
60 setID = (int)filter["setid"].asInteger();
61 else if (filter.isMember("set"))
62 videoUrl.AddOption("set", filter["set"].asString());
63 else if (filter.isMember("tag"))
64 videoUrl.AddOption("tag", filter["tag"].asString());
65 else if (filter.isObject())
68 if (!GetXspFiltering("movies", filter, xsp))
71 videoUrl.AddOption("xsp", xsp);
74 // setID must not be -1 otherwise GetMoviesNav() will return sets
79 if (!videodatabase.GetMoviesNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, setID, -1, sorting))
82 return GetAdditionalMovieDetails(parameterObject, items, result, videodatabase, false);
85 JSONRPC_STATUS CVideoLibrary::GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
87 int id = (int)parameterObject["movieid"].asInteger();
89 CVideoDatabase videodatabase;
90 if (!videodatabase.Open())
94 if (!videodatabase.GetMovieInfo("", infos, id) || infos.m_iDbId <= 0)
97 HandleFileItem("movieid", true, "moviedetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
101 JSONRPC_STATUS CVideoLibrary::GetMovieSets(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
103 CVideoDatabase videodatabase;
104 if (!videodatabase.Open())
105 return InternalError;
108 if (!videodatabase.GetSetsNav("videodb://1/7/", items, VIDEODB_CONTENT_MOVIES))
109 return InternalError;
111 HandleFileItemList("setid", false, "sets", items, parameterObject, result);
115 JSONRPC_STATUS CVideoLibrary::GetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
117 int id = (int)parameterObject["setid"].asInteger();
119 CVideoDatabase videodatabase;
120 if (!videodatabase.Open())
121 return InternalError;
123 // Get movie set details
125 if (!videodatabase.GetSetInfo(id, infos) || infos.m_iDbId <= 0)
126 return InvalidParams;
128 HandleFileItem("setid", false, "setdetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
130 // Get movies from the set
132 if (!videodatabase.GetMoviesNav("videodb://1/2/", items, -1, -1, -1, -1, -1, -1, id))
133 return InternalError;
135 return GetAdditionalMovieDetails(parameterObject["movies"], items, result["setdetails"], videodatabase, true);
138 JSONRPC_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
140 CVideoDatabase videodatabase;
141 if (!videodatabase.Open())
142 return InternalError;
144 SortDescription sorting;
145 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
146 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
147 return InvalidParams;
149 CVideoDbUrl videoUrl;
150 videoUrl.FromString("videodb://2/2/");
151 int genreID = -1, year = -1;
152 const CVariant &filter = parameterObject["filter"];
153 if (filter.isMember("genreid"))
154 genreID = (int)filter["genreid"].asInteger();
155 else if (filter.isMember("genre"))
156 videoUrl.AddOption("genre", filter["genre"].asString());
157 else if (filter.isMember("year"))
158 year = (int)filter["year"].asInteger();
159 else if (filter.isMember("actor"))
160 videoUrl.AddOption("actor", filter["actor"].asString());
161 else if (filter.isMember("studio"))
162 videoUrl.AddOption("studio", filter["studio"].asString());
163 else if (filter.isMember("tag"))
164 videoUrl.AddOption("tag", filter["tag"].asString());
165 else if (filter.isObject())
168 if (!GetXspFiltering("tvshows", filter, xsp))
169 return InvalidParams;
171 videoUrl.AddOption("xsp", xsp);
175 if (!videodatabase.GetTvShowsNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, sorting))
176 return InvalidParams;
178 bool additionalInfo = false;
179 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
181 CStdString fieldValue = itr->asString();
182 if (fieldValue == "cast" || fieldValue == "tag")
183 additionalInfo = true;
188 for (int index = 0; index < items.Size(); index++)
189 videodatabase.GetTvShowInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
192 int size = items.Size();
193 if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
194 size = (int)items.GetProperty("total").asInteger();
195 HandleFileItemList("tvshowid", true, "tvshows", items, parameterObject, result, size, false);
200 JSONRPC_STATUS CVideoLibrary::GetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
202 CVideoDatabase videodatabase;
203 if (!videodatabase.Open())
204 return InternalError;
206 int id = (int)parameterObject["tvshowid"].asInteger();
209 if (!videodatabase.GetTvShowInfo("", infos, id) || infos.m_iDbId <= 0)
210 return InvalidParams;
212 HandleFileItem("tvshowid", true, "tvshowdetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
216 JSONRPC_STATUS CVideoLibrary::GetSeasons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
218 CVideoDatabase videodatabase;
219 if (!videodatabase.Open())
220 return InternalError;
222 int tvshowID = (int)parameterObject["tvshowid"].asInteger();
225 strPath.Format("videodb://2/2/%i/", tvshowID);
227 if (!videodatabase.GetSeasonsNav(strPath, items, -1, -1, -1, -1, tvshowID, false))
228 return InternalError;
230 HandleFileItemList(NULL, false, "seasons", items, parameterObject, result);
234 JSONRPC_STATUS CVideoLibrary::GetEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
236 CVideoDatabase videodatabase;
237 if (!videodatabase.Open())
238 return InternalError;
240 SortDescription sorting;
241 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
242 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
243 return InvalidParams;
245 int tvshowID = (int)parameterObject["tvshowid"].asInteger();
246 int season = (int)parameterObject["season"].asInteger();
249 strPath.Format("videodb://2/2/%i/%i/", tvshowID, season);
251 CVideoDbUrl videoUrl;
252 videoUrl.FromString(strPath);
253 const CVariant &filter = parameterObject["filter"];
254 if (filter.isMember("genreid"))
255 videoUrl.AddOption("genreid", (int)filter["genreid"].asInteger());
256 else if (filter.isMember("genre"))
257 videoUrl.AddOption("genre", filter["genre"].asString());
258 else if (filter.isMember("year"))
259 videoUrl.AddOption("year", (int)filter["year"].asInteger());
260 else if (filter.isMember("actor"))
261 videoUrl.AddOption("actor", filter["actor"].asString());
262 else if (filter.isMember("director"))
263 videoUrl.AddOption("director", filter["director"].asString());
264 else if (filter.isObject())
267 if (!GetXspFiltering("episodes", filter, xsp))
268 return InvalidParams;
270 videoUrl.AddOption("xsp", xsp);
273 if (tvshowID <= 0 && (season > 0 || videoUrl.HasOption("genreid") || videoUrl.HasOption("genre") || videoUrl.HasOption("actor")))
274 return InvalidParams;
278 videoUrl.AddOption("tvshowid", tvshowID);
280 videoUrl.AddOption("season", season);
284 if (!videodatabase.GetEpisodesByWhere(videoUrl.ToString(), CDatabase::Filter(), items, false, sorting))
285 return InvalidParams;
287 return GetAdditionalEpisodeDetails(parameterObject, items, result, videodatabase, false);
290 JSONRPC_STATUS CVideoLibrary::GetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
292 CVideoDatabase videodatabase;
293 if (!videodatabase.Open())
294 return InternalError;
296 int id = (int)parameterObject["episodeid"].asInteger();
299 if (!videodatabase.GetEpisodeInfo("", infos, id) || infos.m_iDbId <= 0)
300 return InvalidParams;
302 CFileItemPtr pItem = CFileItemPtr(new CFileItem(infos));
303 // We need to set the correct base path to get the valid fanart
304 int tvshowid = infos.m_iIdShow;
306 tvshowid = videodatabase.GetTvShowForEpisode(id);
308 CStdString basePath; basePath.Format("videodb://2/2/%ld/%ld/%ld", tvshowid, infos.m_iSeason, id);
309 pItem->SetPath(basePath);
311 HandleFileItem("episodeid", true, "episodedetails", pItem, parameterObject, parameterObject["properties"], result, false);
315 JSONRPC_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
317 CVideoDatabase videodatabase;
318 if (!videodatabase.Open())
319 return InternalError;
321 SortDescription sorting;
322 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
323 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
324 return InvalidParams;
326 CVideoDbUrl videoUrl;
327 videoUrl.FromString("videodb://3/2/");
328 int genreID = -1, year = -1;
329 const CVariant &filter = parameterObject["filter"];
330 if (filter.isMember("artist"))
331 videoUrl.AddOption("artist", filter["artist"].asString());
332 else if (filter.isMember("genreid"))
333 genreID = (int)filter["genreid"].asInteger();
334 else if (filter.isMember("genre"))
335 videoUrl.AddOption("genre", filter["genre"].asString());
336 else if (filter.isMember("year"))
337 year = (int)filter["year"].asInteger();
338 else if (filter.isMember("director"))
339 videoUrl.AddOption("director", filter["director"].asString());
340 else if (filter.isMember("studio"))
341 videoUrl.AddOption("studio", filter["studio"].asString());
342 else if (filter.isMember("tag"))
343 videoUrl.AddOption("tag", filter["tag"].asString());
344 else if (filter.isObject())
347 if (!GetXspFiltering("musicvideos", filter, xsp))
348 return InvalidParams;
350 videoUrl.AddOption("xsp", xsp);
354 if (!videodatabase.GetMusicVideosNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, -1, sorting))
355 return InternalError;
357 return GetAdditionalMusicVideoDetails(parameterObject, items, result, videodatabase, false);
360 JSONRPC_STATUS CVideoLibrary::GetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
362 CVideoDatabase videodatabase;
363 if (!videodatabase.Open())
364 return InternalError;
366 int id = (int)parameterObject["musicvideoid"].asInteger();
369 if (!videodatabase.GetMusicVideoInfo("", infos, id) || infos.m_iDbId <= 0)
370 return InvalidParams;
372 HandleFileItem("musicvideoid", true, "musicvideodetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
376 JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
378 CVideoDatabase videodatabase;
379 if (!videodatabase.Open())
380 return InternalError;
383 if (!videodatabase.GetRecentlyAddedMoviesNav("videodb://4/", items))
384 return InternalError;
386 return GetAdditionalMovieDetails(parameterObject, items, result, videodatabase, true);
389 JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
391 CVideoDatabase videodatabase;
392 if (!videodatabase.Open())
393 return InternalError;
396 if (!videodatabase.GetRecentlyAddedEpisodesNav("videodb://5/", items))
397 return InternalError;
399 return GetAdditionalEpisodeDetails(parameterObject, items, result, videodatabase, true);
402 JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
404 CVideoDatabase videodatabase;
405 if (!videodatabase.Open())
406 return InternalError;
409 if (!videodatabase.GetRecentlyAddedMusicVideosNav("videodb://6/", items))
410 return InternalError;
412 return GetAdditionalMusicVideoDetails(parameterObject, items, result, videodatabase, true);
415 JSONRPC_STATUS CVideoLibrary::GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
417 CStdString media = parameterObject["type"].asString();
418 media = media.ToLower();
421 CStdString strPath = "videodb://";
422 /* select which video content to get genres from*/
423 if (media.Equals("movie"))
425 idContent = VIDEODB_CONTENT_MOVIES;
428 else if (media.Equals("tvshow"))
430 idContent = VIDEODB_CONTENT_TVSHOWS;
433 else if (media.Equals("musicvideo"))
435 idContent = VIDEODB_CONTENT_MUSICVIDEOS;
440 CVideoDatabase videodatabase;
441 if (!videodatabase.Open())
442 return InternalError;
445 if (!videodatabase.GetGenresNav(strPath, items, idContent))
446 return InternalError;
448 /* need to set strTitle in each item*/
449 for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
450 items[i]->GetVideoInfoTag()->m_strTitle = items[i]->GetLabel();
452 HandleFileItemList("genreid", false, "genres", items, parameterObject, result);
456 JSONRPC_STATUS CVideoLibrary::SetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
458 int id = (int)parameterObject["movieid"].asInteger();
460 CVideoDatabase videodatabase;
461 if (!videodatabase.Open())
462 return InternalError;
465 if (!videodatabase.GetMovieInfo("", infos, id) || infos.m_iDbId <= 0)
466 return InvalidParams;
469 std::map<std::string, std::string> artwork;
470 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
472 int playcount = infos.m_playCount;
473 CDateTime lastPlayed = infos.m_lastPlayed;
475 UpdateVideoTag(parameterObject, infos, artwork);
477 // we need to manually remove tags/taglinks for now because they aren't replaced
478 // due to scrapers not supporting them
479 videodatabase.RemoveTagsFromItem(id, "movie");
481 if (videodatabase.SetDetailsForMovie(infos.m_strFileNameAndPath, infos, artwork, id) <= 0)
482 return InternalError;
484 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
486 // restore original playcount or the new one won't be announced
487 int newPlaycount = infos.m_playCount;
488 infos.m_playCount = playcount;
489 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
492 CJSONRPCUtils::NotifyItemUpdated();
496 JSONRPC_STATUS CVideoLibrary::SetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
498 int id = (int)parameterObject["tvshowid"].asInteger();
500 CVideoDatabase videodatabase;
501 if (!videodatabase.Open())
502 return InternalError;
505 if (!videodatabase.GetTvShowInfo("", infos, id) || infos.m_iDbId <= 0)
506 return InvalidParams;
509 std::map<std::string, std::string> artwork;
510 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
512 std::map<int, std::map<std::string, std::string> > seasonArt;
513 videodatabase.GetTvShowSeasonArt(infos.m_iDbId, seasonArt);
515 int playcount = infos.m_playCount;
516 CDateTime lastPlayed = infos.m_lastPlayed;
518 UpdateVideoTag(parameterObject, infos, artwork);
520 // we need to manually remove tags/taglinks for now because they aren't replaced
521 // due to scrapers not supporting them
522 videodatabase.RemoveTagsFromItem(id, "tvshow");
524 if (videodatabase.SetDetailsForTvShow(infos.m_strFileNameAndPath, infos, artwork, seasonArt, id) <= 0)
525 return InternalError;
527 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
529 // restore original playcount or the new one won't be announced
530 int newPlaycount = infos.m_playCount;
531 infos.m_playCount = playcount;
532 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
535 CJSONRPCUtils::NotifyItemUpdated();
539 JSONRPC_STATUS CVideoLibrary::SetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
541 int id = (int)parameterObject["episodeid"].asInteger();
543 CVideoDatabase videodatabase;
544 if (!videodatabase.Open())
545 return InternalError;
548 videodatabase.GetEpisodeInfo("", infos, id);
549 if (infos.m_iDbId <= 0)
551 videodatabase.Close();
552 return InvalidParams;
555 int tvshowid = videodatabase.GetTvShowForEpisode(id);
558 videodatabase.Close();
559 return InvalidParams;
563 std::map<std::string, std::string> artwork;
564 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
566 int playcount = infos.m_playCount;
567 CDateTime lastPlayed = infos.m_lastPlayed;
569 UpdateVideoTag(parameterObject, infos, artwork);
571 if (videodatabase.SetDetailsForEpisode(infos.m_strFileNameAndPath, infos, artwork, tvshowid, id) <= 0)
572 return InternalError;
574 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
576 // restore original playcount or the new one won't be announced
577 int newPlaycount = infos.m_playCount;
578 infos.m_playCount = playcount;
579 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
582 CJSONRPCUtils::NotifyItemUpdated();
586 JSONRPC_STATUS CVideoLibrary::SetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
588 int id = (int)parameterObject["musicvideoid"].asInteger();
590 CVideoDatabase videodatabase;
591 if (!videodatabase.Open())
592 return InternalError;
595 videodatabase.GetMusicVideoInfo("", infos, id);
596 if (infos.m_iDbId <= 0)
598 videodatabase.Close();
599 return InvalidParams;
603 std::map<std::string, std::string> artwork;
604 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
606 int playcount = infos.m_playCount;
607 CDateTime lastPlayed = infos.m_lastPlayed;
609 UpdateVideoTag(parameterObject, infos, artwork);
611 // we need to manually remove tags/taglinks for now because they aren't replaced
612 // due to scrapers not supporting them
613 videodatabase.RemoveTagsFromItem(id, "musicvideo");
615 if (videodatabase.SetDetailsForMusicVideo(infos.m_strFileNameAndPath, infos, artwork, id) <= 0)
616 return InternalError;
618 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
620 // restore original playcount or the new one won't be announced
621 int newPlaycount = infos.m_playCount;
622 infos.m_playCount = playcount;
623 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
626 CJSONRPCUtils::NotifyItemUpdated();
630 JSONRPC_STATUS CVideoLibrary::RemoveMovie(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
632 return RemoveVideo(parameterObject);
635 JSONRPC_STATUS CVideoLibrary::RemoveTVShow(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
637 return RemoveVideo(parameterObject);
640 JSONRPC_STATUS CVideoLibrary::RemoveEpisode(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
642 return RemoveVideo(parameterObject);
645 JSONRPC_STATUS CVideoLibrary::RemoveMusicVideo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
647 return RemoveVideo(parameterObject);
650 JSONRPC_STATUS CVideoLibrary::Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
652 std::string directory = parameterObject["directory"].asString();
654 if (directory.empty())
655 cmd = "updatelibrary(video)";
657 cmd.Format("updatelibrary(video, %s)", directory.c_str());
659 CApplicationMessenger::Get().ExecBuiltIn(cmd);
663 JSONRPC_STATUS CVideoLibrary::Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
666 if (parameterObject["options"].isMember("path"))
667 cmd.Format("exportlibrary(video, false, %s)", parameterObject["options"]["path"].asString());
669 cmd.Format("exportlibrary(video, true, %s, %s, %s)",
670 parameterObject["options"]["images"].asBoolean() ? "true" : "false",
671 parameterObject["options"]["overwrite"].asBoolean() ? "true" : "false",
672 parameterObject["options"]["actorthumbs"].asBoolean() ? "true" : "false");
674 CApplicationMessenger::Get().ExecBuiltIn(cmd);
678 JSONRPC_STATUS CVideoLibrary::Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
680 CApplicationMessenger::Get().ExecBuiltIn("cleanlibrary(video)");
684 bool CVideoLibrary::FillFileItem(const CStdString &strFilename, CFileItemPtr &item, const CVariant ¶meterObject /* = CVariant(CVariant::VariantTypeArray) */)
686 CVideoDatabase videodatabase;
687 if (strFilename.empty() || !videodatabase.Open())
690 CVideoInfoTag details;
691 if (!videodatabase.LoadVideoInfo(strFilename, details))
694 item->SetFromVideoInfoTag(details);
695 if (item->GetLabel().empty())
696 item->SetLabel(CUtil::GetTitleFromPath(strFilename, false));
697 if (item->GetLabel())
698 item->SetLabel(URIUtils::GetFileName(strFilename));
702 bool CVideoLibrary::FillFileItemList(const CVariant ¶meterObject, CFileItemList &list)
704 CVideoDatabase videodatabase;
705 if (!videodatabase.Open())
708 CStdString file = parameterObject["file"].asString();
709 int movieID = (int)parameterObject["movieid"].asInteger(-1);
710 int episodeID = (int)parameterObject["episodeid"].asInteger(-1);
711 int musicVideoID = (int)parameterObject["musicvideoid"].asInteger(-1);
713 bool success = false;
714 CFileItemPtr fileItem(new CFileItem());
715 if (FillFileItem(file, fileItem))
723 CVideoInfoTag details;
724 videodatabase.GetMovieInfo("", details, movieID);
725 if (!details.IsEmpty())
727 list.Add(CFileItemPtr(new CFileItem(details)));
733 CVideoInfoTag details;
734 if (videodatabase.GetEpisodeInfo("", details, episodeID) && !details.IsEmpty())
736 list.Add(CFileItemPtr(new CFileItem(details)));
740 if (musicVideoID > 0)
742 CVideoInfoTag details;
743 videodatabase.GetMusicVideoInfo("", details, musicVideoID);
744 if (!details.IsEmpty())
746 list.Add(CFileItemPtr(new CFileItem(details)));
754 JSONRPC_STATUS CVideoLibrary::GetAdditionalMovieDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */)
756 if (!videodatabase.Open())
757 return InternalError;
759 bool additionalInfo = false;
760 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
762 CStdString fieldValue = itr->asString();
763 if (fieldValue == "cast" || fieldValue == "showlink" || fieldValue == "tag" || fieldValue == "streamdetails")
764 additionalInfo = true;
769 for (int index = 0; index < items.Size(); index++)
772 videodatabase.GetMovieInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
776 int size = items.Size();
777 if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
778 size = (int)items.GetProperty("total").asInteger();
779 HandleFileItemList("movieid", true, "movies", items, parameterObject, result, size, limit);
784 JSONRPC_STATUS CVideoLibrary::GetAdditionalEpisodeDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */)
786 if (!videodatabase.Open())
787 return InternalError;
789 bool additionalInfo = false;
790 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
792 CStdString fieldValue = itr->asString();
793 if (fieldValue == "cast" || fieldValue == "streamdetails")
794 additionalInfo = true;
799 for (int index = 0; index < items.Size(); index++)
802 videodatabase.GetEpisodeInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
806 int size = items.Size();
807 if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
808 size = (int)items.GetProperty("total").asInteger();
809 HandleFileItemList("episodeid", true, "episodes", items, parameterObject, result, size, limit);
814 JSONRPC_STATUS CVideoLibrary::GetAdditionalMusicVideoDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */)
816 if (!videodatabase.Open())
817 return InternalError;
819 bool streamdetails = false;
820 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
822 if (itr->asString() == "tag" || itr->asString() == "streamdetails")
823 streamdetails = true;
828 for (int index = 0; index < items.Size(); index++)
829 videodatabase.GetMusicVideoInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
832 int size = items.Size();
833 if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
834 size = (int)items.GetProperty("total").asInteger();
835 HandleFileItemList("musicvideoid", true, "musicvideos", items, parameterObject, result, size, limit);
840 JSONRPC_STATUS CVideoLibrary::RemoveVideo(const CVariant ¶meterObject)
842 CVideoDatabase videodatabase;
843 if (!videodatabase.Open())
844 return InternalError;
846 if (parameterObject.isMember("movieid"))
847 videodatabase.DeleteMovie((int)parameterObject["movieid"].asInteger());
848 else if (parameterObject.isMember("tvshowid"))
849 videodatabase.DeleteTvShow((int)parameterObject["tvshowid"].asInteger());
850 else if (parameterObject.isMember("episodeid"))
851 videodatabase.DeleteEpisode((int)parameterObject["episodeid"].asInteger());
852 else if (parameterObject.isMember("musicvideoid"))
853 videodatabase.DeleteMusicVideo((int)parameterObject["musicvideoid"].asInteger());
855 CJSONRPCUtils::NotifyItemUpdated();
859 void CVideoLibrary::UpdateVideoTag(const CVariant ¶meterObject, CVideoInfoTag& details, std::map<std::string, std::string> &artwork)
861 if (ParameterNotNull(parameterObject, "title"))
862 details.m_strTitle = parameterObject["title"].asString();
863 if (ParameterNotNull(parameterObject, "playcount"))
864 details.m_playCount = (int)parameterObject["playcount"].asInteger();
865 if (ParameterNotNull(parameterObject, "runtime"))
866 details.m_duration = (int)parameterObject["runtime"].asInteger();
867 if (ParameterNotNull(parameterObject, "director"))
868 CopyStringArray(parameterObject["director"], details.m_director);
869 if (ParameterNotNull(parameterObject, "studio"))
870 CopyStringArray(parameterObject["studio"], details.m_studio);
871 if (ParameterNotNull(parameterObject, "year"))
872 details.m_iYear = (int)parameterObject["year"].asInteger();
873 if (ParameterNotNull(parameterObject, "plot"))
874 details.m_strPlot = parameterObject["plot"].asString();
875 if (ParameterNotNull(parameterObject, "album"))
876 details.m_strAlbum = parameterObject["album"].asString();
877 if (ParameterNotNull(parameterObject, "artist"))
878 CopyStringArray(parameterObject["artist"], details.m_artist);
879 if (ParameterNotNull(parameterObject, "genre"))
880 CopyStringArray(parameterObject["genre"], details.m_genre);
881 if (ParameterNotNull(parameterObject, "track"))
882 details.m_iTrack = (int)parameterObject["track"].asInteger();
883 if (ParameterNotNull(parameterObject, "rating"))
884 details.m_fRating = parameterObject["rating"].asFloat();
885 if (ParameterNotNull(parameterObject, "mpaa"))
886 details.m_strMPAARating = parameterObject["mpaa"].asString();
887 if (ParameterNotNull(parameterObject, "imdbnumber"))
888 details.m_strIMDBNumber = parameterObject["imdbnumber"].asString();
889 if (ParameterNotNull(parameterObject, "premiered"))
890 details.m_premiered.SetFromDBDate(parameterObject["premiered"].asString());
891 if (ParameterNotNull(parameterObject, "votes"))
892 details.m_strVotes = parameterObject["votes"].asString();
893 if (ParameterNotNull(parameterObject, "lastplayed"))
894 details.m_lastPlayed.SetFromDBDateTime(parameterObject["lastplayed"].asString());
895 if (ParameterNotNull(parameterObject, "firstaired"))
896 details.m_firstAired.SetFromDBDateTime(parameterObject["firstaired"].asString());
897 if (ParameterNotNull(parameterObject, "productioncode"))
898 details.m_strProductionCode = parameterObject["productioncode"].asString();
899 if (ParameterNotNull(parameterObject, "season"))
900 details.m_iSeason = (int)parameterObject["season"].asInteger();
901 if (ParameterNotNull(parameterObject, "episode"))
902 details.m_iEpisode = (int)parameterObject["episode"].asInteger();
903 if (ParameterNotNull(parameterObject, "originaltitle"))
904 details.m_strOriginalTitle = parameterObject["originaltitle"].asString();
905 if (ParameterNotNull(parameterObject, "trailer"))
906 details.m_strTrailer = parameterObject["trailer"].asString();
907 if (ParameterNotNull(parameterObject, "tagline"))
908 details.m_strTagLine = parameterObject["tagline"].asString();
909 if (ParameterNotNull(parameterObject, "plotoutline"))
910 details.m_strPlotOutline = parameterObject["plotoutline"].asString();
911 if (ParameterNotNull(parameterObject, "writer"))
912 CopyStringArray(parameterObject["writer"], details.m_writingCredits);
913 if (ParameterNotNull(parameterObject, "country"))
914 CopyStringArray(parameterObject["country"], details.m_country);
915 if (ParameterNotNull(parameterObject, "top250"))
916 details.m_iTop250 = (int)parameterObject["top250"].asInteger();
917 if (ParameterNotNull(parameterObject, "sorttitle"))
918 details.m_strSortTitle = parameterObject["sorttitle"].asString();
919 if (ParameterNotNull(parameterObject, "episodeguide"))
920 details.m_strEpisodeGuide = parameterObject["episodeguide"].asString();
921 if (ParameterNotNull(parameterObject, "set"))
922 details.m_strSet = parameterObject["set"].asString();
923 if (ParameterNotNull(parameterObject, "showlink"))
924 CopyStringArray(parameterObject["showlink"], details.m_showLink);
925 if (ParameterNotNull(parameterObject, "thumbnail"))
926 artwork["thumb"] = parameterObject["thumbnail"].asString();
927 if (ParameterNotNull(parameterObject, "fanart"))
928 artwork["fanart"] = parameterObject["fanart"].asString();
929 if (ParameterNotNull(parameterObject, "tag"))
930 CopyStringArray(parameterObject["tag"], details.m_tags);
931 if (ParameterNotNull(parameterObject, "art"))
933 CVariant art = parameterObject["art"];
934 for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++)
936 if (!artIt->second.asString().empty())
937 artwork[artIt->first] = CTextureCache::UnwrapImageURL(artIt->second.asString());