aboutsummaryrefslogtreecommitdiff
path: root/src/video/VideoInfoDownloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video/VideoInfoDownloader.cpp')
-rw-r--r--src/video/VideoInfoDownloader.cpp272
1 files changed, 272 insertions, 0 deletions
diff --git a/src/video/VideoInfoDownloader.cpp b/src/video/VideoInfoDownloader.cpp
new file mode 100644
index 0000000000..f33ac8a0db
--- /dev/null
+++ b/src/video/VideoInfoDownloader.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2005-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 "VideoInfoDownloader.h"
+#include "utils/XMLUtils.h"
+#include "utils/RegExp.h"
+#include "NfoFile.h"
+#include "dialogs/GUIDialogProgress.h"
+#include "dialogs/GUIDialogOK.h"
+#include "ApplicationMessenger.h"
+#include "guilib/GUIWindowManager.h"
+#include "guilib/LocalizeStrings.h"
+#include "utils/log.h"
+#include "utils/URIUtils.h"
+
+using namespace std;
+using namespace VIDEO;
+
+#ifndef __GNUC__
+#pragma warning (disable:4018)
+#endif
+
+CVideoInfoDownloader::CVideoInfoDownloader(const ADDON::ScraperPtr &scraper) :
+ CThread("VideoInfoDownloader"), m_state(DO_NOTHING), m_found(0), m_info(scraper)
+{
+ m_http = new XFILE::CCurlFile;
+}
+
+CVideoInfoDownloader::~CVideoInfoDownloader()
+{
+ delete m_http;
+}
+
+// return value: 0 = we failed, -1 = we failed and reported an error, 1 = success
+int CVideoInfoDownloader::InternalFindMovie(const CStdString &strMovie,
+ MOVIELIST& movielist,
+ bool cleanChars /* = true */)
+{
+ try
+ {
+ movielist = m_info->FindMovie(*m_http, strMovie, cleanChars);
+ }
+ catch (const ADDON::CScraperError &sce)
+ {
+ ShowErrorDialog(sce);
+ return sce.FAborted() ? 0 : -1;
+ }
+ return 1; // success
+}
+
+void CVideoInfoDownloader::ShowErrorDialog(const ADDON::CScraperError &sce)
+{
+ if (!sce.Title().empty())
+ {
+ CGUIDialogOK *pdlg = (CGUIDialogOK *)g_windowManager.GetWindow(WINDOW_DIALOG_OK);
+ pdlg->SetHeading(sce.Title());
+ pdlg->SetLine(0, sce.Message());
+ CApplicationMessenger::Get().DoModal(pdlg, WINDOW_DIALOG_OK);
+ }
+}
+
+// threaded functions
+void CVideoInfoDownloader::Process()
+{
+ // note here that we're calling our external functions but we're calling them with
+ // no progress bar set, so they're effectively calling our internal functions directly.
+ m_found = 0;
+ if (m_state == FIND_MOVIE)
+ {
+ if (!(m_found=FindMovie(m_strMovie, m_movieList)))
+ CLog::Log(LOGERROR, "%s: Error looking up item %s", __FUNCTION__, m_strMovie.c_str());
+ m_state = DO_NOTHING;
+ return;
+ }
+
+ if (m_url.m_url.empty())
+ {
+ // empty url when it's not supposed to be..
+ // this might happen if the previously scraped item was removed from the site (see ticket #10537)
+ CLog::Log(LOGERROR, "%s: Error getting details for %s due to an empty url", __FUNCTION__, m_strMovie.c_str());
+ }
+ else if (m_state == GET_DETAILS)
+ {
+ if (!GetDetails(m_url, m_movieDetails))
+ CLog::Log(LOGERROR, "%s: Error getting details from %s", __FUNCTION__,m_url.m_url[0].m_url.c_str());
+ }
+ else if (m_state == GET_EPISODE_DETAILS)
+ {
+ if (!GetEpisodeDetails(m_url, m_movieDetails))
+ CLog::Log(LOGERROR, "%s: Error getting episode details from %s", __FUNCTION__, m_url.m_url[0].m_url.c_str());
+ }
+ else if (m_state == GET_EPISODE_LIST)
+ {
+ if (!GetEpisodeList(m_url, m_episode))
+ CLog::Log(LOGERROR, "%s: Error getting episode list from %s", __FUNCTION__, m_url.m_url[0].m_url.c_str());
+ }
+ m_found = 1;
+ m_state = DO_NOTHING;
+}
+
+int CVideoInfoDownloader::FindMovie(const CStdString &strMovie,
+ MOVIELIST& movieList,
+ CGUIDialogProgress *pProgress /* = NULL */)
+{
+ //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::FindMovie(%s)", strMovie.c_str());
+
+ if (pProgress)
+ { // threaded version
+ m_state = FIND_MOVIE;
+ m_strMovie = strMovie;
+ m_found = 0;
+ if (IsRunning())
+ StopThread();
+ Create();
+ while (m_state != DO_NOTHING)
+ {
+ pProgress->Progress();
+ if (pProgress->IsCanceled())
+ {
+ CloseThread();
+ return 0;
+ }
+ Sleep(1);
+ }
+ // transfer to our movielist
+ m_movieList.swap(movieList);
+ int found=m_found;
+ CloseThread();
+ return found;
+ }
+
+ // unthreaded
+ int success = InternalFindMovie(strMovie, movieList);
+ // NOTE: this might be improved by rescraping if the match quality isn't high?
+ if (success == 1 && movieList.empty())
+ { // no results. try without cleaning chars like '.' and '_'
+ success = InternalFindMovie(strMovie, movieList, false);
+ }
+ return success;
+}
+
+bool CVideoInfoDownloader::GetDetails(const CScraperUrl &url,
+ CVideoInfoTag &movieDetails,
+ CGUIDialogProgress *pProgress /* = NULL */)
+{
+ //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails(%s)", url.m_strURL.c_str());
+ m_url = url;
+ m_movieDetails = movieDetails;
+
+ // fill in the defaults
+ movieDetails.Reset();
+ if (pProgress)
+ { // threaded version
+ m_state = GET_DETAILS;
+ m_found = 0;
+ if (IsRunning())
+ StopThread();
+ Create();
+ while (!m_found)
+ {
+ pProgress->Progress();
+ if (pProgress->IsCanceled())
+ {
+ CloseThread();
+ return false;
+ }
+ Sleep(1);
+ }
+ movieDetails = m_movieDetails;
+ CloseThread();
+ return true;
+ }
+ else // unthreaded
+ return m_info->GetVideoDetails(*m_http, url, true/*fMovie*/, movieDetails);
+}
+
+bool CVideoInfoDownloader::GetEpisodeDetails(const CScraperUrl &url,
+ CVideoInfoTag &movieDetails,
+ CGUIDialogProgress *pProgress /* = NULL */)
+{
+ //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails(%s)", url.m_strURL.c_str());
+ m_url = url;
+ m_movieDetails = movieDetails;
+
+ // fill in the defaults
+ movieDetails.Reset();
+ if (pProgress)
+ { // threaded version
+ m_state = GET_EPISODE_DETAILS;
+ m_found = 0;
+ if (IsRunning())
+ StopThread();
+ Create();
+ while (!m_found)
+ {
+ pProgress->Progress();
+ if (pProgress->IsCanceled())
+ {
+ CloseThread();
+ return false;
+ }
+ Sleep(1);
+ }
+ movieDetails = m_movieDetails;
+ CloseThread();
+ return true;
+ }
+ else // unthreaded
+ return m_info->GetVideoDetails(*m_http, url, false/*fMovie*/, movieDetails);
+}
+
+bool CVideoInfoDownloader::GetEpisodeList(const CScraperUrl& url,
+ EPISODELIST& movieDetails,
+ CGUIDialogProgress *pProgress /* = NULL */)
+{
+ //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails(%s)", url.m_strURL.c_str());
+ m_url = url;
+ m_episode = movieDetails;
+
+ // fill in the defaults
+ movieDetails.clear();
+ if (pProgress)
+ { // threaded version
+ m_state = GET_EPISODE_LIST;
+ m_found = 0;
+ if (IsRunning())
+ StopThread();
+ Create();
+ while (!m_found)
+ {
+ pProgress->Progress();
+ if (pProgress->IsCanceled())
+ {
+ CloseThread();
+ return false;
+ }
+ Sleep(1);
+ }
+ movieDetails = m_episode;
+ CloseThread();
+ return true;
+ }
+ else // unthreaded
+ return !(movieDetails = m_info->GetEpisodeList(*m_http, url)).empty();
+}
+
+void CVideoInfoDownloader::CloseThread()
+{
+ m_http->Cancel();
+ StopThread();
+ m_http->Reset();
+ m_state = DO_NOTHING;
+ m_found = 0;
+}
+