2 * Copyright (C) 2005-2012 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/>.
22 #include "ScraperUrl.h"
23 #include "settings/AdvancedSettings.h"
25 #include "CharsetConverter.h"
27 #include "filesystem/CurlFile.h"
28 #include "filesystem/ZipFile.h"
36 CScraperUrl::CScraperUrl(const CStdString& strUrl)
42 CScraperUrl::CScraperUrl(const TiXmlElement* element)
45 ParseElement(element);
48 CScraperUrl::CScraperUrl()
53 CScraperUrl::~CScraperUrl()
57 void CScraperUrl::Clear()
65 bool CScraperUrl::Parse()
67 CStdString strToParse = m_xml;
69 return ParseString(strToParse);
72 bool CScraperUrl::ParseElement(const TiXmlElement* element)
74 if (!element || !element->FirstChild() ||
75 !element->FirstChild()->Value()) return false;
79 m_xml += stream.str();
82 url.m_url = element->FirstChild()->Value();
83 const char* pSpoof = element->Attribute("spoof");
86 const char* szPost=element->Attribute("post");
87 if (szPost && stricmp(szPost,"yes") == 0)
91 const char* szIsGz=element->Attribute("gzip");
92 if (szIsGz && stricmp(szIsGz,"yes") == 0)
96 const char* pCache = element->Attribute("cache");
100 const char* szType = element->Attribute("type");
101 url.m_type = URL_TYPE_GENERAL;
103 if (szType && stricmp(szType,"season") == 0)
105 url.m_type = URL_TYPE_SEASON;
106 const char* szSeason = element->Attribute("season");
108 url.m_season = atoi(szSeason);
110 const char *aspect = element->Attribute("aspect");
112 url.m_aspect = aspect;
114 m_url.push_back(url);
119 bool CScraperUrl::ParseString(CStdString strUrl)
121 if (strUrl.IsEmpty())
124 // ok, now parse the xml file
125 if (!XMLUtils::HasUTF8Declaration(strUrl))
126 g_charsetConverter.unknownToUTF8(strUrl);
129 doc.Parse(strUrl.c_str(),0,TIXML_ENCODING_UTF8);
131 TiXmlElement* pElement = doc.RootElement();
136 url.m_type = URL_TYPE_GENERAL;
140 m_url.push_back(url);
147 ParseElement(pElement);
148 pElement = pElement->NextSiblingElement(pElement->Value());
155 const CScraperUrl::SUrlEntry CScraperUrl::GetFirstThumb(const std::string &type) const
157 for (vector<SUrlEntry>::const_iterator iter=m_url.begin();iter != m_url.end();++iter)
159 if (iter->m_type == URL_TYPE_GENERAL && (type.empty() || type == "thumb" || iter->m_aspect == type))
164 result.m_type = URL_TYPE_GENERAL;
165 result.m_post = false;
166 result.m_isgz = false;
167 result.m_season = -1;
171 const CScraperUrl::SUrlEntry CScraperUrl::GetSeasonThumb(int season, const std::string &type) const
173 for (vector<SUrlEntry>::const_iterator iter=m_url.begin();iter != m_url.end();++iter)
175 if (iter->m_type == URL_TYPE_SEASON && iter->m_season == season &&
176 (type.empty() || type == "thumb" || iter->m_aspect == type))
181 result.m_type = URL_TYPE_GENERAL;
182 result.m_post = false;
183 result.m_isgz = false;
184 result.m_season = -1;
188 unsigned int CScraperUrl::GetMaxSeasonThumb() const
190 unsigned int maxSeason = 0;
191 for (vector<SUrlEntry>::const_iterator iter=m_url.begin();iter != m_url.end();++iter)
193 if (iter->m_type == URL_TYPE_SEASON && iter->m_season > 0 && (unsigned int)iter->m_season > maxSeason)
194 maxSeason = iter->m_season;
199 bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCurlFile& http, const CStdString& cacheContext)
201 CURL url(scrURL.m_url);
202 http.SetReferer(scrURL.m_spoof);
203 CStdString strCachePath;
206 http.SetContentEncoding("gzip");
208 if (!scrURL.m_cache.IsEmpty())
210 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
211 "scrapers/"+cacheContext+"/"+scrURL.m_cache,
213 if (XFILE::CFile::Exists(strCachePath))
216 if (file.Open(strCachePath))
218 char* temp = new char[(int)file.GetLength()];
219 file.Read(temp,file.GetLength());
221 strHTML.append(temp,temp+file.GetLength());
229 CStdString strHTML1(strHTML);
233 CStdString strOptions = url.GetOptions();
234 strOptions = strOptions.substr(1);
237 if (!http.Post(url.Get(), strOptions, strHTML1))
241 if (!http.Get(url.Get(), strHTML1))
246 if (scrURL.m_url.Find(".zip") > -1 )
248 XFILE::CZipFile file;
249 CStdString strBuffer;
250 int iSize = file.UnpackFromMemory(strBuffer,strHTML,scrURL.m_isgz);
254 strHTML.append(strBuffer.c_str(),strBuffer.data()+iSize);
258 if (!scrURL.m_cache.IsEmpty())
260 CStdString strCachePath;
261 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
262 "scrapers/"+cacheContext+"/"+scrURL.m_cache,
265 if (file.OpenForWrite(strCachePath,true))
266 file.Write(strHTML.data(),strHTML.size());
272 // XML format is of strUrls is:
273 // <TAG><url>...</url>...</TAG> (parsed by ParseElement) or <url>...</url> (ditto)
274 bool CScraperUrl::ParseEpisodeGuide(CStdString strUrls)
276 if (strUrls.IsEmpty())
279 // ok, now parse the xml file
280 if (!XMLUtils::HasUTF8Declaration(strUrls))
281 g_charsetConverter.unknownToUTF8(strUrls);
284 doc.Parse(strUrls.c_str(),0,TIXML_ENCODING_UTF8);
285 if (doc.RootElement())
287 TiXmlHandle docHandle( &doc );
288 TiXmlElement *link = docHandle.FirstChild("episodeguide").Element();
289 if (link->FirstChildElement("url"))
291 for (link = link->FirstChildElement("url"); link; link = link->NextSiblingElement("url"))
294 else if (link->FirstChild() && link->FirstChild()->Value())
303 CStdString CScraperUrl::GetThumbURL(const CScraperUrl::SUrlEntry &entry)
305 if (entry.m_spoof.IsEmpty())
307 CStdString spoof = entry.m_spoof;
309 return entry.m_url + "|Referer=" + spoof;
312 void CScraperUrl::GetThumbURLs(std::vector<CStdString> &thumbs, const std::string &type, int season) const
314 for (vector<SUrlEntry>::const_iterator iter = m_url.begin(); iter != m_url.end(); ++iter)
316 if (iter->m_aspect == type || type.empty() || type == "thumb" || iter->m_aspect.empty())
318 if ((iter->m_type == CScraperUrl::URL_TYPE_GENERAL && season == -1)
319 || (iter->m_type == CScraperUrl::URL_TYPE_SEASON && iter->m_season == season))
321 thumbs.push_back(GetThumbURL(*iter));