aboutsummaryrefslogtreecommitdiff
path: root/src/utils/SaveFileStateJob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/SaveFileStateJob.cpp')
-rw-r--r--src/utils/SaveFileStateJob.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/utils/SaveFileStateJob.cpp b/src/utils/SaveFileStateJob.cpp
new file mode 100644
index 0000000000..3be229bb38
--- /dev/null
+++ b/src/utils/SaveFileStateJob.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "SaveFileStateJob.h"
+#include "pvr/PVRManager.h"
+#include "pvr/recordings/PVRRecordings.h"
+#include "settings/MediaSettings.h"
+#include "network/upnp/UPnP.h"
+#include "StringUtils.h"
+#include "Variant.h"
+#include "URIUtils.h"
+#include "URL.h"
+#include "log.h"
+#include "video/VideoDatabase.h"
+#include "interfaces/AnnouncementManager.h"
+#include "Util.h"
+#include "guilib/GUIMessage.h"
+#include "guilib/GUIWindowManager.h"
+#include "GUIUserMessages.h"
+#include "music/MusicDatabase.h"
+
+bool CSaveFileStateJob::DoWork()
+{
+ std::string progressTrackingFile = m_item.GetPath();
+
+ if (m_item.HasVideoInfoTag() && StringUtils::StartsWith(m_item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://"))
+ progressTrackingFile = m_item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified
+ else if (m_item.HasProperty("original_listitem_url"))
+ {
+ // only use original_listitem_url for Python, UPnP and Bluray sources
+ std::string original = m_item.GetProperty("original_listitem_url").asString();
+ if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(m_item.GetPath()))
+ progressTrackingFile = original;
+ }
+
+ if (progressTrackingFile != "")
+ {
+#ifdef HAS_UPNP
+ // checks if UPnP server of this file is available and supports updating
+ if (URIUtils::IsUPnP(progressTrackingFile)
+ && UPNP::CUPnP::SaveFileState(m_item, m_bookmark, m_updatePlayCount)) {
+ return true;
+ }
+#endif
+ if (m_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
+ {
+ bool updateListing = false;
+ // No resume & watched status for livetv
+ if (!m_item.IsLiveTV())
+ {
+ if (m_updatePlayCount)
+ {
+ CLog::Log(LOGDEBUG, "%s - Marking video item %s as watched", __FUNCTION__, redactPath.c_str());
+
+ // consider this item as played
+ videodatabase.IncrementPlayCount(m_item);
+ m_item.GetVideoInfoTag()->m_playCount++;
+
+ // PVR: Set recording's play count on the backend (if supported)
+ if (m_item.HasPVRRecordingInfoTag())
+ m_item.GetPVRRecordingInfoTag()->IncrementPlayCount();
+
+ m_item.SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, true);
+ updateListing = true;
+ }
+ else
+ videodatabase.UpdateLastPlayed(m_item);
+
+ if (!m_item.HasVideoInfoTag() || m_item.GetVideoInfoTag()->m_resumePoint.timeInSeconds != m_bookmark.timeInSeconds)
+ {
+ if (m_bookmark.timeInSeconds <= 0.0f)
+ videodatabase.ClearBookMarksOfFile(progressTrackingFile, CBookmark::RESUME);
+ else
+ videodatabase.AddBookMarkToFile(progressTrackingFile, m_bookmark, CBookmark::RESUME);
+ if (m_item.HasVideoInfoTag())
+ m_item.GetVideoInfoTag()->m_resumePoint = m_bookmark;
+
+ // PVR: Set/clear recording's resume bookmark on the backend (if supported)
+ if (m_item.HasPVRRecordingInfoTag())
+ {
+ PVR::CPVRRecording *recording = m_item.GetPVRRecordingInfoTag();
+ recording->SetLastPlayedPosition(m_bookmark.timeInSeconds <= 0.0f ? 0 : (int)m_bookmark.timeInSeconds);
+ recording->m_resumePoint = m_bookmark;
+ }
+
+ // UPnP announce resume point changes to clients
+ // however not if playcount is modified as that already announces
+ if (m_item.IsVideoDb() && !m_updatePlayCount)
+ {
+ CVariant data;
+ data["id"] = m_item.GetVideoInfoTag()->m_iDbId;
+ data["type"] = m_item.GetVideoInfoTag()->m_type;
+ ANNOUNCEMENT::CAnnouncementManager::Get().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data);
+ }
+
+ updateListing = true;
+ }
+ }
+
+ if (m_videoSettings != CMediaSettings::Get().GetDefaultVideoSettings())
+ {
+ videodatabase.SetVideoSettings(progressTrackingFile, m_videoSettings);
+ }
+
+ if (m_item.HasVideoInfoTag() && m_item.GetVideoInfoTag()->HasStreamDetails())
+ {
+ CFileItem dbItem(m_item);
+
+ // Check whether the item's db streamdetails need updating
+ if (!videodatabase.GetStreamDetails(dbItem) || dbItem.GetVideoInfoTag()->m_streamDetails != m_item.GetVideoInfoTag()->m_streamDetails)
+ {
+ videodatabase.SetStreamDetailsForFile(m_item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile);
+ updateListing = true;
+ }
+ }
+
+ // in order to properly update the the list, we need to update the stack item which is held in g_application.m_stackFileItemToUpdate
+ if (m_item.HasProperty("stackFileItemToUpdate"))
+ {
+ m_item = m_item_discstack; // as of now, the item is replaced by the discstack item
+ videodatabase.GetResumePoint(*m_item.GetVideoInfoTag());
+ }
+ videodatabase.Close();
+
+ if (updateListing)
+ {
+ CUtil::DeleteVideoDatabaseDirectoryCache();
+ CFileItemPtr msgItem(new CFileItem(m_item));
+ if (m_item.HasProperty("original_listitem_url"))
+ msgItem->SetPath(m_item.GetProperty("original_listitem_url").asString());
+ CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE_ITEM, 1, msgItem); // 1 to update the listing as well
+ g_windowManager.SendThreadMessage(message);
+ }
+ }
+ }
+
+ if (m_item.IsAudio())
+ {
+ std::string redactPath = CURL::GetRedacted(progressTrackingFile);
+ CLog::Log(LOGDEBUG, "%s - Saving file state for audio item %s", __FUNCTION__, redactPath.c_str());
+
+ if (m_updatePlayCount)
+ {
+#if 0
+ // Can't write to the musicdatabase while scanning for music info
+ CGUIDialogMusicScan *dialog = (CGUIDialogMusicScan *)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN);
+ if (dialog && !dialog->IsDialogRunning())
+#endif
+ {
+ CMusicDatabase musicdatabase;
+ 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(m_item);
+ musicdatabase.Close();
+ }
+ }
+ }
+ }
+ }
+ return true;
+}