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/StringUtils.h"
26 #include "utils/URIUtils.h"
27 #include "video/VideoDatabase.h"
29 using namespace JSONRPC;
31 JSONRPC_STATUS CVideoLibrary::GetMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
33 CVideoDatabase videodatabase;
34 if (!videodatabase.Open())
37 SortDescription sorting;
38 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
39 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
43 videoUrl.FromString("videodb://movies/titles/");
44 int genreID = -1, year = -1, setID = 0;
45 const CVariant &filter = parameterObject["filter"];
46 if (filter.isMember("genreid"))
47 genreID = (int)filter["genreid"].asInteger();
48 else if (filter.isMember("genre"))
49 videoUrl.AddOption("genre", filter["genre"].asString());
50 else if (filter.isMember("year"))
51 year = (int)filter["year"].asInteger();
52 else if (filter.isMember("actor"))
53 videoUrl.AddOption("actor", filter["actor"].asString());
54 else if (filter.isMember("director"))
55 videoUrl.AddOption("director", filter["director"].asString());
56 else if (filter.isMember("studio"))
57 videoUrl.AddOption("studio", filter["studio"].asString());
58 else if (filter.isMember("country"))
59 videoUrl.AddOption("country", filter["country"].asString());
60 else if (filter.isMember("setid"))
61 setID = (int)filter["setid"].asInteger();
62 else if (filter.isMember("set"))
63 videoUrl.AddOption("set", filter["set"].asString());
64 else if (filter.isMember("tag"))
65 videoUrl.AddOption("tag", filter["tag"].asString());
66 else if (filter.isObject())
69 if (!GetXspFiltering("movies", filter, xsp))
72 videoUrl.AddOption("xsp", xsp);
75 // setID must not be -1 otherwise GetMoviesNav() will return sets
80 if (!videodatabase.GetMoviesNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, setID, -1, sorting))
83 return GetAdditionalMovieDetails(parameterObject, items, result, videodatabase, false);
86 JSONRPC_STATUS CVideoLibrary::GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
88 int id = (int)parameterObject["movieid"].asInteger();
90 CVideoDatabase videodatabase;
91 if (!videodatabase.Open())
95 if (!videodatabase.GetMovieInfo("", infos, id) || infos.m_iDbId <= 0)
98 HandleFileItem("movieid", true, "moviedetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
102 JSONRPC_STATUS CVideoLibrary::GetMovieSets(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
104 CVideoDatabase videodatabase;
105 if (!videodatabase.Open())
106 return InternalError;
109 if (!videodatabase.GetSetsNav("videodb://movies/sets/", items, VIDEODB_CONTENT_MOVIES))
110 return InternalError;
112 HandleFileItemList("setid", false, "sets", items, parameterObject, result);
116 JSONRPC_STATUS CVideoLibrary::GetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
118 int id = (int)parameterObject["setid"].asInteger();
120 CVideoDatabase videodatabase;
121 if (!videodatabase.Open())
122 return InternalError;
124 // Get movie set details
126 if (!videodatabase.GetSetInfo(id, infos) || infos.m_iDbId <= 0)
127 return InvalidParams;
129 HandleFileItem("setid", false, "setdetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
131 // Get movies from the set
133 if (!videodatabase.GetMoviesNav("videodb://movies/titles/", items, -1, -1, -1, -1, -1, -1, id))
134 return InternalError;
136 return GetAdditionalMovieDetails(parameterObject["movies"], items, result["setdetails"], videodatabase, true);
139 JSONRPC_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
141 CVideoDatabase videodatabase;
142 if (!videodatabase.Open())
143 return InternalError;
145 SortDescription sorting;
146 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
147 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
148 return InvalidParams;
150 CVideoDbUrl videoUrl;
151 videoUrl.FromString("videodb://tvshows/titles/");
152 int genreID = -1, year = -1;
153 const CVariant &filter = parameterObject["filter"];
154 if (filter.isMember("genreid"))
155 genreID = (int)filter["genreid"].asInteger();
156 else if (filter.isMember("genre"))
157 videoUrl.AddOption("genre", filter["genre"].asString());
158 else if (filter.isMember("year"))
159 year = (int)filter["year"].asInteger();
160 else if (filter.isMember("actor"))
161 videoUrl.AddOption("actor", filter["actor"].asString());
162 else if (filter.isMember("studio"))
163 videoUrl.AddOption("studio", filter["studio"].asString());
164 else if (filter.isMember("tag"))
165 videoUrl.AddOption("tag", filter["tag"].asString());
166 else if (filter.isObject())
169 if (!GetXspFiltering("tvshows", filter, xsp))
170 return InvalidParams;
172 videoUrl.AddOption("xsp", xsp);
176 if (!videodatabase.GetTvShowsNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, sorting))
177 return InvalidParams;
179 bool additionalInfo = false;
180 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
182 CStdString fieldValue = itr->asString();
183 if (fieldValue == "cast" || fieldValue == "tag")
184 additionalInfo = true;
189 for (int index = 0; index < items.Size(); index++)
190 videodatabase.GetTvShowInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
193 int size = items.Size();
194 if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
195 size = (int)items.GetProperty("total").asInteger();
196 HandleFileItemList("tvshowid", true, "tvshows", items, parameterObject, result, size, false);
201 JSONRPC_STATUS CVideoLibrary::GetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
203 CVideoDatabase videodatabase;
204 if (!videodatabase.Open())
205 return InternalError;
207 int id = (int)parameterObject["tvshowid"].asInteger();
210 if (!videodatabase.GetTvShowInfo("", infos, id) || infos.m_iDbId <= 0)
211 return InvalidParams;
213 HandleFileItem("tvshowid", true, "tvshowdetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
217 JSONRPC_STATUS CVideoLibrary::GetSeasons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
219 CVideoDatabase videodatabase;
220 if (!videodatabase.Open())
221 return InternalError;
223 int tvshowID = (int)parameterObject["tvshowid"].asInteger();
226 strPath.Format("videodb://tvshows/titles/%i/", tvshowID);
228 if (!videodatabase.GetSeasonsNav(strPath, items, -1, -1, -1, -1, tvshowID, false))
229 return InternalError;
231 HandleFileItemList(NULL, false, "seasons", items, parameterObject, result);
235 JSONRPC_STATUS CVideoLibrary::GetEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
237 CVideoDatabase videodatabase;
238 if (!videodatabase.Open())
239 return InternalError;
241 SortDescription sorting;
242 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
243 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
244 return InvalidParams;
246 int tvshowID = (int)parameterObject["tvshowid"].asInteger();
247 int season = (int)parameterObject["season"].asInteger();
250 strPath.Format("videodb://tvshows/titles/%i/%i/", tvshowID, season);
252 CVideoDbUrl videoUrl;
253 videoUrl.FromString(strPath);
254 const CVariant &filter = parameterObject["filter"];
255 if (filter.isMember("genreid"))
256 videoUrl.AddOption("genreid", (int)filter["genreid"].asInteger());
257 else if (filter.isMember("genre"))
258 videoUrl.AddOption("genre", filter["genre"].asString());
259 else if (filter.isMember("year"))
260 videoUrl.AddOption("year", (int)filter["year"].asInteger());
261 else if (filter.isMember("actor"))
262 videoUrl.AddOption("actor", filter["actor"].asString());
263 else if (filter.isMember("director"))
264 videoUrl.AddOption("director", filter["director"].asString());
265 else if (filter.isObject())
268 if (!GetXspFiltering("episodes", filter, xsp))
269 return InvalidParams;
271 videoUrl.AddOption("xsp", xsp);
274 if (tvshowID <= 0 && (season > 0 || videoUrl.HasOption("genreid") || videoUrl.HasOption("genre") || videoUrl.HasOption("actor")))
275 return InvalidParams;
279 videoUrl.AddOption("tvshowid", tvshowID);
281 videoUrl.AddOption("season", season);
285 if (!videodatabase.GetEpisodesByWhere(videoUrl.ToString(), CDatabase::Filter(), items, false, sorting))
286 return InvalidParams;
288 return GetAdditionalEpisodeDetails(parameterObject, items, result, videodatabase, false);
291 JSONRPC_STATUS CVideoLibrary::GetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
293 CVideoDatabase videodatabase;
294 if (!videodatabase.Open())
295 return InternalError;
297 int id = (int)parameterObject["episodeid"].asInteger();
300 if (!videodatabase.GetEpisodeInfo("", infos, id) || infos.m_iDbId <= 0)
301 return InvalidParams;
303 CFileItemPtr pItem = CFileItemPtr(new CFileItem(infos));
304 // We need to set the correct base path to get the valid fanart
305 int tvshowid = infos.m_iIdShow;
307 tvshowid = videodatabase.GetTvShowForEpisode(id);
309 CStdString basePath; basePath.Format("videodb://tvshows/titles/%ld/%ld/%ld", tvshowid, infos.m_iSeason, id);
310 pItem->SetPath(basePath);
312 HandleFileItem("episodeid", true, "episodedetails", pItem, parameterObject, parameterObject["properties"], result, false);
316 JSONRPC_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
318 CVideoDatabase videodatabase;
319 if (!videodatabase.Open())
320 return InternalError;
322 SortDescription sorting;
323 ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
324 if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
325 return InvalidParams;
327 CVideoDbUrl videoUrl;
328 videoUrl.FromString("videodb://musicvideos/titles/");
329 int genreID = -1, year = -1;
330 const CVariant &filter = parameterObject["filter"];
331 if (filter.isMember("artist"))
332 videoUrl.AddOption("artist", filter["artist"].asString());
333 else if (filter.isMember("genreid"))
334 genreID = (int)filter["genreid"].asInteger();
335 else if (filter.isMember("genre"))
336 videoUrl.AddOption("genre", filter["genre"].asString());
337 else if (filter.isMember("year"))
338 year = (int)filter["year"].asInteger();
339 else if (filter.isMember("director"))
340 videoUrl.AddOption("director", filter["director"].asString());
341 else if (filter.isMember("studio"))
342 videoUrl.AddOption("studio", filter["studio"].asString());
343 else if (filter.isMember("tag"))
344 videoUrl.AddOption("tag", filter["tag"].asString());
345 else if (filter.isObject())
348 if (!GetXspFiltering("musicvideos", filter, xsp))
349 return InvalidParams;
351 videoUrl.AddOption("xsp", xsp);
355 if (!videodatabase.GetMusicVideosNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, -1, sorting))
356 return InternalError;
358 return GetAdditionalMusicVideoDetails(parameterObject, items, result, videodatabase, false);
361 JSONRPC_STATUS CVideoLibrary::GetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
363 CVideoDatabase videodatabase;
364 if (!videodatabase.Open())
365 return InternalError;
367 int id = (int)parameterObject["musicvideoid"].asInteger();
370 if (!videodatabase.GetMusicVideoInfo("", infos, id) || infos.m_iDbId <= 0)
371 return InvalidParams;
373 HandleFileItem("musicvideoid", true, "musicvideodetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false);
377 JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
379 CVideoDatabase videodatabase;
380 if (!videodatabase.Open())
381 return InternalError;
384 if (!videodatabase.GetRecentlyAddedMoviesNav("videodb://recentlyaddedmovies/", items))
385 return InternalError;
387 return GetAdditionalMovieDetails(parameterObject, items, result, videodatabase, true);
390 JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
392 CVideoDatabase videodatabase;
393 if (!videodatabase.Open())
394 return InternalError;
397 if (!videodatabase.GetRecentlyAddedEpisodesNav("videodb://recentlyaddedepisodes/", items))
398 return InternalError;
400 return GetAdditionalEpisodeDetails(parameterObject, items, result, videodatabase, true);
403 JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
405 CVideoDatabase videodatabase;
406 if (!videodatabase.Open())
407 return InternalError;
410 if (!videodatabase.GetRecentlyAddedMusicVideosNav("videodb://recentlyaddedmusicvideos/", items))
411 return InternalError;
413 return GetAdditionalMusicVideoDetails(parameterObject, items, result, videodatabase, true);
416 JSONRPC_STATUS CVideoLibrary::GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
418 CStdString media = parameterObject["type"].asString();
419 media = media.ToLower();
422 CStdString strPath = "videodb://";
423 /* select which video content to get genres from*/
424 if (media.Equals("movie"))
426 idContent = VIDEODB_CONTENT_MOVIES;
429 else if (media.Equals("tvshow"))
431 idContent = VIDEODB_CONTENT_TVSHOWS;
432 strPath += "tvshows";
434 else if (media.Equals("musicvideo"))
436 idContent = VIDEODB_CONTENT_MUSICVIDEOS;
437 strPath += "musicvideos";
439 strPath += "/genres/";
441 CVideoDatabase videodatabase;
442 if (!videodatabase.Open())
443 return InternalError;
446 if (!videodatabase.GetGenresNav(strPath, items, idContent))
447 return InternalError;
449 /* need to set strTitle in each item*/
450 for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
451 items[i]->GetVideoInfoTag()->m_strTitle = items[i]->GetLabel();
453 HandleFileItemList("genreid", false, "genres", items, parameterObject, result);
457 JSONRPC_STATUS CVideoLibrary::SetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
459 int id = (int)parameterObject["movieid"].asInteger();
461 CVideoDatabase videodatabase;
462 if (!videodatabase.Open())
463 return InternalError;
466 if (!videodatabase.GetMovieInfo("", infos, id) || infos.m_iDbId <= 0)
467 return InvalidParams;
470 std::map<std::string, std::string> artwork;
471 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
473 int playcount = infos.m_playCount;
474 CDateTime lastPlayed = infos.m_lastPlayed;
476 UpdateVideoTag(parameterObject, infos, artwork);
478 // we need to manually remove tags/taglinks for now because they aren't replaced
479 // due to scrapers not supporting them
480 videodatabase.RemoveTagsFromItem(id, "movie");
482 if (videodatabase.SetDetailsForMovie(infos.m_strFileNameAndPath, infos, artwork, id) <= 0)
483 return InternalError;
485 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
487 // restore original playcount or the new one won't be announced
488 int newPlaycount = infos.m_playCount;
489 infos.m_playCount = playcount;
490 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
493 UpdateResumePoint(parameterObject, infos, videodatabase);
495 CJSONRPCUtils::NotifyItemUpdated();
499 JSONRPC_STATUS CVideoLibrary::SetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
501 int id = (int)parameterObject["tvshowid"].asInteger();
503 CVideoDatabase videodatabase;
504 if (!videodatabase.Open())
505 return InternalError;
508 if (!videodatabase.GetTvShowInfo("", infos, id) || infos.m_iDbId <= 0)
509 return InvalidParams;
512 std::map<std::string, std::string> artwork;
513 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
515 std::map<int, std::map<std::string, std::string> > seasonArt;
516 videodatabase.GetTvShowSeasonArt(infos.m_iDbId, seasonArt);
518 int playcount = infos.m_playCount;
519 CDateTime lastPlayed = infos.m_lastPlayed;
521 UpdateVideoTag(parameterObject, infos, artwork);
523 // we need to manually remove tags/taglinks for now because they aren't replaced
524 // due to scrapers not supporting them
525 videodatabase.RemoveTagsFromItem(id, "tvshow");
527 if (videodatabase.SetDetailsForTvShow(infos.m_strFileNameAndPath, infos, artwork, seasonArt, id) <= 0)
528 return InternalError;
530 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
532 // restore original playcount or the new one won't be announced
533 int newPlaycount = infos.m_playCount;
534 infos.m_playCount = playcount;
535 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
538 CJSONRPCUtils::NotifyItemUpdated();
542 JSONRPC_STATUS CVideoLibrary::SetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
544 int id = (int)parameterObject["episodeid"].asInteger();
546 CVideoDatabase videodatabase;
547 if (!videodatabase.Open())
548 return InternalError;
551 videodatabase.GetEpisodeInfo("", infos, id);
552 if (infos.m_iDbId <= 0)
554 videodatabase.Close();
555 return InvalidParams;
558 int tvshowid = videodatabase.GetTvShowForEpisode(id);
561 videodatabase.Close();
562 return InvalidParams;
566 std::map<std::string, std::string> artwork;
567 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
569 int playcount = infos.m_playCount;
570 CDateTime lastPlayed = infos.m_lastPlayed;
572 UpdateVideoTag(parameterObject, infos, artwork);
574 if (videodatabase.SetDetailsForEpisode(infos.m_strFileNameAndPath, infos, artwork, tvshowid, id) <= 0)
575 return InternalError;
577 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
579 // restore original playcount or the new one won't be announced
580 int newPlaycount = infos.m_playCount;
581 infos.m_playCount = playcount;
582 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
585 UpdateResumePoint(parameterObject, infos, videodatabase);
587 CJSONRPCUtils::NotifyItemUpdated();
591 JSONRPC_STATUS CVideoLibrary::SetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
593 int id = (int)parameterObject["musicvideoid"].asInteger();
595 CVideoDatabase videodatabase;
596 if (!videodatabase.Open())
597 return InternalError;
600 videodatabase.GetMusicVideoInfo("", infos, id);
601 if (infos.m_iDbId <= 0)
603 videodatabase.Close();
604 return InvalidParams;
608 std::map<std::string, std::string> artwork;
609 videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
611 int playcount = infos.m_playCount;
612 CDateTime lastPlayed = infos.m_lastPlayed;
614 UpdateVideoTag(parameterObject, infos, artwork);
616 // we need to manually remove tags/taglinks for now because they aren't replaced
617 // due to scrapers not supporting them
618 videodatabase.RemoveTagsFromItem(id, "musicvideo");
620 if (videodatabase.SetDetailsForMusicVideo(infos.m_strFileNameAndPath, infos, artwork, id) <= 0)
621 return InternalError;
623 if (playcount != infos.m_playCount || lastPlayed != infos.m_lastPlayed)
625 // restore original playcount or the new one won't be announced
626 int newPlaycount = infos.m_playCount;
627 infos.m_playCount = playcount;
628 videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed.IsValid() ? infos.m_lastPlayed : CDateTime::GetCurrentDateTime());
631 UpdateResumePoint(parameterObject, infos, videodatabase);
633 CJSONRPCUtils::NotifyItemUpdated();
637 JSONRPC_STATUS CVideoLibrary::RemoveMovie(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
639 return RemoveVideo(parameterObject);
642 JSONRPC_STATUS CVideoLibrary::RemoveTVShow(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
644 return RemoveVideo(parameterObject);
647 JSONRPC_STATUS CVideoLibrary::RemoveEpisode(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
649 return RemoveVideo(parameterObject);
652 JSONRPC_STATUS CVideoLibrary::RemoveMusicVideo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
654 return RemoveVideo(parameterObject);
657 JSONRPC_STATUS CVideoLibrary::Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
659 std::string directory = parameterObject["directory"].asString();
661 if (directory.empty())
662 cmd = "updatelibrary(video)";
664 cmd.Format("updatelibrary(video, %s)", StringUtils::Paramify(directory).c_str());
666 CApplicationMessenger::Get().ExecBuiltIn(cmd);
670 JSONRPC_STATUS CVideoLibrary::Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
673 if (parameterObject["options"].isMember("path"))
674 cmd.Format("exportlibrary(video, false, %s)", StringUtils::Paramify(parameterObject["options"]["path"].asString()));
676 cmd.Format("exportlibrary(video, true, %s, %s, %s)",
677 parameterObject["options"]["images"].asBoolean() ? "true" : "false",
678 parameterObject["options"]["overwrite"].asBoolean() ? "true" : "false",
679 parameterObject["options"]["actorthumbs"].asBoolean() ? "true" : "false");
681 CApplicationMessenger::Get().ExecBuiltIn(cmd);
685 JSONRPC_STATUS CVideoLibrary::Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
687 CApplicationMessenger::Get().ExecBuiltIn("cleanlibrary(video)");
691 bool CVideoLibrary::FillFileItem(const CStdString &strFilename, CFileItemPtr &item, const CVariant ¶meterObject /* = CVariant(CVariant::VariantTypeArray) */)
693 CVideoDatabase videodatabase;
694 if (strFilename.empty())
698 if (videodatabase.Open())
700 CVideoInfoTag details;
701 if (videodatabase.LoadVideoInfo(strFilename, details))
703 item->SetFromVideoInfoTag(details);
708 if (item->GetLabel().empty())
710 item->SetLabel(CUtil::GetTitleFromPath(strFilename, false));
711 if (item->GetLabel().empty())
712 item->SetLabel(URIUtils::GetFileName(strFilename));
718 bool CVideoLibrary::FillFileItemList(const CVariant ¶meterObject, CFileItemList &list)
720 CVideoDatabase videodatabase;
721 if (!videodatabase.Open())
724 CStdString file = parameterObject["file"].asString();
725 int movieID = (int)parameterObject["movieid"].asInteger(-1);
726 int episodeID = (int)parameterObject["episodeid"].asInteger(-1);
727 int musicVideoID = (int)parameterObject["musicvideoid"].asInteger(-1);
729 bool success = false;
730 CFileItemPtr fileItem(new CFileItem());
731 if (FillFileItem(file, fileItem))
739 CVideoInfoTag details;
740 videodatabase.GetMovieInfo("", details, movieID);
741 if (!details.IsEmpty())
743 list.Add(CFileItemPtr(new CFileItem(details)));
749 CVideoInfoTag details;
750 if (videodatabase.GetEpisodeInfo("", details, episodeID) && !details.IsEmpty())
752 list.Add(CFileItemPtr(new CFileItem(details)));
756 if (musicVideoID > 0)
758 CVideoInfoTag details;
759 videodatabase.GetMusicVideoInfo("", details, musicVideoID);
760 if (!details.IsEmpty())
762 list.Add(CFileItemPtr(new CFileItem(details)));
770 JSONRPC_STATUS CVideoLibrary::GetAdditionalMovieDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */)
772 if (!videodatabase.Open())
773 return InternalError;
775 bool additionalInfo = false;
776 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
778 CStdString fieldValue = itr->asString();
779 if (fieldValue == "cast" || fieldValue == "showlink" || fieldValue == "tag" || fieldValue == "streamdetails")
780 additionalInfo = true;
785 for (int index = 0; index < items.Size(); index++)
788 videodatabase.GetMovieInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
792 int size = items.Size();
793 if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
794 size = (int)items.GetProperty("total").asInteger();
795 HandleFileItemList("movieid", true, "movies", items, parameterObject, result, size, limit);
800 JSONRPC_STATUS CVideoLibrary::GetAdditionalEpisodeDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */)
802 if (!videodatabase.Open())
803 return InternalError;
805 bool additionalInfo = false;
806 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
808 CStdString fieldValue = itr->asString();
809 if (fieldValue == "cast" || fieldValue == "streamdetails")
810 additionalInfo = true;
815 for (int index = 0; index < items.Size(); index++)
818 videodatabase.GetEpisodeInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
822 int size = items.Size();
823 if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
824 size = (int)items.GetProperty("total").asInteger();
825 HandleFileItemList("episodeid", true, "episodes", items, parameterObject, result, size, limit);
830 JSONRPC_STATUS CVideoLibrary::GetAdditionalMusicVideoDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */)
832 if (!videodatabase.Open())
833 return InternalError;
835 bool streamdetails = false;
836 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
838 if (itr->asString() == "tag" || itr->asString() == "streamdetails")
839 streamdetails = true;
844 for (int index = 0; index < items.Size(); index++)
845 videodatabase.GetMusicVideoInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId);
848 int size = items.Size();
849 if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
850 size = (int)items.GetProperty("total").asInteger();
851 HandleFileItemList("musicvideoid", true, "musicvideos", items, parameterObject, result, size, limit);
856 JSONRPC_STATUS CVideoLibrary::RemoveVideo(const CVariant ¶meterObject)
858 CVideoDatabase videodatabase;
859 if (!videodatabase.Open())
860 return InternalError;
862 if (parameterObject.isMember("movieid"))
863 videodatabase.DeleteMovie((int)parameterObject["movieid"].asInteger());
864 else if (parameterObject.isMember("tvshowid"))
865 videodatabase.DeleteTvShow((int)parameterObject["tvshowid"].asInteger());
866 else if (parameterObject.isMember("episodeid"))
867 videodatabase.DeleteEpisode((int)parameterObject["episodeid"].asInteger());
868 else if (parameterObject.isMember("musicvideoid"))
869 videodatabase.DeleteMusicVideo((int)parameterObject["musicvideoid"].asInteger());
871 CJSONRPCUtils::NotifyItemUpdated();
875 void CVideoLibrary::UpdateResumePoint(const CVariant ¶meterObject, CVideoInfoTag &details, CVideoDatabase &videodatabase)
877 if (!parameterObject["resume"].isNull())
879 int position = (int)parameterObject["resume"]["position"].asInteger();
881 videodatabase.ClearBookMarksOfFile(details.m_strFileNameAndPath, CBookmark::RESUME);
885 if (videodatabase.GetResumeBookMark(details.m_strFileNameAndPath, bookmark))
887 bookmark.timeInSeconds = position;
889 int total = (int)parameterObject["resume"]["total"].asInteger();
891 bookmark.totalTimeInSeconds = total;
892 videodatabase.AddBookMarkToFile(details.m_strFileNameAndPath, bookmark, CBookmark::RESUME);
898 void CVideoLibrary::UpdateVideoTag(const CVariant ¶meterObject, CVideoInfoTag& details, std::map<std::string, std::string> &artwork)
900 if (ParameterNotNull(parameterObject, "title"))
901 details.m_strTitle = parameterObject["title"].asString();
902 if (ParameterNotNull(parameterObject, "playcount"))
903 details.m_playCount = (int)parameterObject["playcount"].asInteger();
904 if (ParameterNotNull(parameterObject, "runtime"))
905 details.m_duration = (int)parameterObject["runtime"].asInteger();
906 if (ParameterNotNull(parameterObject, "director"))
907 CopyStringArray(parameterObject["director"], details.m_director);
908 if (ParameterNotNull(parameterObject, "studio"))
909 CopyStringArray(parameterObject["studio"], details.m_studio);
910 if (ParameterNotNull(parameterObject, "year"))
911 details.m_iYear = (int)parameterObject["year"].asInteger();
912 if (ParameterNotNull(parameterObject, "plot"))
913 details.m_strPlot = parameterObject["plot"].asString();
914 if (ParameterNotNull(parameterObject, "album"))
915 details.m_strAlbum = parameterObject["album"].asString();
916 if (ParameterNotNull(parameterObject, "artist"))
917 CopyStringArray(parameterObject["artist"], details.m_artist);
918 if (ParameterNotNull(parameterObject, "genre"))
919 CopyStringArray(parameterObject["genre"], details.m_genre);
920 if (ParameterNotNull(parameterObject, "track"))
921 details.m_iTrack = (int)parameterObject["track"].asInteger();
922 if (ParameterNotNull(parameterObject, "rating"))
923 details.m_fRating = parameterObject["rating"].asFloat();
924 if (ParameterNotNull(parameterObject, "mpaa"))
925 details.m_strMPAARating = parameterObject["mpaa"].asString();
926 if (ParameterNotNull(parameterObject, "imdbnumber"))
927 details.m_strIMDBNumber = parameterObject["imdbnumber"].asString();
928 if (ParameterNotNull(parameterObject, "premiered"))
929 details.m_premiered.SetFromDBDate(parameterObject["premiered"].asString());
930 if (ParameterNotNull(parameterObject, "votes"))
931 details.m_strVotes = parameterObject["votes"].asString();
932 if (ParameterNotNull(parameterObject, "lastplayed"))
933 details.m_lastPlayed.SetFromDBDateTime(parameterObject["lastplayed"].asString());
934 if (ParameterNotNull(parameterObject, "firstaired"))
935 details.m_firstAired.SetFromDBDateTime(parameterObject["firstaired"].asString());
936 if (ParameterNotNull(parameterObject, "productioncode"))
937 details.m_strProductionCode = parameterObject["productioncode"].asString();
938 if (ParameterNotNull(parameterObject, "season"))
939 details.m_iSeason = (int)parameterObject["season"].asInteger();
940 if (ParameterNotNull(parameterObject, "episode"))
941 details.m_iEpisode = (int)parameterObject["episode"].asInteger();
942 if (ParameterNotNull(parameterObject, "originaltitle"))
943 details.m_strOriginalTitle = parameterObject["originaltitle"].asString();
944 if (ParameterNotNull(parameterObject, "trailer"))
945 details.m_strTrailer = parameterObject["trailer"].asString();
946 if (ParameterNotNull(parameterObject, "tagline"))
947 details.m_strTagLine = parameterObject["tagline"].asString();
948 if (ParameterNotNull(parameterObject, "plotoutline"))
949 details.m_strPlotOutline = parameterObject["plotoutline"].asString();
950 if (ParameterNotNull(parameterObject, "writer"))
951 CopyStringArray(parameterObject["writer"], details.m_writingCredits);
952 if (ParameterNotNull(parameterObject, "country"))
953 CopyStringArray(parameterObject["country"], details.m_country);
954 if (ParameterNotNull(parameterObject, "top250"))
955 details.m_iTop250 = (int)parameterObject["top250"].asInteger();
956 if (ParameterNotNull(parameterObject, "sorttitle"))
957 details.m_strSortTitle = parameterObject["sorttitle"].asString();
958 if (ParameterNotNull(parameterObject, "episodeguide"))
959 details.m_strEpisodeGuide = parameterObject["episodeguide"].asString();
960 if (ParameterNotNull(parameterObject, "set"))
961 details.m_strSet = parameterObject["set"].asString();
962 if (ParameterNotNull(parameterObject, "showlink"))
963 CopyStringArray(parameterObject["showlink"], details.m_showLink);
964 if (ParameterNotNull(parameterObject, "thumbnail"))
965 artwork["thumb"] = parameterObject["thumbnail"].asString();
966 if (ParameterNotNull(parameterObject, "fanart"))
967 artwork["fanart"] = parameterObject["fanart"].asString();
968 if (ParameterNotNull(parameterObject, "tag"))
969 CopyStringArray(parameterObject["tag"], details.m_tags);
970 if (ParameterNotNull(parameterObject, "art"))
972 CVariant art = parameterObject["art"];
973 for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++)
975 if (!artIt->second.asString().empty())
976 artwork[artIt->first] = CTextureCache::UnwrapImageURL(artIt->second.asString());