bool CInputStream::Open(CFileItem &fileitem) { INPUTSTREAM props; props.m_nCountInfoValues = 0; std::vector<std::string> values; for (auto &key : m_fileItemProps) { if (fileitem.GetProperty(key).isNull()) continue; props.m_ListItemProperties[props.m_nCountInfoValues].m_strKey = key.c_str(); values.push_back(fileitem.GetProperty(key).asString()); props.m_ListItemProperties[props.m_nCountInfoValues].m_strValue = values.back().c_str(); props.m_nCountInfoValues++; } props.m_strURL = fileitem.GetPath().c_str(); bool ret = false; try { ret = m_pStruct->Open(props); if (ret) m_caps = m_pStruct->GetCapabilities(); } catch (std::exception &e) { CLog::Log(LOGERROR, "CInputStream::Open - could not open stream. Reason: %s", e.what()); return false; } UpdateStreams(); return ret; }
bool CInputStream::Open(CFileItem &fileitem) { INPUTSTREAM props; std::map<std::string, std::string> propsMap; for (auto &key : m_fileItemProps) { if (fileitem.GetProperty(key).isNull()) continue; propsMap[key] = fileitem.GetProperty(key).asString(); } props.m_nCountInfoValues = 0; for (auto &pair : propsMap) { props.m_ListItemProperties[props.m_nCountInfoValues].m_strKey = pair.first.c_str(); props.m_ListItemProperties[props.m_nCountInfoValues].m_strValue = pair.second.c_str(); props.m_nCountInfoValues++; } props.m_strURL = fileitem.GetPath().c_str(); std::string libFolder = URIUtils::GetDirectory(m_parentLib); std::string profileFolder = CSpecialProtocol::TranslatePath(Profile()); props.m_libFolder = libFolder.c_str(); props.m_profileFolder = profileFolder.c_str(); bool ret = m_pStruct->Open(props); if (ret) m_caps = m_pStruct->GetCapabilities(); UpdateStreams(); return ret; }
bool CAppManager::Launch(const CFileItem& item, bool bReportInstall) { m_launchedItem = item; if (item.GetPropertyBOOL("testapp") == true) { item.Dump(); CUtil::CopyDirRecursive(item.GetProperty("actual-path"),_P(item.GetProperty("app-localpath"))); } return Launch(item.m_strPath, bReportInstall); }
void CGUIMediaWindow::GetContextButtons(int itemNumber, CContextButtons &buttons) { CFileItem *item = (itemNumber >= 0 && itemNumber < m_vecItems->Size()) ? m_vecItems->Get(itemNumber) : NULL; if (item == NULL) return; if (item->IsPluginFolder()) { if (CPluginSettings::SettingsExist(item->m_strPath)) buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045); } // user added buttons CStdString label; CStdString action; for (int i = CONTEXT_BUTTON_USER1; i <= CONTEXT_BUTTON_USER10; i++) { label.Format("contextmenulabel(%i)", i - CONTEXT_BUTTON_USER1); if (item->GetProperty(label).IsEmpty()) break; action.Format("contextmenuaction(%i)", i - CONTEXT_BUTTON_USER1); if (item->GetProperty(action).IsEmpty()) break; buttons.Add((CONTEXT_BUTTON)i, item->GetProperty(label)); } #ifdef PRE_SKIN_VERSION_2_1_COMPATIBILITY // check if the skin even supports favourites RESOLUTION res; CStdString favourites(g_SkinInfo.GetSkinPath("DialogFavourites.xml", &res)); if (XFILE::CFile::Exists(favourites)) { #endif // TODO: FAVOURITES Conditions on masterlock and localisation if (!item->IsParentFolder() && !item->m_strPath.Equals("add") && !item->m_strPath.Equals("newplaylist://") && !item->m_strPath.Left(19).Equals("newsmartplaylist://")) { if (CFavourites::IsFavourite(item, GetID())) buttons.Add(CONTEXT_BUTTON_ADD_FAVOURITE, 14077); // Remove Favourite else buttons.Add(CONTEXT_BUTTON_ADD_FAVOURITE, 14076); // Add To Favourites; } #ifdef PRE_SKIN_VERSION_2_1_COMPATIBILITY } #endif }
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; }
bool SaveFileState(const CFileItem& item, const CBookmark& bookmark, const bool updatePlayCount) { std::string path = item.GetProperty("original_listitem_url").asString(); if (!item.HasVideoInfoTag() || path.empty()) { return false; } NPT_String curr_value; NPT_String new_value; if (item.GetVideoInfoTag()->m_resumePoint.timeInSeconds != bookmark.timeInSeconds) { CLog::Log(LOGDEBUG, "UPNP: Updating resume point for item %s", path.c_str()); long time = (long)bookmark.timeInSeconds; if (time < 0) time = 0; curr_value.Append(NPT_String::Format("<upnp:lastPlaybackPosition>%ld</upnp:lastPlaybackPosition>", (long)item.GetVideoInfoTag()->m_resumePoint.timeInSeconds)); new_value.Append(NPT_String::Format("<upnp:lastPlaybackPosition>%ld</upnp:lastPlaybackPosition>", time)); } if (updatePlayCount) { CLog::Log(LOGDEBUG, "UPNP: Marking video item %s as watched", path.c_str()); if (!curr_value.IsEmpty()) curr_value.Append(","); if (!new_value.IsEmpty()) new_value.Append(","); curr_value.Append("<upnp:playCount>0</upnp:playCount>"); new_value.Append("<upnp:playCount>1</upnp:playCount>"); } return InvokeUpdateObject(path.c_str(), (const char*)curr_value, (const char*)new_value); }
bool CInputStream::Open(CFileItem &fileitem) { INPUTSTREAM props; std::map<std::string, std::string> propsMap; for (auto &key : m_fileItemProps) { if (fileitem.GetProperty(key).isNull()) continue; propsMap[key] = fileitem.GetProperty(key).asString(); } props.m_nCountInfoValues = 0; for (auto &pair : propsMap) { props.m_ListItemProperties[props.m_nCountInfoValues].m_strKey = pair.first.c_str(); props.m_ListItemProperties[props.m_nCountInfoValues].m_strValue = pair.second.c_str(); props.m_nCountInfoValues++; } props.m_strURL = fileitem.GetPath().c_str(); std::string libFolder = URIUtils::GetDirectory(m_parentLib); props.m_libFolder = libFolder.c_str(); bool ret = false; try { ret = m_pStruct->Open(props); if (ret) m_caps = m_pStruct->GetCapabilities(); } catch (std::exception &e) { CLog::Log(LOGERROR, "CInputStream::Open - could not open stream. Reason: %s", e.what()); return false; } UpdateStreams(); return ret; }
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 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; }
bool CRetroPlayerDialogs::GameLauchDialog(const CFileItem &file, GameClientPtr &result) { CFileItem fileCopy = file; // If an explicit game client was specified, try to download that if (fileCopy.HasProperty("gameclient")) { if (InstallGameClient(fileCopy.GetProperty("gameclient").asString(), fileCopy, result)) return true; fileCopy.ClearProperty("gameclient"); // don't want this to interfere later on } // First, ask the user if they would like to install a game client or go to // the add-on manager CContextButtons choices; choices.Add(0, 24026); // Install emulator choices.Add(1, 24058); // Add-on manager int btnid = CGUIDialogContextMenu::ShowAndGetChoice(choices); if (btnid == 0) // Install emulator { return InstallGameClientDialog(fileCopy, result); } else if (btnid == 1) // Add-on manager { // Queue the file so that if a compatible game client is installed, the // user will be asked to launch the file. CGameManager::Get().SetAutoLaunch(fileCopy); CLog::Log(LOGDEBUG, "RetroPlayer: User chose to go to the add-on manager"); CStdStringArray params; params.push_back("addons://all/xbmc.gameclient"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); } else { CLog::Log(LOGDEBUG, "RetroPlayer: User canceled game client selection"); } return false; }
void CSaveFileState::DoWork(CFileItem& item, CBookmark& bookmark, bool updatePlayCount) { std::string progressTrackingFile = item.GetPath(); if (item.HasVideoInfoTag() && StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://")) progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified else if (item.HasProperty("original_listitem_url")) { // only use original_listitem_url for Python, UPnP and Bluray sources std::string original = item.GetProperty("original_listitem_url").asString(); if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(item.GetPath())) progressTrackingFile = original; } if (!progressTrackingFile.empty()) { #ifdef HAS_UPNP // checks if UPnP server of this file is available and supports updating if (URIUtils::IsUPnP(progressTrackingFile) && UPNP::CUPnP::SaveFileState(item, bookmark, updatePlayCount)) { return; } #endif if (item.IsVideo()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for video item %s", __FUNCTION__, redactPath.c_str()); CVideoDatabase videodatabase; if (!videodatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open video database. Can not save file state!", __FUNCTION__); } else { if (URIUtils::IsPlugin(progressTrackingFile) && !(item.HasVideoInfoTag() && item.GetVideoInfoTag()->m_iDbId >= 0)) { // FileItem from plugin can lack information, make sure all needed fields are set CVideoInfoTag *tag = item.GetVideoInfoTag(); CStreamDetails streams = tag->m_streamDetails; if (videodatabase.LoadVideoInfo(progressTrackingFile, *tag)) { item.SetPath(progressTrackingFile); item.ClearProperty("original_listitem_url"); tag->m_streamDetails = streams; } } bool updateListing = false; // No resume & watched status for livetv if (!item.IsLiveTV()) { if (updatePlayCount) { // no watched for not yet finished pvr recordings if (!item.IsInProgressPVRRecording()) { CLog::Log(LOGDEBUG, "%s - Marking video item %s as watched", __FUNCTION__, redactPath.c_str()); // consider this item as played videodatabase.IncrementPlayCount(item); item.GetVideoInfoTag()->IncrementPlayCount(); item.SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, true); updateListing = true; if (item.HasVideoInfoTag()) { CVariant data; data["id"] = item.GetVideoInfoTag()->m_iDbId; data["type"] = item.GetVideoInfoTag()->m_type; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data); } } } else videodatabase.UpdateLastPlayed(item); if (!item.HasVideoInfoTag() || item.GetVideoInfoTag()->GetResumePoint().timeInSeconds != bookmark.timeInSeconds) { if (bookmark.timeInSeconds <= 0.0f) videodatabase.ClearBookMarksOfFile(progressTrackingFile, CBookmark::RESUME); else videodatabase.AddBookMarkToFile(progressTrackingFile, bookmark, CBookmark::RESUME); if (item.HasVideoInfoTag()) item.GetVideoInfoTag()->SetResumePoint(bookmark); // UPnP announce resume point changes to clients // however not if playcount is modified as that already announces if (item.HasVideoInfoTag() && !updatePlayCount) { CVariant data; data["id"] = item.GetVideoInfoTag()->m_iDbId; data["type"] = item.GetVideoInfoTag()->m_type; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data); } updateListing = true; } } if (item.HasVideoInfoTag() && item.GetVideoInfoTag()->HasStreamDetails()) { CFileItem dbItem(item); // Check whether the item's db streamdetails need updating if (!videodatabase.GetStreamDetails(dbItem) || dbItem.GetVideoInfoTag()->m_streamDetails != item.GetVideoInfoTag()->m_streamDetails) { videodatabase.SetStreamDetailsForFile(item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile); updateListing = true; } } // Could be part of an ISO stack. In this case the bookmark is saved onto the part. // In order to properly update the list, we need to refresh the stack's resume point CApplicationStackHelper& stackHelper = g_application.GetAppStackHelper(); if (stackHelper.HasRegisteredStack(item) && stackHelper.GetRegisteredStackTotalTimeMs(item) == 0) videodatabase.GetResumePoint(*(stackHelper.GetRegisteredStack(item)->GetVideoInfoTag())); videodatabase.Close(); if (updateListing) { CUtil::DeleteVideoDatabaseDirectoryCache(); CFileItemPtr msgItem(new CFileItem(item)); if (item.HasProperty("original_listitem_url")) msgItem->SetPath(item.GetProperty("original_listitem_url").asString()); CGUIMessage message(GUI_MSG_NOTIFY_ALL, CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow(), 0, GUI_MSG_UPDATE_ITEM, 0, msgItem); CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(message); } } } if (item.IsAudio()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for audio item %s", __FUNCTION__, redactPath.c_str()); CMusicDatabase musicdatabase; if (updatePlayCount) { if (!musicdatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open music database. Can not save file state!", __FUNCTION__); } else { // consider this item as played CLog::Log(LOGDEBUG, "%s - Marking audio item %s as listened", __FUNCTION__, redactPath.c_str()); musicdatabase.IncrementPlayCount(item); musicdatabase.Close(); // UPnP announce resume point changes to clients // however not if playcount is modified as that already announces if (item.IsMusicDb()) { CVariant data; data["id"] = item.GetMusicInfoTag()->GetDatabaseId(); data["type"] = item.GetMusicInfoTag()->GetType(); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::AudioLibrary, "xbmc", "OnUpdate", data); } } } if (item.IsAudioBook()) { musicdatabase.Open(); musicdatabase.SetResumeBookmarkForAudioBook(item, item.m_lStartOffset + CUtil::ConvertSecsToMilliSecs(bookmark.timeInSeconds)); musicdatabase.Close(); } } } }
bool CNfsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CURI url(strPath); bool bResult = false; if(url.GetProtocol() != "nfs") { CLog::Log(LOGERROR, "CNfsDirectory::%s - invalid protocol [%s]", __func__, url.GetProtocol().c_str()); return false; } CBrowserService* pBrowser = g_application.GetBrowserService(); if( strPath == "nfs://" && pBrowser ) { pBrowser->GetShare( CBrowserService::NFS_SHARE, items ); return true; } // If we have the items in the cache, return them if (g_directoryCache.GetDirectory(strPath, items)) { return true; } if(strPath == "nfs://all") { std::vector<NfsShare> shares; bool succedded = ScanNfsShares(shares); if(!succedded) { CLog::Log(LOGERROR, "CNfsDirectory::%s - failed to scan NFS shares", __func__); return false; } for(size_t i=0; i<shares.size(); i++) { CStdString hostName = shares[i].hostName.IsEmpty() ? shares[i].ipAddr : shares[i].hostName; CFileItemPtr pItem(new CFileItem(hostName)); pItem->m_strTitle = hostName; pItem->m_bIsFolder = true; pItem->m_strPath.Format("nfs://%s", hostName); pItem->SetProperty("isNetwork",true); items.Add(pItem); } CLog::Log(LOGDEBUG, "CNfsDirectory::%s - found %d NFS devices", __func__, shares.size()); return true; } CStdString hostName = url.GetHostName(); CStdString fileName = url.GetFileName(); if(fileName.IsEmpty()) { std::vector<CStdString> exports; if(false == GetExports(hostName.c_str(), exports)) { CLog::Log(LOGERROR, "CNfsDirectory::%s - failed to get export for host [%s]", __func__, hostName.c_str()); return false; } CLog::Log(LOGDEBUG, "CNfsDirectory::%s - found [%d] exports for [%s] ", __func__, exports.size(), hostName.c_str()); for(size_t i=0; i<exports.size(); i++) { CStdString title = exports[i]; CFileItemPtr pItem(new CFileItem(title)); pItem->m_strTitle = title; pItem->m_bIsFolder = true; pItem->SetProperty("isNetwork",true); pItem->m_strPath.Format("nfs://%s%s", hostName, exports[i]); items.Add(pItem); } bResult = true; } else { CFileItem item; if(false == GetResource(url, item)) { CLog::Log(LOGERROR, "CNfsDirectory::%s - failed to get resource for path [%s]", __func__, url.Get().c_str()); return false; } bResult = CUtil::GetHDDDirectory(item.m_strPath,items); for(int i=0; i<items.Size(); i++) { if(items[i]->m_bIsFolder) { items[i]->SetProperty("isNetwork",true); } // build nfs path CStdString nfsPath = items[i]->m_strPath; nfsPath.Replace(item.m_strPath, strPath); if (nfsPath.length() >= strPath.length()) { CStdString strNewFilename = nfsPath.substr(strPath.length()); CStdString strNfsFileName; CStdString strFileName = item.GetProperty("filename"); if (strFileName.IsEmpty()) strNfsFileName = ":" + strNewFilename; else strNfsFileName = strNewFilename; items[i]->m_strPath.Format("%s%s", strPath.c_str(), strNfsFileName.c_str()); } } } return bResult; }