JSONRPC_STATUS CAudioLibrary::GetArtistDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int artistID = (int)parameterObject["artistid"].asInteger(); CMusicDbUrl musicUrl; if (!musicUrl.FromString("musicdb://2/")) return InternalError; CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; musicUrl.AddOption("artistid", artistID); CFileItemList items; CDatabase::Filter filter; if (!musicdatabase.GetArtistsByWhere(musicUrl.ToString(), filter, items) || items.Size() != 1) return InvalidParams; // Add "artist" to "properties" array by default CVariant param = parameterObject; if (!param.isMember("properties")) param["properties"] = CVariant(CVariant::VariantTypeArray); param["properties"].append("artist"); HandleFileItem("artistid", false, "artistdetails", items[0], param, param["properties"], result, false); return OK; }
bool CGUIWindowMusicBase::GetDirectory(const CStdString &strDirectory, CFileItemList &items) { CStdString directory = strDirectory; // check if the path contains a filter and if so load it and // remove it from the path to get proper GUI view states etc CSmartPlaylist filterXsp; CMusicDbUrl musicUrl; if (musicUrl.FromString(strDirectory)) { CVariant filter; if (musicUrl.GetOption("filter", filter)) { // load the filter and if it's type does not match the // path's item type reset it if (filterXsp.LoadFromJson(filter.asString()) && !filterXsp.GetType().Equals(musicUrl.GetType().c_str())) filterXsp.Reset(); // remove the "filter" option from the path musicUrl.AddOption("filter", ""); } directory = musicUrl.ToString(); } items.SetArt("thumb", ""); bool bResult = CGUIMediaWindow::GetDirectory(directory, items); if (bResult) CMusicThumbLoader::FillThumb(items); // (re-)apply the previously retrieved filter // because it was reset in CGUIMediaWindow::GetDirectory() if (!filterXsp.IsEmpty()) m_filter = filterXsp; // add in the "New Playlist" item if we're in the playlists folder if ((items.GetPath() == "special://musicplaylists/") && !items.Contains("newplaylist://")) { CFileItemPtr newPlaylist(new CFileItem(g_settings.GetUserDataItem("PartyMode.xsp"),false)); newPlaylist->SetLabel(g_localizeStrings.Get(16035)); newPlaylist->SetLabelPreformated(true); newPlaylist->m_bIsFolder = true; items.Add(newPlaylist); newPlaylist.reset(new CFileItem("newplaylist://", false)); newPlaylist->SetLabel(g_localizeStrings.Get(525)); newPlaylist->SetLabelPreformated(true); newPlaylist->SetSpecialSort(SortSpecialOnBottom); newPlaylist->SetCanQueue(false); items.Add(newPlaylist); newPlaylist.reset(new CFileItem("newsmartplaylist://music", false)); newPlaylist->SetLabel(g_localizeStrings.Get(21437)); newPlaylist->SetLabelPreformated(true); newPlaylist->SetSpecialSort(SortSpecialOnBottom); newPlaylist->SetCanQueue(false); items.Add(newPlaylist); } return bResult; }
JSONRPC_STATUS CAudioLibrary::GetAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; CMusicDbUrl musicUrl; musicUrl.FromString("musicdb://3/"); int artistID = -1, genreID = -1; const CVariant &filter = parameterObject["filter"]; if (filter.isMember("artistid")) artistID = (int)filter["artistid"].asInteger(); if (filter.isMember("artist")) musicUrl.AddOption("artist", filter["artist"].asString()); if (filter.isMember("genreid")) genreID = (int)filter["genreid"].asInteger(); if (filter.isMember("genre")) musicUrl.AddOption("genre", filter["genre"].asString()); SortDescription sorting; ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd); if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes)) return InvalidParams; CFileItemList items; if (!musicdatabase.GetAlbumsNav(musicUrl.ToString(), items, genreID, artistID, sorting)) return InternalError; int size = items.Size(); if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size) size = (int)items.GetProperty("total").asInteger(); HandleFileItemList("albumid", false, "albums", items, parameterObject, result, size, false); 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["includesingles"].asBoolean()) musicUrl.AddOption("singles", false); int genreID = -1, albumID = -1, artistID = -1; const CVariant &filter = parameterObject["filter"]; if (filter.isMember("artistid")) artistID = (int)filter["artistid"].asInteger(); else if (filter.isMember("artist")) musicUrl.AddOption("artist", filter["artist"].asString()); else if (filter.isMember("genreid")) genreID = (int)filter["genreid"].asInteger(); else if (filter.isMember("genre")) musicUrl.AddOption("genre", filter["genre"].asString()); else if (filter.isMember("albumid")) albumID = (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; CFileItemList items; if (!musicdatabase.GetSongsNav(musicUrl.ToString(), items, genreID, artistID, albumID, sorting)) return InternalError; JSONRPC_STATUS ret = GetAdditionalSongDetails(parameterObject, items, musicdatabase); if (ret != OK) return ret; int size = items.Size(); if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size) size = (int)items.GetProperty("total").asInteger(); HandleFileItemList("songid", true, "songs", items, parameterObject, result, size, 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; int genreID = -1, albumID = -1, songID = -1; const CVariant &filter = parameterObject["filter"]; if (filter.isMember("genreid")) genreID = (int)filter["genreid"].asInteger(); else if (filter.isMember("genre")) musicUrl.AddOption("genre", filter["genre"].asString()); else if (filter.isMember("albumid")) albumID = (int)filter["albumid"].asInteger(); else if (filter.isMember("album")) musicUrl.AddOption("album", filter["album"].asString()); else if (filter.isMember("songid")) songID = (int)filter["songid"].asInteger(); else if (filter.isObject()) { std::string xsp; if (!GetXspFiltering("artists", filter, xsp)) return InvalidParams; musicUrl.AddOption("xsp", xsp); } bool albumArtistsOnly = !CSettings::GetInstance().GetBool(CSettings::SETTING_MUSICLIBRARY_SHOWCOMPILATIONARTISTS); if (parameterObject["albumartistsonly"].isBoolean()) albumArtistsOnly = parameterObject["albumartistsonly"].asBoolean(); SortDescription sorting; ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd); if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes)) return InvalidParams; CFileItemList items; if (!musicdatabase.GetArtistsNav(musicUrl.ToString(), items, albumArtistsOnly, genreID, albumID, songID, CDatabase::Filter(), sorting)) return InternalError; // Add "artist" to "properties" array by default CVariant param = parameterObject; if (!param.isMember("properties")) param["properties"] = CVariant(CVariant::VariantTypeArray); param["properties"].append("artist"); int size = items.Size(); if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size) size = (int)items.GetProperty("total").asInteger(); HandleFileItemList("artistid", false, "artists", items, param, result, size, false); return OK; }
JSONRPC_STATUS CAudioLibrary::GetArtists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return InternalError; CMusicDbUrl musicUrl; musicUrl.FromString("musicdb://2/"); int genreID = -1, albumID = -1, songID = -1; const CVariant &filter = parameterObject["filter"]; if (filter.isMember("genreid")) genreID = (int)filter["genreid"].asInteger(); if (filter.isMember("genre")) musicUrl.AddOption("genre", filter["genre"].asString()); if (filter.isMember("albumid")) albumID = (int)filter["albumid"].asInteger(); if (filter.isMember("album")) musicUrl.AddOption("album", filter["album"].asString()); if (filter.isMember("songid")) songID = (int)filter["songid"].asInteger(); bool albumArtistsOnly = !g_guiSettings.GetBool("musiclibrary.showcompilationartists"); if (parameterObject["albumartistsonly"].isBoolean()) albumArtistsOnly = parameterObject["albumartistsonly"].asBoolean(); SortDescription sorting; ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd); if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes)) return InvalidParams; CFileItemList items; if (!musicdatabase.GetArtistsNav(musicUrl.ToString(), items, albumArtistsOnly, genreID, albumID, songID, sorting)) return InternalError; // Add "artist" to "properties" array by default CVariant param = parameterObject; if (!param.isMember("properties")) param["properties"] = CVariant(CVariant::VariantTypeArray); param["properties"].append("artist"); HandleFileItemList("artistid", false, "artists", items, param, result, false); return OK; }
/// \brief Add unique file and folders and its subfolders to playlist /// \param pItem The file item to add void CGUIWindowMusicBase::AddItemToPlayList(const CFileItemPtr &pItem, CFileItemList &queuedItems) { if (!pItem->CanQueue() || pItem->IsRAR() || pItem->IsZIP() || pItem->IsParentFolder()) // no zip/rar enques thank you! return; // fast lookup is needed here queuedItems.SetFastLookup(true); if (pItem->IsMusicDb() && pItem->m_bIsFolder && !pItem->IsParentFolder()) { // we have a music database folder, just grab the "all" item underneath it CMusicDatabaseDirectory dir; if (!dir.ContainsSongs(pItem->GetPath())) { // grab the ALL item in this category // Genres will still require 2 lookups, and queuing the entire Genre folder // will require 3 lookups (genre, artist, album) CMusicDbUrl musicUrl; musicUrl.FromString(pItem->GetPath()); musicUrl.AppendPath("-1/"); CFileItemPtr item(new CFileItem(musicUrl.ToString(), true)); item->SetCanQueue(true); // workaround for CanQueue() check above AddItemToPlayList(item, queuedItems); return; } } if (pItem->m_bIsFolder || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList())) { // Check if we add a locked share if ( pItem->m_bIsShareOrDrive ) { CFileItem item = *pItem; if ( !g_passwordManager.IsItemUnlocked( &item, "music" ) ) return ; } // recursive CFileItemList items; GetDirectory(pItem->GetPath(), items); //OnRetrieveMusicInfo(items); FormatAndSort(items); for (int i = 0; i < items.Size(); ++i) AddItemToPlayList(items[i], queuedItems); } else { if (pItem->IsPlayList()) { auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(*pItem)); if (pPlayList.get()) { // load it if (!pPlayList->Load(pItem->GetPath())) { CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0); return; //hmmm unable to load playlist? } CPlayList playlist = *pPlayList; for (int i = 0; i < (int)playlist.size(); ++i) { AddItemToPlayList(playlist[i], queuedItems); } return; } } else if(pItem->IsInternetStream()) { // just queue the internet stream, it will be expanded on play queuedItems.Add(pItem); } else if (pItem->IsPlugin() && pItem->GetProperty("isplayable") == "true") { // python files can be played queuedItems.Add(pItem); } else if (!pItem->IsNFO() && pItem->IsAudio()) { CFileItemPtr itemCheck = queuedItems.Get(pItem->GetPath()); if (!itemCheck || itemCheck->m_lStartOffset != pItem->m_lStartOffset) { // add item CFileItemPtr item(new CFileItem(*pItem)); m_musicdatabase.SetPropertiesForFileItem(*item); queuedItems.Add(item); } } } }
// Add an "* All ..." folder to the CFileItemList // depending on the child node void CDirectoryNode::AddQueuingFolder(CFileItemList& items) const { CFileItemPtr pItem; CMusicDbUrl musicUrl; if (!musicUrl.FromString(BuildPath())) return; // always hide "all" items if (g_advancedSettings.m_bMusicLibraryHideAllItems) return; // no need for "all" item when only one item if (items.GetObjectCount() <= 1) return; switch (GetChildType()) { // Have no queuing folder case NODE_TYPE_ROOT: case NODE_TYPE_OVERVIEW: case NODE_TYPE_TOP100: break; /* no need for all genres case NODE_TYPE_GENRE: pItem.reset(new CFileItem(g_localizeStrings.Get(15105))); // "All Genres" musicUrl.AppendPath("-1/"); pItem->SetPath(musicUrl.ToString()); break; */ case NODE_TYPE_ARTIST: if (GetType() == NODE_TYPE_OVERVIEW) return; pItem.reset(new CFileItem(g_localizeStrings.Get(15103))); // "All Artists" musicUrl.AppendPath("-1/"); pItem->SetPath(musicUrl.ToString()); break; // All album related nodes case NODE_TYPE_ALBUM: if (GetType() == NODE_TYPE_OVERVIEW) return; case NODE_TYPE_ALBUM_RECENTLY_PLAYED: case NODE_TYPE_ALBUM_RECENTLY_ADDED: case NODE_TYPE_ALBUM_COMPILATIONS: case NODE_TYPE_ALBUM_TOP100: case NODE_TYPE_YEAR_ALBUM: pItem.reset(new CFileItem(g_localizeStrings.Get(15102))); // "All Albums" musicUrl.AppendPath("-1/"); pItem->SetPath(musicUrl.ToString()); break; // All song related nodes /* case NODE_TYPE_ALBUM_RECENTLY_PLAYED_SONGS: case NODE_TYPE_ALBUM_RECENTLY_ADDED_SONGS: case NODE_TYPE_ALBUM_COMPILATIONS_SONGS: case NODE_TYPE_ALBUM_TOP100_SONGS: case NODE_TYPE_SONG_TOP100: case NODE_TYPE_SONG: pItem = new CFileItem(g_localizeStrings.Get(15104)); // "All Songs" musicUrl.AppendPath("-1/"); pItem->SetPath(musicUrl.ToString()); break;*/ default: break; } if (pItem) { pItem->m_bIsFolder = true; pItem->SetSpecialSort(g_advancedSettings.m_bMusicLibraryAllItemsOnBottom ? SortSpecialOnBottom : SortSpecialOnTop); pItem->SetCanQueue(false); pItem->SetLabelPreformated(true); if (g_advancedSettings.m_bMusicLibraryAllItemsOnBottom) items.Add(pItem); else items.AddFront(pItem, (items.Size() > 0 && items[0]->IsParentFolder()) ? 1 : 0); } }
bool CSmartPlaylistDirectory::GetDirectory(const CSmartPlaylist &playlist, CFileItemList& items, const std::string &strBaseDir /* = "" */, bool filter /* = false */) { bool success = false, success2 = false; std::vector<std::string> virtualFolders; SortDescription sorting; sorting.limitEnd = playlist.GetLimit(); sorting.sortBy = playlist.GetOrder(); sorting.sortOrder = playlist.GetOrderAscending() ? SortOrderAscending : SortOrderDescending; sorting.sortAttributes = playlist.GetOrderAttributes(); if (CSettings::Get().GetBool("filelists.ignorethewhensorting")) sorting.sortAttributes = (SortAttribute)(sorting.sortAttributes | SortAttributeIgnoreArticle); items.SetSortIgnoreFolders((sorting.sortAttributes & SortAttributeIgnoreFolders) == SortAttributeIgnoreFolders); std::string option = !filter ? "xsp" : "filter"; const std::string& group = playlist.GetGroup(); bool isGrouped = !group.empty() && !StringUtils::EqualsNoCase(group, "none") && !playlist.IsGroupMixed(); // get all virtual folders and add them to the item list playlist.GetVirtualFolders(virtualFolders); for (std::vector<std::string>::const_iterator virtualFolder = virtualFolders.begin(); virtualFolder != virtualFolders.end(); virtualFolder++) { CFileItemPtr pItem = CFileItemPtr(new CFileItem(*virtualFolder, true)); IFileDirectory *dir = CFileDirectoryFactory::Create(pItem->GetURL(), pItem.get()); if (dir != NULL) { pItem->SetSpecialSort(SortSpecialOnTop); items.Add(pItem); delete dir; } } if (playlist.GetType() == "movies" || playlist.GetType() == "tvshows" || playlist.GetType() == "episodes") { CVideoDatabase db; if (db.Open()) { MediaType mediaType = MediaTypes::FromString(playlist.GetType()); std::string baseDir = strBaseDir; if (strBaseDir.empty()) { if (mediaType == MediaTypeTvShow || mediaType == MediaTypeEpisode) baseDir = "videodb://tvshows/"; else if (mediaType == MediaTypeMovie) baseDir = "videodb://movies/"; else return false; if (!isGrouped) baseDir += "titles"; else baseDir += group; URIUtils::AddSlashAtEnd(baseDir); if (mediaType == MediaTypeEpisode) baseDir += "-1/-1/"; } CVideoDbUrl videoUrl; if (!videoUrl.FromString(baseDir)) return false; // store the smartplaylist as JSON in the URL as well std::string xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } if (!xsp.empty()) videoUrl.AddOption(option, xsp); else videoUrl.RemoveOption(option); CDatabase::Filter dbfilter; success = db.GetItems(videoUrl.ToString(), items, dbfilter, sorting); db.Close(); // if we retrieve a list of episodes and we didn't receive // a pre-defined base path, we need to fix it if (strBaseDir.empty() && mediaType == MediaTypeEpisode && !isGrouped) videoUrl.AppendPath("-1/-1/"); items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } else if (playlist.IsMusicType() || playlist.GetType().empty()) { CMusicDatabase db; if (db.Open()) { CSmartPlaylist plist(playlist); if (playlist.GetType() == "mixed" || playlist.GetType().empty()) plist.SetType("songs"); MediaType mediaType = MediaTypes::FromString(plist.GetType()); std::string baseDir = strBaseDir; if (strBaseDir.empty()) { baseDir = "musicdb://"; if (!isGrouped) { if (mediaType == MediaTypeArtist) baseDir += "artists"; else if (mediaType == MediaTypeAlbum) baseDir += "albums"; else if (mediaType == MediaTypeSong) baseDir += "songs"; else return false; } else baseDir += group; URIUtils::AddSlashAtEnd(baseDir); } CMusicDbUrl musicUrl; if (!musicUrl.FromString(baseDir)) return false; // store the smartplaylist as JSON in the URL as well std::string xsp; if (!plist.IsEmpty(filter)) { if (!plist.SaveAsJson(xsp, !filter)) return false; } if (!xsp.empty()) musicUrl.AddOption(option, xsp); else musicUrl.RemoveOption(option); CDatabase::Filter dbfilter; success = db.GetItems(musicUrl.ToString(), items, dbfilter, sorting); db.Close(); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } if (playlist.GetType() == "musicvideos" || playlist.GetType() == "mixed") { CVideoDatabase db; if (db.Open()) { CSmartPlaylist mvidPlaylist(playlist); if (playlist.GetType() == "mixed") mvidPlaylist.SetType("musicvideos"); std::string baseDir = strBaseDir; if (baseDir.empty()) { baseDir = "videodb://musicvideos/"; if (!isGrouped) baseDir += "titles"; else baseDir += group; URIUtils::AddSlashAtEnd(baseDir); } CVideoDbUrl videoUrl; if (!videoUrl.FromString(baseDir)) return false; // store the smartplaylist as JSON in the URL as well std::string xsp; if (!mvidPlaylist.IsEmpty(filter)) { if (!mvidPlaylist.SaveAsJson(xsp, !filter)) return false; } if (!xsp.empty()) videoUrl.AddOption(option, xsp); else videoUrl.RemoveOption(option); CFileItemList items2; CDatabase::Filter dbfilter; success2 = db.GetItems(videoUrl.ToString(), items2, dbfilter, sorting); db.Close(); if (items.Size() <= 0) items.SetPath(videoUrl.ToString()); items.Append(items2); if (items2.Size()) { if (items.Size() > items2.Size()) items.SetContent("mixed"); else items.SetContent("musicvideos"); } items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } items.SetLabel(playlist.GetName()); if (isGrouped) items.SetContent(group); else items.SetContent(playlist.GetType()); items.SetProperty(PROPERTY_SORT_ORDER, (int)playlist.GetOrder()); items.SetProperty(PROPERTY_SORT_ASCENDING, playlist.GetOrderDirection() == SortOrderAscending); if (!group.empty()) { items.SetProperty(PROPERTY_GROUP_BY, group); items.SetProperty(PROPERTY_GROUP_MIXED, playlist.IsGroupMixed()); } // sort grouped list by label if (items.Size() > 1 && !group.empty()) items.Sort(SortByLabel, SortOrderAscending, SortAttributeIgnoreArticle); // go through and set the playlist order for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; item->m_iprogramCount = i; // hack for playlist order } if (playlist.GetType() == "mixed") return success || success2; else if (playlist.GetType() == "musicvideos") return success2; else return success; }
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; }
JSONRPC_STATUS CAudioLibrary::GetAlbums(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://albums/")) return InternalError; if (parameterObject["includesingles"].asBoolean()) musicUrl.AddOption("show_singles", true); const CVariant &filter = parameterObject["filter"]; if (filter.isMember("artistid")) musicUrl.AddOption("artistid", (int)filter["artistid"].asInteger()); else if (filter.isMember("artist")) musicUrl.AddOption("artist", filter["artist"].asString()); else if (filter.isMember("genreid")) musicUrl.AddOption("genreid", (int)filter["genreid"].asInteger()); else if (filter.isMember("genre")) musicUrl.AddOption("genre", filter["genre"].asString()); else if (filter.isObject()) { std::string xsp; if (!GetXspFiltering("albums", 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; VECALBUMS albums; if (!musicdatabase.GetAlbumsByWhere(musicUrl.ToString(), CDatabase::Filter(), albums, total, sorting)) return InternalError; CFileItemList items; items.Reserve(albums.size()); for (unsigned int index = 0; index < albums.size(); index++) { CMusicDbUrl itemUrl = musicUrl; std::string path = StringUtils::Format("%i/", albums[index].idAlbum); itemUrl.AppendPath(path); CFileItemPtr pItem; FillAlbumItem(albums[index], itemUrl.ToString(), pItem); items.Add(pItem); } //Get Genre IDs JSONRPC_STATUS ret = GetAdditionalAlbumDetails(parameterObject, items, musicdatabase); if (ret != OK) return ret; int size = items.Size(); if (total > size) size = total; HandleFileItemList("albumid", false, "albums", items, parameterObject, result, size, false); return OK; }
bool CSmartPlaylistDirectory::GetDirectory(const CSmartPlaylist &playlist, CFileItemList& items, const CStdString &strBaseDir /* = "" */, bool filter /* = false */) { bool success = false, success2 = false; std::set<CStdString> playlists; SortDescription sorting; sorting.limitEnd = playlist.GetLimit(); sorting.sortBy = playlist.GetOrder(); sorting.sortOrder = playlist.GetOrderAscending() ? SortOrderAscending : SortOrderDescending; if (g_guiSettings.GetBool("filelists.ignorethewhensorting")) sorting.sortAttributes = SortAttributeIgnoreArticle; std::string option = !filter ? "xsp" : "filter"; if (playlist.GetType().Equals("movies") || playlist.GetType().Equals("tvshows") || playlist.GetType().Equals("episodes")) { CVideoDatabase db; if (db.Open()) { MediaType mediaType = DatabaseUtils::MediaTypeFromString(playlist.GetType()); CStdString baseDir = strBaseDir; if (strBaseDir.empty()) { switch (mediaType) { case MediaTypeTvShow: case MediaTypeEpisode: baseDir = "videodb://2/2/"; break; case MediaTypeMovie: baseDir = "videodb://1/2/"; break; default: return false; } } CVideoDbUrl videoUrl; if (!videoUrl.FromString(baseDir)) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } videoUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetSortedVideos(mediaType, videoUrl.ToString(), sorting, items, dbfilter, true); db.Close(); // if we retrieve a list of episodes and we didn't receive // a pre-defined base path, we need to fix it if (strBaseDir.empty() && mediaType == MediaTypeEpisode) videoUrl.AppendPath("-1/-1/"); items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } else if (playlist.GetType().Equals("albums")) { CMusicDatabase db; if (db.Open()) { CMusicDbUrl musicUrl; if (!musicUrl.FromString(!strBaseDir.empty() ? strBaseDir : "musicdb://3/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } musicUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetAlbumsByWhere(musicUrl.ToString(), dbfilter, items, sorting); db.Close(); items.SetContent("albums"); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } else if (playlist.GetType().Equals("artists")) { CMusicDatabase db; if (db.Open()) { CMusicDbUrl musicUrl; if (!musicUrl.FromString("musicdb://2/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } musicUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetArtistsNav(musicUrl.ToString(), items, !g_guiSettings.GetBool("musiclibrary.showcompilationartists"), -1, -1, -1, dbfilter, sorting); db.Close(); items.SetContent("artists"); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } if (playlist.GetType().Equals("songs") || playlist.GetType().Equals("mixed") || playlist.GetType().IsEmpty()) { CMusicDatabase db; if (db.Open()) { CSmartPlaylist songPlaylist(playlist); if (playlist.GetType().IsEmpty() || playlist.GetType().Equals("mixed")) songPlaylist.SetType("songs"); CMusicDbUrl musicUrl; if (!musicUrl.FromString(!strBaseDir.empty() ? strBaseDir : "musicdb://4/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!songPlaylist.IsEmpty(filter)) { if (!songPlaylist.SaveAsJson(xsp, !filter)) return false; } musicUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetSongsByWhere(musicUrl.ToString(), dbfilter, items, sorting); db.Close(); items.SetContent("songs"); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } if (playlist.GetType().Equals("musicvideos") || playlist.GetType().Equals("mixed")) { CVideoDatabase db; if (db.Open()) { CSmartPlaylist mvidPlaylist(playlist); if (playlist.GetType().Equals("mixed")) mvidPlaylist.SetType("musicvideos"); CVideoDbUrl videoUrl; if (!videoUrl.FromString(!strBaseDir.empty() ? strBaseDir : "videodb://3/2/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!mvidPlaylist.IsEmpty(filter)) { if (!mvidPlaylist.SaveAsJson(xsp, !filter)) return false; } videoUrl.AddOption(option, xsp); CFileItemList items2; success2 = db.GetSortedVideos(MediaTypeMusicVideo, videoUrl.ToString(), sorting, items2); db.Close(); items.Append(items2); if (items2.Size()) { if (items.Size() > items2.Size()) items.SetContent("mixed"); else items.SetContent("musicvideos"); } items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } items.SetLabel(playlist.GetName()); // go through and set the playlist order for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; item->m_iprogramCount = i; // hack for playlist order } if (playlist.GetType().Equals("mixed")) return success || success2; else if (playlist.GetType().Equals("musicvideos")) return success2; else return success; }
bool CSmartPlaylistDirectory::GetDirectory(const CSmartPlaylist &playlist, CFileItemList& items) { bool success = false, success2 = false; std::set<CStdString> playlists; SortDescription sorting; sorting.limitEnd = playlist.GetLimit(); sorting.sortBy = playlist.GetOrder(); sorting.sortOrder = playlist.GetOrderAscending() ? SortOrderAscending : SortOrderDescending; if (g_guiSettings.GetBool("filelists.ignorethewhensorting")) sorting.sortAttributes = SortAttributeIgnoreArticle; if (playlist.GetType().Equals("movies") || playlist.GetType().Equals("tvshows") || playlist.GetType().Equals("episodes")) { CVideoDatabase db; if (db.Open()) { MediaType mediaType = DatabaseUtils::MediaTypeFromString(playlist.GetType()); CStdString strBaseDir; switch (mediaType) { case MediaTypeTvShow: case MediaTypeEpisode: strBaseDir = "videodb://2/2/"; break; case MediaTypeMovie: strBaseDir = "videodb://1/2/"; break; default: return false; } CVideoDbUrl videoUrl; CStdString xsp; if (!videoUrl.FromString(strBaseDir) || !playlist.SaveAsJson(xsp, false)) return false; // store the smartplaylist as JSON in the URL as well videoUrl.AddOption("xsp", xsp); CDatabase::Filter filter; success = db.GetSortedVideos(mediaType, videoUrl.ToString(), sorting, items, filter, true); db.Close(); } } else if (playlist.GetType().Equals("albums")) { CMusicDatabase db; if (db.Open()) { CMusicDbUrl musicUrl; CStdString xsp; if (!musicUrl.FromString("musicdb://3/") || !playlist.SaveAsJson(xsp, false)) return false; // store the smartplaylist as JSON in the URL as well musicUrl.AddOption("xsp", xsp); CDatabase::Filter filter; success = db.GetAlbumsByWhere(musicUrl.ToString(), filter, items, sorting); items.SetContent("albums"); db.Close(); } } if (playlist.GetType().Equals("songs") || playlist.GetType().Equals("mixed") || playlist.GetType().IsEmpty()) { CMusicDatabase db; if (db.Open()) { CSmartPlaylist songPlaylist(playlist); if (playlist.GetType().IsEmpty() || playlist.GetType().Equals("mixed")) songPlaylist.SetType("songs"); CMusicDbUrl musicUrl; CStdString xsp; if (!musicUrl.FromString("musicdb://4/") || !songPlaylist.SaveAsJson(xsp, false)) return false; // store the smartplaylist as JSON in the URL as well musicUrl.AddOption("xsp", xsp); CDatabase::Filter filter; success = db.GetSongsByWhere(musicUrl.ToString(), filter, items, sorting); items.SetContent("songs"); db.Close(); } } if (playlist.GetType().Equals("musicvideos") || playlist.GetType().Equals("mixed")) { CVideoDatabase db; if (db.Open()) { CSmartPlaylist mvidPlaylist(playlist); if (playlist.GetType().Equals("mixed")) mvidPlaylist.SetType("musicvideos"); CVideoDbUrl videoUrl; CStdString xsp; if (!videoUrl.FromString("videodb://3/2/") || !mvidPlaylist.SaveAsJson(xsp, false)) return false; // store the smartplaylist as JSON in the URL as well videoUrl.AddOption("xsp", xsp); CFileItemList items2; success2 = db.GetSortedVideos(MediaTypeMusicVideo, videoUrl.ToString(), sorting, items2); db.Close(); items.Append(items2); if (items2.Size()) { if (items.Size() > items2.Size()) items.SetContent("mixed"); else items.SetContent("musicvideos"); } } } items.SetLabel(playlist.GetName()); // go through and set the playlist order for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; item->m_iprogramCount = i; // hack for playlist order } if (playlist.GetType().Equals("mixed")) return success || success2; else if (playlist.GetType().Equals("musicvideos")) return success2; else return success; }