2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "VideoInfoDownloader.h"
22 #include "utils/XMLUtils.h"
23 #include "utils/RegExp.h"
25 #include "dialogs/GUIDialogProgress.h"
26 #include "dialogs/GUIDialogOK.h"
27 #include "ApplicationMessenger.h"
28 #include "guilib/GUIWindowManager.h"
29 #include "guilib/LocalizeStrings.h"
30 #include "utils/log.h"
31 #include "utils/URIUtils.h"
34 using namespace VIDEO;
37 #pragma warning (disable:4018)
40 CVideoInfoDownloader::CVideoInfoDownloader(const ADDON::ScraperPtr &scraper) :
41 CThread("VideoInfoDownloader"), m_state(DO_NOTHING), m_found(0), m_info(scraper)
43 m_http = new XFILE::CCurlFile;
46 CVideoInfoDownloader::~CVideoInfoDownloader()
51 // return value: 0 = we failed, -1 = we failed and reported an error, 1 = success
52 int CVideoInfoDownloader::InternalFindMovie(const CStdString &strMovie,
54 bool cleanChars /* = true */)
58 movielist = m_info->FindMovie(*m_http, strMovie, cleanChars);
60 catch (const ADDON::CScraperError &sce)
63 return sce.FAborted() ? 0 : -1;
68 void CVideoInfoDownloader::ShowErrorDialog(const ADDON::CScraperError &sce)
70 if (!sce.Title().empty())
72 CGUIDialogOK *pdlg = (CGUIDialogOK *)g_windowManager.GetWindow(WINDOW_DIALOG_OK);
73 pdlg->SetHeading(sce.Title());
74 pdlg->SetLine(0, sce.Message());
75 CApplicationMessenger::Get().DoModal(pdlg, WINDOW_DIALOG_OK);
80 void CVideoInfoDownloader::Process()
82 // note here that we're calling our external functions but we're calling them with
83 // no progress bar set, so they're effectively calling our internal functions directly.
85 if (m_state == FIND_MOVIE)
87 if (!(m_found=FindMovie(m_strMovie, m_movieList)))
88 CLog::Log(LOGERROR, "%s: Error looking up item %s", __FUNCTION__, m_strMovie.c_str());
93 if (m_url.m_url.empty())
95 // empty url when it's not supposed to be..
96 // this might happen if the previously scraped item was removed from the site (see ticket #10537)
97 CLog::Log(LOGERROR, "%s: Error getting details for %s due to an empty url", __FUNCTION__, m_strMovie.c_str());
99 else if (m_state == GET_DETAILS)
101 if (!GetDetails(m_url, m_movieDetails))
102 CLog::Log(LOGERROR, "%s: Error getting details from %s", __FUNCTION__,m_url.m_url[0].m_url.c_str());
104 else if (m_state == GET_EPISODE_DETAILS)
106 if (!GetEpisodeDetails(m_url, m_movieDetails))
107 CLog::Log(LOGERROR, "%s: Error getting episode details from %s", __FUNCTION__, m_url.m_url[0].m_url.c_str());
109 else if (m_state == GET_EPISODE_LIST)
111 if (!GetEpisodeList(m_url, m_episode))
112 CLog::Log(LOGERROR, "%s: Error getting episode list from %s", __FUNCTION__, m_url.m_url[0].m_url.c_str());
115 m_state = DO_NOTHING;
118 int CVideoInfoDownloader::FindMovie(const CStdString &strMovie,
119 MOVIELIST& movieList,
120 CGUIDialogProgress *pProgress /* = NULL */)
122 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::FindMovie(%s)", strMovie.c_str());
125 { // threaded version
126 m_state = FIND_MOVIE;
127 m_strMovie = strMovie;
132 while (m_state != DO_NOTHING)
134 pProgress->Progress();
135 if (pProgress->IsCanceled())
142 // transfer to our movielist
143 m_movieList.swap(movieList);
150 int success = InternalFindMovie(strMovie, movieList);
151 // NOTE: this might be improved by rescraping if the match quality isn't high?
152 if (success == 1 && movieList.empty())
153 { // no results. try without cleaning chars like '.' and '_'
154 success = InternalFindMovie(strMovie, movieList, false);
159 bool CVideoInfoDownloader::GetDetails(const CScraperUrl &url,
160 CVideoInfoTag &movieDetails,
161 CGUIDialogProgress *pProgress /* = NULL */)
163 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails(%s)", url.m_strURL.c_str());
165 m_movieDetails = movieDetails;
167 // fill in the defaults
168 movieDetails.Reset();
170 { // threaded version
171 m_state = GET_DETAILS;
178 pProgress->Progress();
179 if (pProgress->IsCanceled())
186 movieDetails = m_movieDetails;
191 return m_info->GetVideoDetails(*m_http, url, true/*fMovie*/, movieDetails);
194 bool CVideoInfoDownloader::GetEpisodeDetails(const CScraperUrl &url,
195 CVideoInfoTag &movieDetails,
196 CGUIDialogProgress *pProgress /* = NULL */)
198 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails(%s)", url.m_strURL.c_str());
200 m_movieDetails = movieDetails;
202 // fill in the defaults
203 movieDetails.Reset();
205 { // threaded version
206 m_state = GET_EPISODE_DETAILS;
213 pProgress->Progress();
214 if (pProgress->IsCanceled())
221 movieDetails = m_movieDetails;
226 return m_info->GetVideoDetails(*m_http, url, false/*fMovie*/, movieDetails);
229 bool CVideoInfoDownloader::GetEpisodeList(const CScraperUrl& url,
230 EPISODELIST& movieDetails,
231 CGUIDialogProgress *pProgress /* = NULL */)
233 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails(%s)", url.m_strURL.c_str());
235 m_episode = movieDetails;
237 // fill in the defaults
238 movieDetails.clear();
240 { // threaded version
241 m_state = GET_EPISODE_LIST;
248 pProgress->Progress();
249 if (pProgress->IsCanceled())
256 movieDetails = m_episode;
261 return !(movieDetails = m_info->GetEpisodeList(*m_http, url)).empty();
264 void CVideoInfoDownloader::CloseThread()
269 m_state = DO_NOTHING;