string ArrayToString(SortAttribute attributes, const CVariant &variant, const string &seperator = " / ") { vector<string> strArray; if (variant.isArray()) { for (CVariant::const_iterator_array it = variant.begin_array(); it != variant.end_array(); it++) { if (attributes & SortAttributeIgnoreArticle) strArray.push_back(SortUtils::RemoveArticles(it->asString())); else strArray.push_back(it->asString()); } return StringUtils::Join(strArray, seperator); } else if (variant.isString()) { if (attributes & SortAttributeIgnoreArticle) return SortUtils::RemoveArticles(variant.asString()); else return variant.asString(); } return ""; }
JSON_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVideoDatabase videodatabase; if (!videodatabase.Open()) return InternalError; CFileItemList items; if (videodatabase.GetTvShowsNav("videodb://", items)) { bool additionalInfo = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "cast") additionalInfo = true; } if (additionalInfo) { for (int index = 0; index < items.Size(); index++) videodatabase.GetTvShowInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId); } HandleFileItemList("tvshowid", true, "tvshows", items, parameterObject, result); } videodatabase.Close(); return OK; }
bool CDatabaseQueryRule::Load(const CVariant &obj) { if (!obj.isObject() || !obj.isMember("field") || !obj["field"].isString() || !obj.isMember("operator") || !obj["operator"].isString()) return false; m_field = TranslateField(obj["field"].asString().c_str()); m_operator = TranslateOperator(obj["operator"].asString().c_str()); if (m_operator == OPERATOR_TRUE || m_operator == OPERATOR_FALSE) return true; if (!obj.isMember("value") || (!obj["value"].isString() && !obj["value"].isArray())) return false; const CVariant &value = obj["value"]; if (value.isString()) m_parameter.push_back(value.asString()); else if (value.isArray()) { for (CVariant::const_iterator_array val = value.begin_array(); val != value.end_array(); val++) { if (val->isString() && !val->asString().empty()) m_parameter.push_back(val->asString()); } if (m_parameter.empty()) m_parameter.push_back(""); } else return false; return true; }
int CVideoLibrary::RequiresAdditionalDetails(const MediaType& mediaType, const CVariant ¶meterObject) { if (mediaType != MediaTypeMovie && mediaType != MediaTypeTvShow && mediaType != MediaTypeEpisode && mediaType != MediaTypeMusicVideo) return VideoDbDetailsNone; const CVariant& properties = parameterObject["properties"]; int details = VideoDbDetailsNone; for (CVariant::const_iterator_array itr = properties.begin_array(); itr != properties.end_array(); itr++) { std::string propertyValue = itr->asString(); if (propertyValue == "cast") details = details | VideoDbDetailsCast; else if (propertyValue == "ratings") details = details | VideoDbDetailsRating; else if (propertyValue == "uniqueid") details = details | VideoDbDetailsUniqueID; else if (propertyValue == "showlink") details = details | VideoDbDetailsShowLink; else if (propertyValue == "streamdetails") details = details | VideoDbDetailsStream; else if (propertyValue == "tag") details = details | VideoDbDetailsTag; } return details; }
JSONRPC_STATUS CVideoLibrary::GetAdditionalEpisodeDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */) { if (!videodatabase.Open()) return InternalError; bool additionalInfo = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { std::string fieldValue = itr->asString(); if (fieldValue == "cast" || fieldValue == "streamdetails") additionalInfo = true; } if (additionalInfo) { for (int index = 0; index < items.Size(); index++) { if (additionalInfo) videodatabase.GetEpisodeInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId); } } int size = items.Size(); if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size) size = (int)items.GetProperty("total").asInteger(); HandleFileItemList("episodeid", true, "episodes", items, parameterObject, result, size, limit); return OK; }
JSONRPC_STATUS CVideoLibrary::GetAdditionalMusicVideoDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase, bool limit /* = true */) { if (!videodatabase.Open()) return InternalError; bool streamdetails = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { if (itr->asString() == "streamdetails") streamdetails = true; } if (streamdetails) { for (int index = 0; index < items.Size(); index++) videodatabase.GetStreamDetails(*(items[index]->GetVideoInfoTag())); } int size = items.Size(); if (!limit && items.HasProperty("total") && items.GetProperty("total").asInteger() > size) size = (int)items.GetProperty("total").asInteger(); HandleFileItemList("musicvideoid", true, "musicvideos", items, parameterObject, result, size, limit); return OK; }
JSONRPC_STATUS CVideoLibrary::GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["movieid"].asInteger(); CVideoDatabase videodatabase; if (!videodatabase.Open()) return InternalError; CVideoInfoTag infos; if (!videodatabase.GetMovieInfo("", infos, id) || infos.m_iDbId <= 0) return InvalidParams; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "streamdetails") { videodatabase.GetStreamDetails(infos); break; } } HandleFileItem("movieid", true, "moviedetails", CFileItemPtr(new CFileItem(infos)), parameterObject, parameterObject["properties"], result, false); return OK; }
JSONRPC_STATUS CVideoLibrary::GetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVideoDatabase videodatabase; if (!videodatabase.Open()) return InternalError; int id = (int)parameterObject["episodeid"].asInteger(); CVideoInfoTag infos; if (!videodatabase.GetEpisodeInfo("", infos, id) || infos.m_iDbId <= 0) return InvalidParams; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "streamdetails") { videodatabase.GetStreamDetails(infos); break; } } CFileItemPtr pItem = CFileItemPtr(new CFileItem(infos)); // We need to set the correct base path to get the valid fanart int tvshowid = infos.m_iIdShow; if (tvshowid <= 0) tvshowid = videodatabase.GetTvShowForEpisode(id); CStdString basePath; basePath.Format("videodb://2/2/%ld/%ld/%ld", tvshowid, infos.m_iSeason, id); pItem->SetPath(basePath); HandleFileItem("episodeid", true, "episodedetails", pItem, parameterObject, parameterObject["properties"], result, false); return OK; }
void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char *resultname, CFileItemPtr item, const CVariant ¶meterObject, const CVariant &validFields, CVariant &result, bool append /* = true */, CThumbLoader *thumbLoader /* = NULL */) { std::set<std::string> fields; if (parameterObject.isMember("properties") && parameterObject["properties"].isArray()) { for (CVariant::const_iterator_array field = parameterObject["properties"].begin_array(); field != parameterObject["properties"].end_array(); field++) fields.insert(field->asString()); } HandleFileItem(ID, allowFile, resultname, item, parameterObject, fields, result, append, thumbLoader); }
JSONRPC_STATUS CAddonsOperations::ExecuteAddon(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { std::string id = parameterObject["addonid"].asString(); AddonPtr addon; if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon) || addon.get() == NULL || addon->Type() < ADDON_VIZ || addon->Type() >= ADDON_MAX) return InvalidParams; std::string argv; CVariant params = parameterObject["params"]; if (params.isObject()) { for (CVariant::const_iterator_map it = params.begin_map(); it != params.end_map(); it++) { if (it != params.begin_map()) argv += ","; argv += it->first + "=" + it->second.asString(); } } else if (params.isArray()) { for (CVariant::const_iterator_array it = params.begin_array(); it != params.end_array(); it++) { if (it != params.begin_array()) argv += ","; argv += StringUtils::Paramify(it->asString()); } } else if (params.isString()) { if (!params.empty()) argv = StringUtils::Paramify(params.asString()); } std::string cmd; if (params.empty()) cmd = StringUtils::Format("RunAddon(%s)", id.c_str()); else cmd = StringUtils::Format("RunAddon(%s, %s)", id.c_str(), argv.c_str()); if (params["wait"].asBoolean()) CApplicationMessenger::GetInstance().SendMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, cmd); else CApplicationMessenger::GetInstance().PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, cmd); return ACK; }
bool CDatabaseQueryRuleCombination::Load(const CVariant &obj, const IDatabaseQueryRuleFactory *factory) { if (!obj.isObject() && !obj.isArray()) return false; CVariant child; if (obj.isObject()) { if (obj.isMember("and") && obj["and"].isArray()) { m_type = CombinationAnd; child = obj["and"]; } else if (obj.isMember("or") && obj["or"].isArray()) { m_type = CombinationOr; child = obj["or"]; } else return false; } else child = obj; for (CVariant::const_iterator_array it = child.begin_array(); it != child.end_array(); it++) { if (!it->isObject()) continue; if (it->isMember("and") || it->isMember("or")) { boost::shared_ptr<CDatabaseQueryRuleCombination> combo(factory->CreateCombination()); if (combo && combo->Load(*it, factory)) m_combinations.push_back(combo); } else { boost::shared_ptr<CDatabaseQueryRule> rule(factory->CreateRule()); if (rule && rule->Load(*it)) m_rules.push_back(rule); } } return true; }
JSONRPC_STATUS CFileOperations::GetFileDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CStdString file = parameterObject["file"].asString(); if (!CFile::Exists(file)) return InvalidParams; if (!CFileUtils::RemoteAccessAllowed(file)) return InvalidParams; CStdString path; URIUtils::GetDirectory(file, path); CFileItemList items; if (path.empty() || !CDirectory::GetDirectory(path, items) || !items.Contains(file)) return InvalidParams; CFileItemPtr item = items.Get(file); if (!URIUtils::IsUPnP(file)) FillFileItem(item, item, parameterObject["media"].asString(), parameterObject); // Check if the "properties" list exists // and make sure it contains the "file" // field CVariant param = parameterObject; if (!param.isMember("properties")) param["properties"] = CVariant(CVariant::VariantTypeArray); bool hasFileField = false; for (CVariant::const_iterator_array itr = param["properties"].begin_array(); itr != param["properties"].end_array(); itr++) { if (itr->asString().compare("file") == 0) { hasFileField = true; break; } } if (!hasFileField) param["properties"].append("file"); param["properties"].append("filetype"); HandleFileItem("id", true, "filedetails", item, parameterObject, param["properties"], result, false); return OK; }
JSONRPC_STATUS CProfilesOperations::GetCurrentProfile(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { const CProfile& currentProfile = CProfilesManager::Get().GetCurrentProfile(); CVariant profileVariant = CVariant(CVariant::VariantTypeObject); profileVariant["label"] = currentProfile.getName(); for (CVariant::const_iterator_array propertyiter = parameterObject["properties"].begin_array(); propertyiter != parameterObject["properties"].end_array(); ++propertyiter) { if (propertyiter->isString()) { if (propertyiter->asString() == "lockmode") profileVariant["lockmode"] = currentProfile.getLockMode(); else if (propertyiter->asString() == "thumbnail") profileVariant["thumbnail"] = currentProfile.getThumb(); } } result = profileVariant; return OK; }
void CFileItemHandler::HandleFileItemList(const char *ID, bool allowFile, const char *resultname, CFileItemList &items, const CVariant ¶meterObject, CVariant &result, int size, bool sortLimit /* = true */) { int start, end; HandleLimits(parameterObject, result, size, start, end); if (sortLimit) Sort(items, parameterObject); else { start = 0; end = items.Size(); } CThumbLoader *thumbLoader = NULL; if (end - start > 0) { if (items.Get(start)->HasVideoInfoTag()) thumbLoader = new CVideoThumbLoader(); else if (items.Get(start)->HasMusicInfoTag()) thumbLoader = new CMusicThumbLoader(); if (thumbLoader != NULL) thumbLoader->Initialize(); } std::set<std::string> fields; if (parameterObject.isMember("properties") && parameterObject["properties"].isArray()) { for (CVariant::const_iterator_array field = parameterObject["properties"].begin_array(); field != parameterObject["properties"].end_array(); field++) fields.insert(field->asString()); } for (int i = start; i < end; i++) { CVariant object; CFileItemPtr item = items.Get(i); HandleFileItem(ID, allowFile, resultname, item, parameterObject, fields, result, true, thumbLoader); } delete thumbLoader; }
bool CAudioLibrary::CheckForAdditionalProperties(const CVariant &properties, const std::set<std::string> &checkProperties, std::set<std::string> &foundProperties) { if (!properties.isArray() || properties.empty()) return false; std::set<std::string> checkingProperties = checkProperties; for (CVariant::const_iterator_array itr = properties.begin_array(); itr != properties.end_array() && !checkingProperties.empty(); itr++) { if (!itr->isString()) continue; std::string property = itr->asString(); if (checkingProperties.find(property) != checkingProperties.end()) { checkingProperties.erase(property); foundProperties.insert(property); } } return !foundProperties.empty(); }
JSONRPC_STATUS CVideoLibrary::GetAdditionalMusicVideoDetails(const CVariant ¶meterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase) { if (!videodatabase.Open()) return InternalError; bool additionalInfo = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "resume") additionalInfo = true; } if (additionalInfo) { for (int index = 0; index < items.Size(); index++) videodatabase.GetMusicVideoInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId); } HandleFileItemList("musicvideoid", true, "musicvideos", items, parameterObject, result); return OK; }
JSONRPC_STATUS CProfilesOperations::GetProfiles(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager(); CFileItemList listItems; for (unsigned int i = 0; i < profileManager->GetNumberOfProfiles(); ++i) { const CProfile *profile = profileManager->GetProfile(i); CFileItemPtr item(new CFileItem(profile->getName())); item->SetArt("thumb", profile->getThumb()); listItems.Add(item); } HandleFileItemList("profileid", false, "profiles", listItems, parameterObject, result); for (CVariant::const_iterator_array propertyiter = parameterObject["properties"].begin_array(); propertyiter != parameterObject["properties"].end_array(); ++propertyiter) { if (propertyiter->isString() && propertyiter->asString() == "lockmode") { for (CVariant::iterator_array profileiter = result["profiles"].begin_array(); profileiter != result["profiles"].end_array(); ++profileiter) { std::string profilename = (*profileiter)["label"].asString(); int index = profileManager->GetProfileIndex(profilename); const CProfile *profile = profileManager->GetProfile(index); LockType locktype = LOCK_MODE_UNKNOWN; if (index == 0) locktype = profileManager->GetMasterProfile().getLockMode(); else locktype = profile->getLockMode(); (*profileiter)["lockmode"] = locktype; } break; } } return OK; }
JSONRPC_STATUS CAudioLibrary::GetProperties(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVariant properties = CVariant(CVariant::VariantTypeObject); for (CVariant::const_iterator_array it = parameterObject["properties"].begin_array(); it != parameterObject["properties"].end_array(); it++) { std::string propertyName = it->asString(); CVariant property; if (propertyName == "missingartistid") property = (int)BLANKARTIST_ID; else if (propertyName == "librarylastupdated") { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; property = musicdatabase.GetLibraryLastUpdated(); } properties[propertyName] = property; } result = properties; return OK; }
JSONRPC_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { PlayerType player = GetPlayer(parameterObject["playerid"]); CFileItemPtr fileItem; switch (player) { case Video: case Audio: { fileItem = CFileItemPtr(new CFileItem(g_application.CurrentFileItem())); if (fileItem->GetLabel().empty()) { if (IsPVRChannel()) { CPVRChannelPtr currentChannel; if (g_PVRManager.GetCurrentChannel(currentChannel) && currentChannel.get() != NULL) fileItem = CFileItemPtr(new CFileItem(*currentChannel.get())); } else if (player == Video) { if (!CVideoLibrary::FillFileItem(g_application.CurrentFile(), fileItem, parameterObject)) { const CVideoInfoTag *currentVideoTag = g_infoManager.GetCurrentMovieTag(); if (currentVideoTag != NULL) fileItem = CFileItemPtr(new CFileItem(*currentVideoTag)); fileItem->SetPath(g_application.CurrentFileItem().GetPath()); } } else { if (!CAudioLibrary::FillFileItem(g_application.CurrentFile(), fileItem, parameterObject)) { const MUSIC_INFO::CMusicInfoTag *currentMusicTag = g_infoManager.GetCurrentSongTag(); if (currentMusicTag != NULL) fileItem = CFileItemPtr(new CFileItem(*currentMusicTag)); fileItem->SetPath(g_application.CurrentFileItem().GetPath()); } } } if (IsPVRChannel()) break; if (player == Video) { bool additionalInfo = false; bool streamdetails = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "cast" || fieldValue == "set" || fieldValue == "setid" || fieldValue == "showlink" || fieldValue == "resume" || (fieldValue == "streamdetails" && !fileItem->GetVideoInfoTag()->m_streamDetails.HasItems())) additionalInfo = true; } CVideoDatabase videodatabase; if ((additionalInfo) && videodatabase.Open()) { if (additionalInfo) { switch (fileItem->GetVideoContentType()) { case VIDEODB_CONTENT_MOVIES: videodatabase.GetMovieInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_MUSICVIDEOS: videodatabase.GetMusicVideoInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_EPISODES: videodatabase.GetEpisodeInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_TVSHOWS: case VIDEODB_CONTENT_MOVIE_SETS: default: break; } } videodatabase.Close(); } } else if (player == Audio) { if (fileItem->IsMusicDb()) { CMusicDatabase musicdb; CFileItemList items; items.Add(fileItem); CAudioLibrary::GetAdditionalSongDetails(parameterObject, items, musicdb); } } break; } case Picture: { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; CFileItemList slides; slideshow->GetSlideShowContents(slides); fileItem = slides[slideshow->CurrentSlide() - 1]; break; } case None: default: return FailedToExecute; } HandleFileItem("id", !IsPVRChannel(), "item", fileItem, parameterObject, parameterObject["properties"], result, false); return OK; }
JSONRPC_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CStdString media = parameterObject["media"].asString(); media = media.ToLower(); CFileItemList items; CStdString strPath = parameterObject["directory"].asString(); // Check if this directory is part of a source and whether it's locked VECSOURCES *sources; bool isSource; for (unsigned int index = 0; index < SourcesSize; index++) { sources = g_settings.GetSourcesFromType(SourceNames[index]); int sourceIndex = CUtil::GetMatchingSource(strPath, *sources, isSource); if (sourceIndex >= 0 && sourceIndex < (int)sources->size() && sources->at(sourceIndex).m_iHasLock == 2) return InvalidParams; } CStdStringArray regexps; CStdString extensions = ""; if (media.Equals("video")) { regexps = g_advancedSettings.m_videoExcludeFromListingRegExps; extensions = g_settings.m_videoExtensions; } else if (media.Equals("music")) { regexps = g_advancedSettings.m_audioExcludeFromListingRegExps; extensions = g_settings.m_musicExtensions; } else if (media.Equals("pictures")) { regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps; extensions = g_settings.m_pictureExtensions; } if (CDirectory::GetDirectory(strPath, items, extensions)) { CFileItemList filteredDirectories, filteredFiles; for (unsigned int i = 0; i < (unsigned int)items.Size(); i++) { if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps)) continue; if (items[i]->IsSmb()) { CURL url(items[i]->GetPath()); items[i]->SetPath(url.GetWithoutUserDetails()); } if ((media == "video" && items[i]->HasVideoInfoTag()) || (media == "music" && items[i]->HasMusicInfoTag()) || (media == "picture" && items[i]->HasPictureInfoTag()) || media == "files") { if (items[i]->m_bIsFolder) filteredDirectories.Add(items[i]); else filteredFiles.Add(items[i]); } else { CFileItem fileItem; if (FillFileItem(items[i], fileItem, media)) { if (items[i]->m_bIsFolder) filteredDirectories.Add(CFileItemPtr(new CFileItem(fileItem))); else filteredFiles.Add(CFileItemPtr(new CFileItem(fileItem))); } else { if (items[i]->m_bIsFolder) filteredDirectories.Add(items[i]); else filteredFiles.Add(items[i]); } } } // Check if the "properties" list exists // and make sure it contains the "file" // field CVariant param = parameterObject; if (!param.isMember("properties")) param["properties"] = CVariant(CVariant::VariantTypeArray); bool hasFileField = false; for (CVariant::const_iterator_array itr = param["properties"].begin_array(); itr != param["properties"].end_array(); itr++) { if (itr->asString().compare("file") == 0) { hasFileField = true; break; } } if (!hasFileField) param["properties"].append("file"); HandleFileItemList("id", true, "files", filteredDirectories, param, result); for (unsigned int index = 0; index < result["files"].size(); index++) { result["files"][index]["filetype"] = "directory"; } int count = (int)result["limits"]["total"].asInteger(); HandleFileItemList("id", true, "files", filteredFiles, param, result); for (unsigned int index = count; index < result["files"].size(); index++) { result["files"][index]["filetype"] = "file"; } count += (int)result["limits"]["total"].asInteger(); result["limits"]["end"] = count; result["limits"]["total"] = count; return OK; } return InvalidParams; }
JSONRPC_STATUS CFavouritesOperations::GetFavourites(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CFileItemList favourites; CServiceBroker::GetFavouritesService().GetAll(favourites); std::string type = !parameterObject["type"].isNull() ? parameterObject["type"].asString() : ""; std::set<std::string> fields; if (parameterObject.isMember("properties") && parameterObject["properties"].isArray()) { for (CVariant::const_iterator_array field = parameterObject["properties"].begin_array(); field != parameterObject["properties"].end_array(); field++) fields.insert(field->asString()); } for (int i = 0; i < favourites.Size(); i++) { CVariant object; CFileItemPtr item = favourites.Get(i); std::string function; std::vector<std::string> parameters; CUtil::SplitExecFunction(item->GetPath(), function, parameters); if (parameters.empty()) continue; object["title"] = item->GetLabel(); if (fields.find("thumbnail") != fields.end()) object["thumbnail"] = item->GetArt("thumb"); if (StringUtils::EqualsNoCase(function, "ActivateWindow")) { object["type"] = "window"; if (fields.find("window") != fields.end()) { if (StringUtils::IsNaturalNumber(parameters[0])) object["window"] = CWindowTranslator::TranslateWindow(strtol(parameters[0].c_str(), NULL, 10)); else object["window"] = parameters[0]; } if (fields.find("windowparameter") != fields.end()) { if (parameters.size() > 1) object["windowparameter"] = parameters[1]; else object["windowparameter"] = ""; } } else if (StringUtils::EqualsNoCase(function, "PlayMedia")) { object["type"] = "media"; if (fields.find("path") != fields.end()) object["path"] = parameters[0]; } else if (StringUtils::EqualsNoCase(function, "RunScript")) { object["type"] = "script"; if (fields.find("path") != fields.end()) object["path"] = parameters[0]; } else object["type"] = "unknown"; if (type.empty() || type.compare(object["type"].asString()) == 0) result["favourites"].append(object); } int start, end; HandleLimits(parameterObject, result, result["favourites"].size(), start, end); return OK; }
JSONRPC_STATUS CVideoLibrary::GetTVShows(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVideoDatabase videodatabase; if (!videodatabase.Open()) return InternalError; SortDescription sorting; ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd); if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes)) return InvalidParams; CVideoDbUrl videoUrl; videoUrl.FromString("videodb://tvshows/titles/"); int genreID = -1, year = -1; const CVariant &filter = parameterObject["filter"]; if (filter.isMember("genreid")) genreID = (int)filter["genreid"].asInteger(); else if (filter.isMember("genre")) videoUrl.AddOption("genre", filter["genre"].asString()); else if (filter.isMember("year")) year = (int)filter["year"].asInteger(); else if (filter.isMember("actor")) videoUrl.AddOption("actor", filter["actor"].asString()); else if (filter.isMember("studio")) videoUrl.AddOption("studio", filter["studio"].asString()); else if (filter.isMember("tag")) videoUrl.AddOption("tag", filter["tag"].asString()); else if (filter.isObject()) { std::string xsp; if (!GetXspFiltering("tvshows", filter, xsp)) return InvalidParams; videoUrl.AddOption("xsp", xsp); } CFileItemList items; if (!videodatabase.GetTvShowsNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, sorting)) return InvalidParams; bool additionalInfo = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { std::string fieldValue = itr->asString(); if (fieldValue == "cast" || fieldValue == "tag") additionalInfo = true; } if (additionalInfo) { for (int index = 0; index < items.Size(); index++) videodatabase.GetTvShowInfo("", *(items[index]->GetVideoInfoTag()), items[index]->GetVideoInfoTag()->m_iDbId); } int size = items.Size(); if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size) size = (int)items.GetProperty("total").asInteger(); HandleFileItemList("tvshowid", true, "tvshows", items, parameterObject, result, size, false); return OK; }
JSONRPC_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CStdString media = parameterObject["media"].asString(); StringUtils::ToLower(media); CFileItemList items; CStdString strPath = parameterObject["directory"].asString(); if (!CFileUtils::RemoteAccessAllowed(strPath)) return InvalidParams; CStdStringArray regexps; CStdString extensions = ""; if (media.Equals("video")) { regexps = g_advancedSettings.m_videoExcludeFromListingRegExps; extensions = g_advancedSettings.m_videoExtensions; } else if (media.Equals("music")) { regexps = g_advancedSettings.m_audioExcludeFromListingRegExps; extensions = g_advancedSettings.m_musicExtensions; } else if (media.Equals("pictures")) { regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps; extensions = g_advancedSettings.m_pictureExtensions; } if (CDirectory::GetDirectory(strPath, items, extensions)) { CFileItemList filteredFiles; for (unsigned int i = 0; i < (unsigned int)items.Size(); i++) { if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps)) continue; if (items[i]->IsSmb()) { CURL url(items[i]->GetPath()); items[i]->SetPath(url.GetWithoutUserDetails()); } if ((media == "video" && items[i]->HasVideoInfoTag()) || (media == "music" && items[i]->HasMusicInfoTag()) || (media == "picture" && items[i]->HasPictureInfoTag()) || media == "files" || URIUtils::IsUPnP(items.GetPath())) filteredFiles.Add(items[i]); else { CFileItemPtr fileItem(new CFileItem()); if (FillFileItem(items[i], fileItem, media, parameterObject)) filteredFiles.Add(fileItem); else filteredFiles.Add(items[i]); } } // Check if the "properties" list exists // and make sure it contains the "file" and "filetype" // fields CVariant param = parameterObject; if (!param.isMember("properties")) param["properties"] = CVariant(CVariant::VariantTypeArray); bool hasFileField = false; for (CVariant::const_iterator_array itr = param["properties"].begin_array(); itr != param["properties"].end_array(); itr++) { if (itr->asString().compare("file") == 0) { hasFileField = true; break; } } if (!hasFileField) param["properties"].append("file"); param["properties"].append("filetype"); HandleFileItemList("id", true, "files", filteredFiles, param, result); return OK; } return InvalidParams; }
JSON_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { PlayerType player = GetPlayer(parameterObject["playerid"]); CFileItemPtr fileItem; switch (player) { case Video: case Audio: { if (g_application.CurrentFileItem().GetLabel().empty()) { CFileItem tmpItem; if (player == Video) CVideoLibrary::FillFileItem(g_application.CurrentFile(), tmpItem); else CAudioLibrary::FillFileItem(g_application.CurrentFile(), tmpItem); fileItem = CFileItemPtr(new CFileItem(tmpItem)); } else fileItem = CFileItemPtr(new CFileItem(g_application.CurrentFileItem())); if (player == Video) { bool additionalInfo = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "cast" || fieldValue == "set" || fieldValue == "setid" || fieldValue == "showlink" || fieldValue == "resume") additionalInfo = true; } if (additionalInfo) { CVideoDatabase videodatabase; if (videodatabase.Open()) { switch (fileItem->GetVideoContentType()) { case VIDEODB_CONTENT_MOVIES: videodatabase.GetMovieInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_MUSICVIDEOS: videodatabase.GetMusicVideoInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_EPISODES: videodatabase.GetEpisodeInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_TVSHOWS: case VIDEODB_CONTENT_MOVIE_SETS: default: break; } videodatabase.Close(); } } } break; } case Picture: { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; CFileItemList slides; slideshow->GetSlideShowContents(slides); fileItem = slides[slideshow->CurrentSlide() - 1]; break; } case None: default: return FailedToExecute; } HandleFileItem("id", true, "item", fileItem, parameterObject, parameterObject["properties"], result, false); return OK; }
JSONRPC_STATUS CAudioLibrary::GetArtists(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; CMusicDbUrl musicUrl; if (!musicUrl.FromString("musicdb://artists/")) return InternalError; bool allroles = false; if (parameterObject["allroles"].isBoolean()) allroles = parameterObject["allroles"].asBoolean(); const CVariant &filter = parameterObject["filter"]; if (allroles) musicUrl.AddOption("roleid", -1000); //All roles, any negative parameter overrides implicit roleid=1 filter required for backward compatibility else if (filter.isMember("roleid")) musicUrl.AddOption("roleid", static_cast<int>(filter["roleid"].asInteger())); else if (filter.isMember("role")) musicUrl.AddOption("role", filter["role"].asString()); // Only one of (song) genreid/genre, albumid/album or songid/song or rules type filter is allowed by filter syntax if (filter.isMember("genreid")) //Deprecated. Use "songgenre" or "artistgenre" musicUrl.AddOption("genreid", static_cast<int>(filter["genreid"].asInteger())); else if (filter.isMember("genre")) musicUrl.AddOption("genre", filter["genre"].asString()); if (filter.isMember("songgenreid")) musicUrl.AddOption("genreid", static_cast<int>(filter["songgenreid"].asInteger())); else if (filter.isMember("songgenre")) musicUrl.AddOption("genre", filter["songgenre"].asString()); else if (filter.isMember("albumid")) musicUrl.AddOption("albumid", static_cast<int>(filter["albumid"].asInteger())); else if (filter.isMember("album")) musicUrl.AddOption("album", filter["album"].asString()); else if (filter.isMember("songid")) musicUrl.AddOption("songid", static_cast<int>(filter["songid"].asInteger())); else if (filter.isObject()) { std::string xsp; if (!GetXspFiltering("artists", filter, xsp)) return InvalidParams; musicUrl.AddOption("xsp", xsp); } bool albumArtistsOnly = !CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_SHOWCOMPILATIONARTISTS); if (parameterObject["albumartistsonly"].isBoolean()) albumArtistsOnly = parameterObject["albumartistsonly"].asBoolean(); musicUrl.AddOption("albumartistsonly", albumArtistsOnly); SortDescription sorting; ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd); if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes)) return InvalidParams; int total; std::set<std::string> fields; if (parameterObject.isMember("properties") && parameterObject["properties"].isArray()) { for (CVariant::const_iterator_array field = parameterObject["properties"].begin_array(); field != parameterObject["properties"].end_array(); field++) fields.insert(field->asString()); } musicdatabase.SetTranslateBlankArtist(false); if (!musicdatabase.GetArtistsByWhereJSON(fields, musicUrl.ToString(), result, total, sorting)) return InternalError; int start, end; HandleLimits(parameterObject, result, total, start, end); return OK; }
JSONRPC_STATUS CAudioLibrary::GetSongs(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; CMusicDbUrl musicUrl; if (!musicUrl.FromString("musicdb://songs/")) return InternalError; if (parameterObject["singlesonly"].asBoolean()) musicUrl.AddOption("singles", true); else if (!parameterObject["includesingles"].asBoolean()) musicUrl.AddOption("singles", false); bool allroles = false; if (parameterObject["allroles"].isBoolean()) allroles = parameterObject["allroles"].asBoolean(); const CVariant &filter = parameterObject["filter"]; if (allroles) musicUrl.AddOption("roleid", -1000); //All roles, override implicit roleid=1 filter required for backward compatibility else if (filter.isMember("roleid")) musicUrl.AddOption("roleid", static_cast<int>(filter["roleid"].asInteger())); else if (filter.isMember("role")) musicUrl.AddOption("role", filter["role"].asString()); // Only one of genreid/genre, artistid/artist, albumid/album or rules type filter is allowed by filter syntax if (filter.isMember("artistid")) musicUrl.AddOption("artistid", static_cast<int>(filter["artistid"].asInteger())); else if (filter.isMember("artist")) musicUrl.AddOption("artist", filter["artist"].asString()); else if (filter.isMember("genreid")) musicUrl.AddOption("genreid", static_cast<int>(filter["genreid"].asInteger())); else if (filter.isMember("genre")) musicUrl.AddOption("genre", filter["genre"].asString()); else if (filter.isMember("albumid")) musicUrl.AddOption("albumid", static_cast<int>(filter["albumid"].asInteger())); else if (filter.isMember("album")) musicUrl.AddOption("album", filter["album"].asString()); else if (filter.isObject()) { std::string xsp; if (!GetXspFiltering("songs", filter, xsp)) return InvalidParams; musicUrl.AddOption("xsp", xsp); } SortDescription sorting; ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd); if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes)) return InvalidParams; int total; std::set<std::string> fields; if (parameterObject.isMember("properties") && parameterObject["properties"].isArray()) { for (CVariant::const_iterator_array field = parameterObject["properties"].begin_array(); field != parameterObject["properties"].end_array(); field++) fields.insert(field->asString()); } if (!musicdatabase.GetSongsByWhereJSON(fields, musicUrl.ToString(), result, total, sorting)) return InternalError; if (!result.isNull()) { bool bFetchArt = fields.find("art") != fields.end(); bool bFetchFanart = fields.find("fanart") != fields.end(); bool bFetchThumb = fields.find("thumbnail") != fields.end(); if (bFetchArt || bFetchFanart || bFetchThumb) { CThumbLoader* thumbLoader = new CMusicThumbLoader(); thumbLoader->OnLoaderStart(); std::set<std::string> artfields; if (bFetchArt) artfields.insert("art"); if (bFetchFanart) artfields.insert("fanart"); if (bFetchThumb) artfields.insert("thumbnail"); for (unsigned int index = 0; index < result["songs"].size(); index++) { CFileItem item; // Only needs song and album id (if we have it) set to get art // Getting art is quicker if "albumid" has been fetched item.GetMusicInfoTag()->SetDatabaseId(result["songs"][index]["songid"].asInteger(), MediaTypeSong); if (result["songs"][index].isMember("albumid")) item.GetMusicInfoTag()->SetAlbumId(result["songs"][index]["albumid"].asInteger()); else item.GetMusicInfoTag()->SetAlbumId(-1); // Could use FillDetails, but it does unnecessary serialization of empty MusiInfoTag // CFileItemPtr itemptr(new CFileItem(item)); // FillDetails(item.GetMusicInfoTag(), itemptr, artfields, result["songs"][index], thumbLoader); thumbLoader->FillLibraryArt(item); if (bFetchThumb) { if (item.HasArt("thumb")) result["songs"][index]["thumbnail"] = CTextureUtils::GetWrappedImageURL(item.GetArt("thumb")); else result["songs"][index]["thumbnail"] = ""; } if (bFetchFanart) { if (item.HasArt("fanart")) result["songs"][index]["fanart"] = CTextureUtils::GetWrappedImageURL(item.GetArt("fanart")); else result["songs"][index]["fanart"] = ""; } if (bFetchArt) { CGUIListItem::ArtMap artMap = item.GetArt(); CVariant artObj(CVariant::VariantTypeObject); for (CGUIListItem::ArtMap::const_iterator artIt = artMap.begin(); artIt != artMap.end(); ++artIt) { if (!artIt->second.empty()) artObj[artIt->first] = CTextureUtils::GetWrappedImageURL(artIt->second); } result["songs"][index]["art"] = artObj; } } delete thumbLoader; } } int start, end; HandleLimits(parameterObject, result, total, start, end); return OK; }
bool CMusicInfoLoader::LoadAdditionalTagInfo(CFileItem* pItem) { if (!pItem || (pItem->m_bIsFolder && !pItem->IsAudio()) || pItem->IsPlayList() || pItem->IsNFO() || pItem->IsInternetStream()) return false; if (pItem->GetProperty("hasfullmusictag") == "true") return false; // already have the information std::string path(pItem->GetPath()); // For songs in library set the (primary) song artist and album properties // Use song Id (not path) as called for items from either library or file view, // but could also be listitem with tag loaded by a script if (pItem->HasMusicInfoTag() && pItem->GetMusicInfoTag()->GetType() == MediaTypeSong && pItem->GetMusicInfoTag()->GetDatabaseId() > 0) { CMusicDatabase database; database.Open(); // May already have song artist ids as item property set when data read from // db, but check property is valid array (scripts could set item properties // incorrectly), otherwise fetch artist using song id. CArtist artist; bool artistfound = false; if (pItem->HasProperty("artistid") && pItem->GetProperty("artistid").isArray()) { CVariant::const_iterator_array varid = pItem->GetProperty("artistid").begin_array(); int idArtist = varid->asInteger(); artistfound = database.GetArtist(idArtist, artist, false); } else artistfound = database.GetArtistFromSong(pItem->GetMusicInfoTag()->GetDatabaseId(), artist); if (artistfound) CMusicDatabase::SetPropertiesFromArtist(*pItem, artist); // May already have album id, otherwise fetch album from song id CAlbum album; bool albumfound = false; int idAlbum = pItem->GetMusicInfoTag()->GetAlbumId(); if (idAlbum > 0) albumfound = database.GetAlbum(idAlbum, album, false); else albumfound = database.GetAlbumFromSong(pItem->GetMusicInfoTag()->GetDatabaseId(), album); if (albumfound) CMusicDatabase::SetPropertiesFromAlbum(*pItem, album); path = pItem->GetMusicInfoTag()->GetURL(); } CLog::Log(LOGDEBUG, "Loading additional tag info for file %s", path.c_str()); // we load up the actual tag for this file in order to // fetch the lyrics and add it to the current music info tag CFileItem tempItem(path, false); std::unique_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(tempItem)); if (NULL != pLoader.get()) { CMusicInfoTag tag; pLoader->Load(path, tag); pItem->GetMusicInfoTag()->SetLyrics(tag.GetLyrics()); pItem->SetProperty("hasfullmusictag", "true"); return true; } return false; }