TEST(TestVariant, VariantTypeNull) { CVariant a; EXPECT_TRUE(a.isNull()); EXPECT_EQ(CVariant::VariantTypeNull, a.type()); }
void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data) { // Extract db id of item CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject; CStdString type; int id = 0; if (item->HasVideoInfoTag()) { CVideoDatabase::VideoContentTypeToString(item->GetVideoContentType(), type); id = item->GetVideoInfoTag()->m_iDbId; } else if (item->HasMusicInfoTag()) { type = "music"; id = item->GetMusicInfoTag()->GetDatabaseId(); } if (id > 0) { type += "id"; object[type] = id; } Announce(flag, sender, message, object); }
bool CInputStream::Supports(const CFileItem &fileitem) { // check if a specific inputstream addon is requested CVariant addon = fileitem.GetProperty("inputstreamaddon"); if (!addon.isNull()) { if (addon.asString() != ID()) return false; else return true; } // check paths CSingleLock lock(m_parentSection); bool match = false; for (auto &path : m_pathList) { if (path.empty()) continue; CRegExp r(true, CRegExp::asciiOnly, path.c_str()); if (r.RegFind(fileitem.GetPath().c_str()) == 0 && r.GetFindLen() > 5) { match = true; break; } } return match; }
void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data) { // Extract db id of item CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject; CStdString type; int id = 0; if (item->HasVideoInfoTag()) { CVideoDatabase::VideoContentTypeToString((VIDEODB_CONTENT_TYPE)item->GetVideoContentType(), type); id = item->GetVideoInfoTag()->m_iDbId; } else if (item->HasMusicInfoTag()) { if (item->IsAlbum()) type = "album"; else type = "song"; id = item->GetMusicInfoTag()->GetDatabaseId(); } else type = "unknown"; object["type"] = type; if (id > 0) object["id"] = id; Announce(flag, sender, message, object); }
void CTCPServer::Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) { Value root; root["jsonrpc"] = "2.0"; root["method"] = "Announcement"; root["params"]["sender"] = sender; root["params"]["message"] = message; if (!data.isNull()) data.toJsonValue(root["params"]["data"]); StyledWriter writer; std::string str = writer.write(root); for (unsigned int i = 0; i < m_connections.size(); i++) { { CSingleLock lock (m_connections[i].m_critSection); if ((m_connections[i].GetAnnouncementFlags() & flag) == 0) continue; } unsigned int sent = 0; do { CSingleLock lock (m_connections[i].m_critSection); sent += send(m_connections[i].m_socket, str.c_str(), str.size() - sent, sent); } while (sent < str.size()); } }
TEST(TestJSONVariantParser, Parse) { CVariant variant; unsigned char buf[100]; memset(buf, 0, sizeof(buf)); variant = CJSONVariantParser::Parse(buf, sizeof(buf)); EXPECT_TRUE(variant.isNull()); }
void CGUIWindowSlideShow::AnnouncePropertyChanged(const std::string &strProperty, const CVariant &value) { if (strProperty.empty() || value.isNull()) return; CVariant data; data["player"]["playerid"] = PLAYLIST_PICTURE; data["property"][strProperty] = value; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Player, "xbmc", "OnPropertyChanged", data); }
bool CDatabaseQueryRule::Save(CVariant &obj) const { if (obj.isNull() || (m_parameter.empty() && m_operator != OPERATOR_TRUE && m_operator != OPERATOR_FALSE)) return false; obj["field"] = TranslateField(m_field); obj["operator"] = TranslateOperator(m_operator); obj["value"] = m_parameter; return true; }
static bool FilterVar(bool valid, const CVariant& variant, const std::string& check) { if (!valid) return false; if (variant.isNull() || variant.asString().empty()) return false; std::string regions = variant.asString(); return regions.find(check) == std::string::npos; }
void CPlayListPlayer::AnnouncePropertyChanged(int iPlaylist, const std::string &strProperty, const CVariant &value) { if (strProperty.empty() || value.isNull() || (iPlaylist == PLAYLIST_VIDEO && !g_application.m_pPlayer->IsPlayingVideo()) || (iPlaylist == PLAYLIST_MUSIC && !g_application.m_pPlayer->IsPlayingAudio())) return; CVariant data; data["player"]["playerid"] = iPlaylist; data["property"][strProperty] = value; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Player, "xbmc", "OnPropertyChanged", data); }
bool CInputStream::Supports(const CFileItem &fileitem) { { CSingleLock lock(m_parentSection); auto it = m_configMap.find(ID()); if (it == m_configMap.end()) return false; if (!it->second.m_ready) return false; } // check if a specific inputstream addon is requested CVariant addon = fileitem.GetProperty("inputstreamaddon"); if (!addon.isNull()) { if (addon.asString() != ID()) return false; else return true; } // check protocols std::string protocol = fileitem.GetURL().GetProtocol(); if (!protocol.empty()) { if (std::find(m_protocolsList.begin(), m_protocolsList.end(), protocol) != m_protocolsList.end()) return true; } // check paths CSingleLock lock(m_parentSection); auto it = m_configMap.find(ID()); if (it == m_configMap.end()) return false; bool match = false; for (auto &path : it->second.m_pathList) { if (path.empty()) continue; CRegExp r(true, CRegExp::asciiOnly, path.c_str()); if (r.RegFind(fileitem.GetPath().c_str()) == 0 && r.GetFindLen() > 5) { match = true; break; } } return match; }
bool CDatabaseQueryRule::Save(CVariant &obj) const { if (obj.isNull() || (m_parameter.empty() && m_operator != OPERATOR_TRUE && m_operator != OPERATOR_FALSE)) return false; obj["field"] = TranslateField(m_field); obj["operator"] = TranslateOperator(m_operator); obj["value"] = CVariant(CVariant::VariantTypeArray); for (vector<CStdString>::const_iterator it = m_parameter.begin(); it != m_parameter.end(); it++) obj["value"].push_back(*it); return true; }
bool CSmartPlaylistRule::Save(CVariant &obj) const { if (obj.isNull() || m_parameter.empty()) return false; CVariant rule(CVariant::VariantTypeObject); rule["field"] = TranslateField(m_field); rule["operator"] = TranslateOperator(m_operator); rule["value"] = CVariant(CVariant::VariantTypeArray); for (vector<CStdString>::const_iterator it = m_parameter.begin(); it != m_parameter.end(); it++) rule["value"].push_back(*it); obj.push_back(rule); return true; }
CVariant CDBusUtil::GetAll(const char *destination, const char *object, const char *interface) { CDBusMessage message(destination, object, "org.freedesktop.DBus.Properties", "GetAll"); CVariant properties; message.AppendArgument(interface); DBusMessage *reply = message.SendSystem(); if (reply) { DBusMessageIter iter; if (dbus_message_iter_init(reply, &iter)) { if (!dbus_message_has_signature(reply, "a{sv}")) CLog::Log(LOGERROR, "DBus: wrong signature on GetAll - should be \"a{sv}\" but was %s", dbus_message_iter_get_signature(&iter)); else { do { DBusMessageIter sub; dbus_message_iter_recurse(&iter, &sub); do { DBusMessageIter dict; dbus_message_iter_recurse(&sub, &dict); do { const char * key = NULL; dbus_message_iter_get_basic(&dict, &key); if (!dbus_message_iter_next(&dict)) break; CVariant value = ParseVariant(&dict); if (!value.isNull()) properties[key] = value; } while (dbus_message_iter_next(&dict)); } while (dbus_message_iter_next(&sub)); } while (dbus_message_iter_next(&iter)); } } } return properties; }
inline void CJSONRPC::BuildResponse(const CVariant& request, JSON_STATUS code, const CVariant& result, CVariant& response) { response["jsonrpc"] = "2.0"; response["id"] = request.isObject() && request.isMember("id") ? request["id"] : CVariant(); switch (code) { case OK: response["result"] = result; break; case ACK: response["result"] = "OK"; break; case InvalidRequest: response["error"]["code"] = InvalidRequest; response["error"]["message"] = "Invalid request."; break; case InvalidParams: response["error"]["code"] = InvalidParams; response["error"]["message"] = "Invalid params."; if (!result.isNull()) response["error"]["data"] = result; break; case MethodNotFound: response["error"]["code"] = MethodNotFound; response["error"]["message"] = "Method not found."; break; case ParseError: response["error"]["code"] = ParseError; response["error"]["message"] = "Parse error."; break; case BadPermission: response["error"]["code"] = BadPermission; response["error"]["message"] = "Bad client permission."; break; case FailedToExecute: response["error"]["code"] = FailedToExecute; response["error"]["message"] = "Failed to execute method."; break; default: response["error"]["code"] = InternalError; response["error"]["message"] = "Internal error."; break; } }
bool CInputStreamAddon::Supports(BinaryAddonBasePtr& addonBase, const CFileItem &fileitem) { // check if a specific inputstream addon is requested CVariant addon = fileitem.GetProperty("inputstreamaddon"); if (!addon.isNull()) return (addon.asString() == addonBase->ID()); // check protocols std::string protocol = fileitem.GetURL().GetProtocol(); if (!protocol.empty()) { std::string protocols = addonBase->Type(ADDON_INPUTSTREAM)->GetValue("@protocols").asString(); if (!protocols.empty()) { std::vector<std::string> protocolsList = StringUtils::Tokenize(protocols, "|"); for (auto& value : protocolsList) { StringUtils::Trim(value); if (value == protocol) return true; } } } std::string filetype = fileitem.GetURL().GetFileType(); if (!filetype.empty()) { std::string extensions = addonBase->Type(ADDON_INPUTSTREAM)->GetValue("@extension").asString(); if (!extensions.empty()) { std::vector<std::string> extensionsList = StringUtils::Tokenize(extensions, "|"); for (auto& value : extensionsList) { StringUtils::Trim(value); if (value == filetype) return true; } } } return false; }
void CUDiskDevice::Update() { CVariant properties = CDBusUtil::GetAll("org.freedesktop.UDisks", m_DeviceKitUDI.c_str(), "org.freedesktop.UDisks.Device"); m_isFileSystem = CStdString(properties["IdUsage"].asString()) == "filesystem"; if (m_isFileSystem) { m_UDI = properties["IdUuid"].asString(); m_Label = properties["IdLabel"].asString(); m_FileSystem = properties["IdType"].asString(); } else { m_UDI.clear(); m_Label.clear(); m_FileSystem.clear(); } m_isMounted = properties["DeviceIsMounted"].asBoolean(); if (m_isMounted && properties["DeviceMountPaths"].size() > 0) m_MountPath = properties["DeviceMountPaths"][0].asString(); else m_MountPath.clear(); m_PartitionSizeGiB = properties["PartitionSize"].asUnsignedInteger() / 1024.0 / 1024.0 / 1024.0; m_isPartition = properties["DeviceIsPartition"].asBoolean(); m_isSystemInternal = properties["DeviceIsSystemInternal"].asBoolean(); m_isOptical = properties["DeviceIsOpticalDisc"].asBoolean(); if (m_isPartition) { CVariant isRemovable = CDBusUtil::GetVariant("org.freedesktop.UDisks", properties["PartitionSlave"].asString().c_str(), "org.freedesktop.UDisks.Device", "DeviceIsRemovable"); if ( !isRemovable.isNull() ) m_isRemovable = isRemovable.asBoolean(); else m_isRemovable = false; } else m_isRemovable = properties["DeviceIsRemovable"].asBoolean(); }
void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data) { if (!item.get()) { Announce(flag, sender, message, data); return; } // Extract db id of item CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject; CStdString type; int id = 0; if(item->HasPVRChannelInfoTag()) { const PVR::CPVRChannel *channel = item->GetPVRChannelInfoTag(); id = channel->ChannelID(); type = "channel"; object["item"]["title"] = channel->ChannelName(); object["item"]["channeltype"] = channel->IsRadio() ? "radio" : "tv"; if (data.isMember("player") && data["player"].isMember("playerid")) object["player"]["playerid"] = channel->IsRadio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO; } else if (item->HasVideoInfoTag()) { id = item->GetVideoInfoTag()->m_iDbId; // TODO: Can be removed once this is properly handled when starting playback of a file if (id <= 0 && !item->GetPath().empty() && (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean())) { CVideoDatabase videodatabase; if (videodatabase.Open()) { if (videodatabase.LoadVideoInfo(item->GetPath(), *item->GetVideoInfoTag())) id = item->GetVideoInfoTag()->m_iDbId; videodatabase.Close(); } } if (!item->GetVideoInfoTag()->m_type.empty()) type = item->GetVideoInfoTag()->m_type; else CVideoDatabase::VideoContentTypeToString((VIDEODB_CONTENT_TYPE)item->GetVideoContentType(), type); if (id <= 0) { // TODO: Can be removed once this is properly handled when starting playback of a file item->SetProperty(LOOKUP_PROPERTY, false); object["item"]["title"] = item->GetVideoInfoTag()->m_strTitle; switch (item->GetVideoContentType()) { case VIDEODB_CONTENT_MOVIES: if (item->GetVideoInfoTag()->m_iYear > 0) object["item"]["year"] = item->GetVideoInfoTag()->m_iYear; break; case VIDEODB_CONTENT_EPISODES: if (item->GetVideoInfoTag()->m_iEpisode >= 0) object["item"]["episode"] = item->GetVideoInfoTag()->m_iEpisode; if (item->GetVideoInfoTag()->m_iSeason >= 0) object["item"]["season"] = item->GetVideoInfoTag()->m_iSeason; if (!item->GetVideoInfoTag()->m_strShowTitle.empty()) object["item"]["showtitle"] = item->GetVideoInfoTag()->m_strShowTitle; break; case VIDEODB_CONTENT_MUSICVIDEOS: if (!item->GetVideoInfoTag()->m_strAlbum.empty()) object["item"]["album"] = item->GetVideoInfoTag()->m_strAlbum; if (!item->GetVideoInfoTag()->m_artist.empty()) object["item"]["artist"] = StringUtils::Join(item->GetVideoInfoTag()->m_artist, " / "); break; } } } else if (item->HasMusicInfoTag()) { id = item->GetMusicInfoTag()->GetDatabaseId(); type = "song"; // TODO: Can be removed once this is properly handled when starting playback of a file if (id <= 0 && !item->GetPath().empty() && (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean())) { CMusicDatabase musicdatabase; if (musicdatabase.Open()) { CSong song; if (musicdatabase.GetSongByFileName(item->GetPath(), song, item->m_lStartOffset)) { item->GetMusicInfoTag()->SetSong(song); id = item->GetMusicInfoTag()->GetDatabaseId(); } musicdatabase.Close(); } } if (id <= 0) { // TODO: Can be removed once this is properly handled when starting playback of a file item->SetProperty(LOOKUP_PROPERTY, false); CStdString title = item->GetMusicInfoTag()->GetTitle(); if (title.IsEmpty()) title = item->GetLabel(); object["item"]["title"] = title; if (item->GetMusicInfoTag()->GetTrackNumber() > 0) object["item"]["track"] = item->GetMusicInfoTag()->GetTrackNumber(); if (!item->GetMusicInfoTag()->GetAlbum().empty()) object["item"]["album"] = item->GetMusicInfoTag()->GetAlbum(); if (!item->GetMusicInfoTag()->GetArtist().empty()) object["item"]["artist"] = item->GetMusicInfoTag()->GetArtist(); } } else if (item->HasPictureInfoTag()) { type = "picture"; object["item"]["file"] = item->GetPath(); } else type = "unknown"; object["item"]["type"] = type; if (id > 0) object["item"]["id"] = id; Announce(flag, sender, message, object); }
CVariant CDBusUtil::ParseType(DBusMessageIter *itr) { CVariant value; const char * string = NULL; dbus_int32_t int32 = 0; dbus_uint32_t uint32 = 0; dbus_int64_t int64 = 0; dbus_uint64_t uint64 = 0; dbus_bool_t boolean = false; double doublev = 0; int type = dbus_message_iter_get_arg_type(itr); switch (type) { case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_STRING: dbus_message_iter_get_basic(itr, &string); value = string; break; case DBUS_TYPE_UINT32: dbus_message_iter_get_basic(itr, &uint32); value = (uint64_t)uint32; break; case DBUS_TYPE_BYTE: case DBUS_TYPE_INT32: dbus_message_iter_get_basic(itr, &int32); value = (int64_t)int32; break; case DBUS_TYPE_UINT64: dbus_message_iter_get_basic(itr, &uint64); value = (uint64_t)uint64; break; case DBUS_TYPE_INT64: dbus_message_iter_get_basic(itr, &int64); value = (int64_t)int64; break; case DBUS_TYPE_BOOLEAN: dbus_message_iter_get_basic(itr, &boolean); value = (bool)boolean; break; case DBUS_TYPE_DOUBLE: dbus_message_iter_get_basic(itr, &doublev); value = (double)doublev; break; case DBUS_TYPE_ARRAY: DBusMessageIter array; dbus_message_iter_recurse(itr, &array); value = CVariant::VariantTypeArray; do { CVariant item = ParseType(&array); if (!item.isNull()) value.push_back(item); } while (dbus_message_iter_next(&array)); break; } return value; }
JSONRPC_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVariant optionShuffled = parameterObject["options"]["shuffled"]; CVariant optionRepeat = parameterObject["options"]["repeat"]; CVariant optionResume = parameterObject["options"]["resume"]; if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid")) { int playlistid = (int)parameterObject["item"]["playlistid"].asInteger(); if (playlistid < PLAYLIST_PICTURE) { // Apply the "shuffled" option if available if (optionShuffled.isBoolean()) g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false); // Apply the "repeat" option if available if (!optionRepeat.isNull()) g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false); } switch (playlistid) { case PLAYLIST_MUSIC: case PLAYLIST_VIDEO: g_application.getApplicationMessenger().MediaPlay(playlistid, (int)parameterObject["item"]["position"].asInteger()); OnPlaylistChanged(); break; case PLAYLIST_PICTURE: return StartSlideshow(); break; } return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path")) { CStdString exec = "slideShow("; exec += parameterObject["item"]["path"].asString(); if ((optionShuffled.isBoolean() && optionShuffled.asBoolean()) || (!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean())) exec += ", random"; else exec += ", notrandom"; if (parameterObject["item"]["recursive"].asBoolean()) exec += ", recursive"; exec += ")"; ThreadMessage msg = { TMSG_EXECUTE_BUILT_IN, (DWORD)0, (DWORD)0, exec }; g_application.getApplicationMessenger().SendMessage(msg); return ACK; } else { CFileItemList list; if (FillFileItemList(parameterObject["item"], list) && list.Size() > 0) { bool slideshow = true; for (int index = 0; index < list.Size(); index++) { if (!list[index]->IsPicture()) { slideshow = false; break; } } if (slideshow) { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; SendSlideshowAction(ACTION_STOP); slideshow->Reset(); for (int index = 0; index < list.Size(); index++) slideshow->Add(list[index].get()); if (optionShuffled.isBoolean() && optionShuffled.asBoolean()) slideshow->Shuffle(); return StartSlideshow(); } else { // Handle "shuffled" option if (optionShuffled.isBoolean()) list.SetProperty("shuffled", optionShuffled); // Handle "repeat" option if (!optionRepeat.isNull()) list.SetProperty("repeat", ParseRepeatState(optionRepeat)); // Handle "resume" option if (list.Size() == 1) { if (optionResume.isBoolean() && optionResume.asBoolean()) list[0]->m_lStartOffset = STARTOFFSET_RESUME; else if (optionResume.isDouble()) list[0]->SetProperty("StartPercent", optionResume); else if (optionResume.isObject()) list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0); } g_application.getApplicationMessenger().MediaPlay(list); } return ACK; } else return InvalidParams; } return InvalidParams; }
JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVariant options = parameterObject["options"]; CVariant optionShuffled = options["shuffled"]; CVariant optionRepeat = options["repeat"]; CVariant optionResume = options["resume"]; CVariant optionPlayer = options["playercoreid"]; if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid")) { int playlistid = (int)parameterObject["item"]["playlistid"].asInteger(); if (playlistid < PLAYLIST_PICTURE) { // Apply the "shuffled" option if available if (optionShuffled.isBoolean()) g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false); // Apply the "repeat" option if available if (!optionRepeat.isNull()) g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false); } int playlistStartPosition = (int)parameterObject["item"]["position"].asInteger(); switch (playlistid) { case PLAYLIST_MUSIC: case PLAYLIST_VIDEO: CApplicationMessenger::Get().MediaPlay(playlistid, playlistStartPosition); OnPlaylistChanged(); break; case PLAYLIST_PICTURE: { std::string firstPicturePath; if (playlistStartPosition > 0) { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (slideshow != NULL) { CFileItemList list; slideshow->GetSlideShowContents(list); if (playlistStartPosition < list.Size()) firstPicturePath = list.Get(playlistStartPosition)->GetPath(); } } return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean(), firstPicturePath); break; } } return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path")) { bool random = (optionShuffled.isBoolean() && optionShuffled.asBoolean()) || (!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean()); return StartSlideshow(parameterObject["item"]["path"].asString(), parameterObject["item"]["recursive"].asBoolean(), random); } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("partymode")) { if (g_partyModeManager.IsEnabled()) g_partyModeManager.Disable(); CApplicationMessenger::Get().ExecBuiltIn("playercontrol(partymode(" + parameterObject["item"]["partymode"].asString() + "))"); return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("channelid")) { if (!g_PVRManager.IsStarted()) return FailedToExecute; CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; if (channelGroupContainer == NULL) return FailedToExecute; CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["item"]["channelid"].asInteger()); if (channel == NULL) return InvalidParams; if ((g_PVRManager.IsPlayingRadio() && channel->IsRadio()) || (g_PVRManager.IsPlayingTV() && !channel->IsRadio())) g_application.m_pPlayer->SwitchChannel(channel); else CApplicationMessenger::Get().MediaPlay(CFileItem(channel)); return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("recordingid")) { if (!g_PVRManager.IsStarted()) return FailedToExecute; CPVRRecordings *recordingsContainer = g_PVRRecordings; if (recordingsContainer == NULL) return FailedToExecute; CFileItemPtr fileItem = recordingsContainer->GetById((int)parameterObject["item"]["recordingid"].asInteger()); if (fileItem == NULL) return InvalidParams; CApplicationMessenger::Get().MediaPlay(*fileItem); return ACK; } else { CFileItemList list; if (FillFileItemList(parameterObject["item"], list) && list.Size() > 0) { bool slideshow = true; for (int index = 0; index < list.Size(); index++) { if (!list[index]->IsPicture()) { slideshow = false; break; } } if (slideshow) { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; SendSlideshowAction(ACTION_STOP); slideshow->Reset(); for (int index = 0; index < list.Size(); index++) slideshow->Add(list[index].get()); return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean()); } else { // Handle the "playerid" option if (!optionPlayer.isNull()) { PLAYERCOREID playerId = EPC_NONE; if (optionPlayer.isInteger()) { playerId = (PLAYERCOREID)optionPlayer.asInteger(); // check if the there's actually a player with the given player ID if (CPlayerCoreFactory::Get().GetPlayerConfig(playerId) == NULL) return InvalidParams; // check if the player can handle at least the first item in the list VECPLAYERCORES possiblePlayers; CPlayerCoreFactory::Get().GetPlayers(*list.Get(0).get(), possiblePlayers); VECPLAYERCORES::const_iterator matchingPlayer = std::find(possiblePlayers.begin(), possiblePlayers.end(), playerId); if (matchingPlayer == possiblePlayers.end()) return InvalidParams; } else if (!optionPlayer.isString() || optionPlayer.asString().compare("default") != 0) return InvalidParams; // set the next player to be used g_application.m_eForcedNextPlayer = playerId; } // Handle "shuffled" option if (optionShuffled.isBoolean()) list.SetProperty("shuffled", optionShuffled); // Handle "repeat" option if (!optionRepeat.isNull()) list.SetProperty("repeat", ParseRepeatState(optionRepeat)); // Handle "resume" option if (list.Size() == 1) { if (optionResume.isBoolean() && optionResume.asBoolean()) list[0]->m_lStartOffset = STARTOFFSET_RESUME; else if (optionResume.isDouble()) list[0]->SetProperty("StartPercent", optionResume); else if (optionResume.isObject()) list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0); } CApplicationMessenger::Get().MediaPlay(list); } return ACK; } else return InvalidParams; } return InvalidParams; }
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 CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVariant optionShuffled = parameterObject["options"]["shuffled"]; CVariant optionRepeat = parameterObject["options"]["repeat"]; CVariant optionResume = parameterObject["options"]["resume"]; if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid")) { int playlistid = (int)parameterObject["item"]["playlistid"].asInteger(); if (playlistid < PLAYLIST_PICTURE) { // Apply the "shuffled" option if available if (optionShuffled.isBoolean()) g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false); // Apply the "repeat" option if available if (!optionRepeat.isNull()) g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false); } switch (playlistid) { case PLAYLIST_MUSIC: case PLAYLIST_VIDEO: CApplicationMessenger::Get().MediaPlay(playlistid, (int)parameterObject["item"]["position"].asInteger()); OnPlaylistChanged(); break; case PLAYLIST_PICTURE: return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean()); break; } return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path")) { bool random = (optionShuffled.isBoolean() && optionShuffled.asBoolean()) || (!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean()); return StartSlideshow(parameterObject["item"]["path"].asString(), parameterObject["item"]["recursive"].asBoolean(), random); } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("partymode")) { if (g_partyModeManager.IsEnabled()) g_partyModeManager.Disable(); CApplicationMessenger::Get().ExecBuiltIn("playercontrol(partymode(" + parameterObject["item"]["partymode"].asString() + "))"); return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("channelid")) { if (!g_PVRManager.IsStarted()) return FailedToExecute; CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; if (channelGroupContainer == NULL) return FailedToExecute; CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["item"]["channelid"].asInteger()); if (channel == NULL) return InvalidParams; CApplicationMessenger::Get().MediaPlay(CFileItem(*channel.get())); return ACK; } else { CFileItemList list; if (FillFileItemList(parameterObject["item"], list) && list.Size() > 0) { bool slideshow = true; for (int index = 0; index < list.Size(); index++) { if (!list[index]->IsPicture()) { slideshow = false; break; } } if (slideshow) { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; SendSlideshowAction(ACTION_STOP); slideshow->Reset(); for (int index = 0; index < list.Size(); index++) slideshow->Add(list[index].get()); return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean()); } else { // Handle "shuffled" option if (optionShuffled.isBoolean()) list.SetProperty("shuffled", optionShuffled); // Handle "repeat" option if (!optionRepeat.isNull()) list.SetProperty("repeat", ParseRepeatState(optionRepeat)); // Handle "resume" option if (list.Size() == 1) { if (optionResume.isBoolean() && optionResume.asBoolean()) list[0]->m_lStartOffset = STARTOFFSET_RESUME; else if (optionResume.isDouble()) list[0]->SetProperty("StartPercent", optionResume); else if (optionResume.isObject()) list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0); } CApplicationMessenger::Get().MediaPlay(list); } return ACK; } else return InvalidParams; } return InvalidParams; }
JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { CVariant options = parameterObject["options"]; CVariant optionShuffled = options["shuffled"]; CVariant optionRepeat = options["repeat"]; CVariant optionResume = options["resume"]; CVariant optionPlayer = options["playername"]; if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid")) { int playlistid = (int)parameterObject["item"]["playlistid"].asInteger(); if (playlistid < PLAYLIST_PICTURE) { // Apply the "shuffled" option if available if (optionShuffled.isBoolean()) g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false); // Apply the "repeat" option if available if (!optionRepeat.isNull()) g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false); } int playlistStartPosition = (int)parameterObject["item"]["position"].asInteger(); switch (playlistid) { case PLAYLIST_MUSIC: case PLAYLIST_VIDEO: CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PLAY, playlistid, playlistStartPosition); OnPlaylistChanged(); break; case PLAYLIST_PICTURE: { std::string firstPicturePath; if (playlistStartPosition > 0) { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (slideshow != NULL) { CFileItemList list; slideshow->GetSlideShowContents(list); if (playlistStartPosition < list.Size()) firstPicturePath = list.Get(playlistStartPosition)->GetPath(); } } return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean(), firstPicturePath); break; } } return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path")) { bool random = (optionShuffled.isBoolean() && optionShuffled.asBoolean()) || (!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean()); return StartSlideshow(parameterObject["item"]["path"].asString(), parameterObject["item"]["recursive"].asBoolean(), random); } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("partymode")) { if (g_partyModeManager.IsEnabled()) g_partyModeManager.Disable(); CApplicationMessenger::GetInstance().SendMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, "playercontrol(partymode(" + parameterObject["item"]["partymode"].asString() + "))"); return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("channelid")) { if (!g_PVRManager.IsStarted()) return FailedToExecute; CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups; if (channelGroupContainer == NULL) return FailedToExecute; CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["item"]["channelid"].asInteger()); if (channel == NULL) return InvalidParams; if ((g_PVRManager.IsPlayingRadio() && channel->IsRadio()) || (g_PVRManager.IsPlayingTV() && !channel->IsRadio())) g_application.m_pPlayer->SwitchChannel(channel); else { CFileItemList *l = new CFileItemList; //don't delete, l->Add(std::make_shared<CFileItem>(channel)); CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, -1, -1, static_cast<void*>(l)); } return ACK; } else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("recordingid")) { if (!g_PVRManager.IsStarted()) return FailedToExecute; CPVRRecordings *recordingsContainer = g_PVRRecordings; if (recordingsContainer == NULL) return FailedToExecute; CFileItemPtr fileItem = recordingsContainer->GetById((int)parameterObject["item"]["recordingid"].asInteger()); if (fileItem == NULL) return InvalidParams; CFileItemList *l = new CFileItemList; //don't delete, l->Add(std::make_shared<CFileItem>(*fileItem)); CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, -1, -1, static_cast<void*>(l)); return ACK; } else { CFileItemList list; if (FillFileItemList(parameterObject["item"], list) && list.Size() > 0) { bool slideshow = true; for (int index = 0; index < list.Size(); index++) { if (!list[index]->IsPicture()) { slideshow = false; break; } } if (slideshow) { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; SendSlideshowAction(ACTION_STOP); slideshow->Reset(); for (int index = 0; index < list.Size(); index++) slideshow->Add(list[index].get()); return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean()); } else { std::string playername; // Handle the "playerid" option if (!optionPlayer.isNull()) { if (optionPlayer.isString()) { playername = optionPlayer.asString(); if (playername != "default") { // check if the there's actually a player with the given name if (CPlayerCoreFactory::GetInstance().GetPlayerType(playername).empty()) return InvalidParams; // check if the player can handle at least the first item in the list std::vector<std::string> possiblePlayers; CPlayerCoreFactory::GetInstance().GetPlayers(*list.Get(0).get(), possiblePlayers); bool match = false; for (auto entry : possiblePlayers) { if (StringUtils::CompareNoCase(entry, playername)) { match = true; break; } } if (!match) return InvalidParams; } } else return InvalidParams; } // Handle "shuffled" option if (optionShuffled.isBoolean()) list.SetProperty("shuffled", optionShuffled); // Handle "repeat" option if (!optionRepeat.isNull()) list.SetProperty("repeat", ParseRepeatState(optionRepeat)); // Handle "resume" option if (list.Size() == 1) { if (optionResume.isBoolean() && optionResume.asBoolean()) list[0]->m_lStartOffset = STARTOFFSET_RESUME; else if (optionResume.isDouble()) list[0]->SetProperty("StartPercent", optionResume); else if (optionResume.isObject()) list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0); } auto l = new CFileItemList(); //don't delete l->Copy(list); CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PLAY, -1, -1, static_cast<void*>(l), playername); } return ACK; } else return InvalidParams; } return InvalidParams; }
void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data) { if (!item.get()) { Announce(flag, sender, message, data); return; } // Extract db id of item CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject; CStdString type; int id = 0; if (item->HasVideoInfoTag()) { id = item->GetVideoInfoTag()->m_iDbId; // TODO: Can be removed once this is properly handled when starting playback of a file if (id <= 0 && !item->GetPath().empty() && (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean())) { CVideoDatabase videodatabase; if (videodatabase.Open()) { if (videodatabase.LoadVideoInfo(item->GetPath(), *item->GetVideoInfoTag())) id = item->GetVideoInfoTag()->m_iDbId; videodatabase.Close(); } } CVideoDatabase::VideoContentTypeToString((VIDEODB_CONTENT_TYPE)item->GetVideoContentType(), type); if (id <= 0) { // TODO: Can be removed once this is properly handled when starting playback of a file item->SetProperty(LOOKUP_PROPERTY, false); object["title"] = item->GetVideoInfoTag()->m_strTitle; switch (item->GetVideoContentType()) { case VIDEODB_CONTENT_MOVIES: if (item->GetVideoInfoTag()->m_iYear > 0) object["year"] = item->GetVideoInfoTag()->m_iYear; break; case VIDEODB_CONTENT_EPISODES: if (item->GetVideoInfoTag()->m_iEpisode >= 0) object["episode"] = item->GetVideoInfoTag()->m_iEpisode; if (item->GetVideoInfoTag()->m_iSeason >= 0) object["season"] = item->GetVideoInfoTag()->m_iSeason; if (!item->GetVideoInfoTag()->m_strShowTitle.empty()) object["showtitle"] = item->GetVideoInfoTag()->m_strShowTitle; break; case VIDEODB_CONTENT_MUSICVIDEOS: if (!item->GetVideoInfoTag()->m_strAlbum.empty()) object["album"] = item->GetVideoInfoTag()->m_strAlbum; if (!item->GetVideoInfoTag()->m_strArtist.empty()) object["artist"] = item->GetVideoInfoTag()->m_strArtist; break; } } } else if (item->HasMusicInfoTag()) { id = item->GetMusicInfoTag()->GetDatabaseId(); type = "song"; // TODO: Can be removed once this is properly handled when starting playback of a file if (id <= 0 && !item->GetPath().empty() && (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean())) { CMusicDatabase musicdatabase; if (musicdatabase.Open()) { CSong song; if (musicdatabase.GetSongByFileName(item->GetPath(), song)) { item->GetMusicInfoTag()->SetSong(song); item->SetMusicThumb(); id = item->GetMusicInfoTag()->GetDatabaseId(); } musicdatabase.Close(); } } if (id <= 0) { // TODO: Can be removed once this is properly handled when starting playback of a file item->SetProperty(LOOKUP_PROPERTY, false); object["title"] = item->GetMusicInfoTag()->GetTitle(); if (item->GetMusicInfoTag()->GetTrackNumber() > 0) object["track"] = item->GetMusicInfoTag()->GetTrackNumber(); if (!item->GetMusicInfoTag()->GetAlbum().empty()) object["album"] = item->GetMusicInfoTag()->GetAlbum(); if (!item->GetMusicInfoTag()->GetArtist().empty()) object["artist"] = item->GetMusicInfoTag()->GetArtist(); } } else type = "unknown"; object["item"]["type"] = type; if (id > 0) object["item"]["id"] = id; Announce(flag, sender, message, object); }