int CGUIWindowVideoNav::GetFirstUnwatchedItemIndex(bool includeAllSeasons, bool includeSpecials) { int iIndex = 0; int iUnwatchedSeason = INT_MAX; // Run through the list of items and find the season number of the first season with unwatched episodes for (int i = 0; i < m_vecItems->Size(); ++i) { CFileItemPtr pItem = m_vecItems->Get(i); if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag()) continue; CVideoInfoTag *pTag = pItem->GetVideoInfoTag(); if ((!includeAllSeasons && pTag->m_iSeason < 0) || (!includeSpecials && pTag->m_iSeason == 0)) continue; // Is the season unwatched, and is its season number lower than the currently identified // first unwatched season if (pTag->GetPlayCount() == 0 && pTag->m_iSeason < iUnwatchedSeason) { iUnwatchedSeason = pTag->m_iSeason; iIndex = i; } } NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath()); if (nodeType == NODE_TYPE::NODE_TYPE_EPISODES) { iIndex = 0; int iUnwatchedEpisode = INT_MAX; // Now run through the list of items and check episodes from the season identified above // to find the first (lowest episode number) unwatched episode. for (int i = 0; i < m_vecItems->Size(); ++i) { CFileItemPtr pItem = m_vecItems->Get(i); if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag()) continue; CVideoInfoTag *pTag = pItem->GetVideoInfoTag(); // Does the episode belong to the unwatched season and Is the episode unwatched, and is its episode number // lower than the currently identified first unwatched episode if (pTag->m_iSeason == iUnwatchedSeason && pTag->GetPlayCount() == 0 && pTag->m_iEpisode < iUnwatchedEpisode) { iUnwatchedEpisode = pTag->m_iEpisode; iIndex = i; } } } return iIndex; }
JSONRPC_STATUS CVideoLibrary::SetEpisodeDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["episodeid"].asInteger(); CVideoDatabase videodatabase; if (!videodatabase.Open()) return InternalError; CVideoInfoTag infos; videodatabase.GetEpisodeInfo("", infos, id); if (infos.m_iDbId <= 0) { videodatabase.Close(); return InvalidParams; } int tvshowid = videodatabase.GetTvShowForEpisode(id); if (tvshowid <= 0) { videodatabase.Close(); return InvalidParams; } // get artwork std::map<std::string, std::string> artwork; videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork); int playcount = infos.GetPlayCount(); CDateTime lastPlayed = infos.m_lastPlayed; std::set<std::string> removedArtwork; std::set<std::string> updatedDetails; UpdateVideoTag(parameterObject, infos, artwork, removedArtwork, updatedDetails); if (videodatabase.SetDetailsForEpisode(infos.m_strFileNameAndPath, infos, artwork, tvshowid, id) <= 0) return InternalError; if (!videodatabase.RemoveArtForItem(infos.m_iDbId, MediaTypeEpisode, removedArtwork)) return InternalError; if (playcount != infos.GetPlayCount() || lastPlayed != infos.m_lastPlayed) { // restore original playcount or the new one won't be announced int newPlaycount = infos.GetPlayCount(); infos.SetPlayCount(playcount); videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed); } UpdateResumePoint(parameterObject, infos, videodatabase); CJSONRPCUtils::NotifyItemUpdated(); return ACK; }
JSONRPC_STATUS CVideoLibrary::SetMusicVideoDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { int id = (int)parameterObject["musicvideoid"].asInteger(); CVideoDatabase videodatabase; if (!videodatabase.Open()) return InternalError; CVideoInfoTag infos; videodatabase.GetMusicVideoInfo("", infos, id); if (infos.m_iDbId <= 0) { videodatabase.Close(); return InvalidParams; } // get artwork std::map<std::string, std::string> artwork; videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork); int playcount = infos.GetPlayCount(); CDateTime lastPlayed = infos.m_lastPlayed; std::set<std::string> removedArtwork; std::set<std::string> updatedDetails; UpdateVideoTag(parameterObject, infos, artwork, removedArtwork, updatedDetails); // we need to manually remove tags/taglinks for now because they aren't replaced // due to scrapers not supporting them videodatabase.RemoveTagsFromItem(id, MediaTypeMusicVideo); if (videodatabase.SetDetailsForMusicVideo(infos.m_strFileNameAndPath, infos, artwork, id) <= 0) return InternalError; if (!videodatabase.RemoveArtForItem(infos.m_iDbId, MediaTypeMusicVideo, removedArtwork)) return InternalError; if (playcount != infos.GetPlayCount()|| lastPlayed != infos.m_lastPlayed) { // restore original playcount or the new one won't be announced int newPlaycount = infos.GetPlayCount(); infos.SetPlayCount(playcount); videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed); } UpdateResumePoint(parameterObject, infos, videodatabase); CJSONRPCUtils::NotifyItemUpdated(); return ACK; }