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"
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_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
,
74 if (!m_url
.HasUrls() && m_uniqueIDs
.empty())
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_uniqueIDs
, 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 std::unordered_map
<std::string
, std::string
>& uniqueIDs
,
151 const CScraperUrl
& url
,
152 CVideoInfoTag
& movieDetails
,
153 CGUIDialogProgress
* pProgress
/* = NULL */)
155 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails({})", url.m_strURL);
157 m_uniqueIDs
= uniqueIDs
;
158 m_movieDetails
= movieDetails
;
160 // fill in the defaults
161 movieDetails
.Reset();
163 { // threaded version
164 m_state
= GET_DETAILS
;
171 pProgress
->Progress();
172 if (pProgress
->IsCanceled())
179 movieDetails
= m_movieDetails
;
184 return m_info
->GetVideoDetails(*m_http
, m_uniqueIDs
, url
, true /*fMovie*/, movieDetails
);
187 bool CVideoInfoDownloader::GetEpisodeDetails(const CScraperUrl
&url
,
188 CVideoInfoTag
&movieDetails
,
189 CGUIDialogProgress
*pProgress
/* = NULL */)
191 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails({})", url.m_strURL);
193 m_movieDetails
= movieDetails
;
195 // fill in the defaults
196 movieDetails
.Reset();
198 { // threaded version
199 m_state
= GET_EPISODE_DETAILS
;
206 pProgress
->Progress();
207 if (pProgress
->IsCanceled())
214 movieDetails
= m_movieDetails
;
219 return m_info
->GetVideoDetails(*m_http
, m_uniqueIDs
, url
, false /*fMovie*/, movieDetails
);
222 bool CVideoInfoDownloader::GetEpisodeList(const CScraperUrl
& url
,
223 VIDEO::EPISODELIST
& movieDetails
,
224 CGUIDialogProgress
* pProgress
/* = NULL */)
226 //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails({})", url.m_strURL);
228 m_episode
= movieDetails
;
230 // fill in the defaults
231 movieDetails
.clear();
233 { // threaded version
234 m_state
= GET_EPISODE_LIST
;
241 pProgress
->Progress();
242 if (pProgress
->IsCanceled())
249 movieDetails
= m_episode
;
254 return !(movieDetails
= m_info
->GetEpisodeList(*m_http
, url
)).empty();
257 void CVideoInfoDownloader::CloseThread()
262 m_state
= DO_NOTHING
;