2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "VideoInfoDownloader.h"
11 #include "dialogs/GUIDialogProgress.h"
12 #include "filesystem/CurlFile.h"
13 #include "messaging/helpers/DialogOKHelper.h"
14 #include "utils/Variant.h"
15 #include "utils/log.h"
17 using namespace VIDEO
;
18 using namespace KODI::MESSAGING
;
19 using namespace std::chrono_literals
;
22 #pragma warning (disable:4018)
25 CVideoInfoDownloader::CVideoInfoDownloader(const ADDON::ScraperPtr
&scraper
) :
26 CThread("VideoInfoDownloader"), m_state(DO_NOTHING
), m_found(0), m_info(scraper
)
28 m_http
= new XFILE::CCurlFile
;
31 CVideoInfoDownloader::~CVideoInfoDownloader()
36 // return value: 0 = we failed, -1 = we failed and reported an error, 1 = success
37 int CVideoInfoDownloader::InternalFindMovie(const std::string
&movieTitle
, int movieYear
,
39 bool cleanChars
/* = true */)
43 movielist
= m_info
->FindMovie(*m_http
, movieTitle
, movieYear
, cleanChars
);
45 catch (const ADDON::CScraperError
&sce
)
48 return sce
.FAborted() ? 0 : -1;
53 void CVideoInfoDownloader::ShowErrorDialog(const ADDON::CScraperError
&sce
)
55 if (!sce
.Title().empty())
56 HELPERS::ShowOKDialogText(CVariant
{ sce
.Title() }, CVariant
{ sce
.Message() });
60 void CVideoInfoDownloader::Process()
62 // note here that we're calling our external functions but we're calling them with
63 // no progress bar set, so they're effectively calling our internal functions directly.
65 if (m_state
== FIND_MOVIE
)
67 if (!(m_found
=FindMovie(m_movieTitle
, m_movieYear
, m_movieList
)))
68 CLog::Log(LOGERROR
, "{}: Error looking up item {} ({})", __FUNCTION__
, m_movieTitle
,
76 // empty url when it's not supposed to be..
77 // this might happen if the previously scraped item was removed from the site (see ticket #10537)
78 CLog::Log(LOGERROR
, "{}: Error getting details for {} ({}) due to an empty url", __FUNCTION__
,
79 m_movieTitle
, m_movieYear
);
81 else if (m_state
== GET_DETAILS
)
83 if (!GetDetails(m_url
, m_movieDetails
))
84 CLog::Log(LOGERROR
, "{}: Error getting details from {}", __FUNCTION__
,
85 m_url
.GetFirstThumbUrl());
87 else if (m_state
== GET_EPISODE_DETAILS
)
89 if (!GetEpisodeDetails(m_url
, m_movieDetails
))
90 CLog::Log(LOGERROR
, "{}: Error getting episode details from {}", __FUNCTION__
,
91 m_url
.GetFirstThumbUrl());
93 else if (m_state
== GET_EPISODE_LIST
)
95 if (!GetEpisodeList(m_url
, m_episode
))
96 CLog::Log(LOGERROR
, "{}: Error getting episode list from {}", __FUNCTION__
,
97 m_url
.GetFirstThumbUrl());
100 m_state
= DO_NOTHING
;
103 int CVideoInfoDownloader::FindMovie(const std::string
&movieTitle
, int movieYear
,
104 MOVIELIST
& movieList
,
105 CGUIDialogProgress
*pProgress
/* = NULL */)
107 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::FindMovie({})", strMovie);
110 { // threaded version
111 m_state
= FIND_MOVIE
;
112 m_movieTitle
= movieTitle
;
113 m_movieYear
= movieYear
;
118 while (m_state
!= DO_NOTHING
)
120 pProgress
->Progress();
121 if (pProgress
->IsCanceled())
128 // transfer to our movielist
129 m_movieList
.swap(movieList
);
136 int success
= InternalFindMovie(movieTitle
, movieYear
, movieList
);
137 // NOTE: this might be improved by rescraping if the match quality isn't high?
138 if (success
== 1 && movieList
.empty())
139 { // no results. try without cleaning chars like '.' and '_'
140 success
= InternalFindMovie(movieTitle
, movieYear
, movieList
, false);
145 bool CVideoInfoDownloader::GetArtwork(CVideoInfoTag
&details
)
147 return m_info
->GetArtwork(*m_http
, details
);
150 bool CVideoInfoDownloader::GetDetails(const CScraperUrl
&url
,
151 CVideoInfoTag
&movieDetails
,
152 CGUIDialogProgress
*pProgress
/* = NULL */)
154 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails({})", url.m_strURL);
156 m_movieDetails
= movieDetails
;
158 // fill in the defaults
159 movieDetails
.Reset();
161 { // threaded version
162 m_state
= GET_DETAILS
;
169 pProgress
->Progress();
170 if (pProgress
->IsCanceled())
177 movieDetails
= m_movieDetails
;
182 return m_info
->GetVideoDetails(*m_http
, url
, true/*fMovie*/, movieDetails
);
185 bool CVideoInfoDownloader::GetEpisodeDetails(const CScraperUrl
&url
,
186 CVideoInfoTag
&movieDetails
,
187 CGUIDialogProgress
*pProgress
/* = NULL */)
189 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails({})", url.m_strURL);
191 m_movieDetails
= movieDetails
;
193 // fill in the defaults
194 movieDetails
.Reset();
196 { // threaded version
197 m_state
= GET_EPISODE_DETAILS
;
204 pProgress
->Progress();
205 if (pProgress
->IsCanceled())
212 movieDetails
= m_movieDetails
;
217 return m_info
->GetVideoDetails(*m_http
, url
, false/*fMovie*/, movieDetails
);
220 bool CVideoInfoDownloader::GetEpisodeList(const CScraperUrl
& url
,
221 EPISODELIST
& movieDetails
,
222 CGUIDialogProgress
*pProgress
/* = NULL */)
224 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails({})", url.m_strURL);
226 m_episode
= movieDetails
;
228 // fill in the defaults
229 movieDetails
.clear();
231 { // threaded version
232 m_state
= GET_EPISODE_LIST
;
239 pProgress
->Progress();
240 if (pProgress
->IsCanceled())
247 movieDetails
= m_episode
;
252 return !(movieDetails
= m_info
->GetEpisodeList(*m_http
, url
)).empty();
255 void CVideoInfoDownloader::CloseThread()
260 m_state
= DO_NOTHING
;