1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "XBDateTime.h"
12 #include "addons/Addon.h"
13 #include "utils/ScraperParser.h"
14 #include "utils/ScraperUrl.h"
15 #include "video/Episode.h"
16 
17 #include <memory>
18 #include <string>
19 #include <vector>
20 
21 class CAlbum;
22 class CArtist;
23 class CVideoInfoTag;
24 
25 namespace MUSIC_GRABBER
26 {
27 class CMusicAlbumInfo;
28 class CMusicArtistInfo;
29 }
30 
31 typedef enum
32 {
33   CONTENT_MOVIES,
34   CONTENT_TVSHOWS,
35   CONTENT_MUSICVIDEOS,
36   CONTENT_ALBUMS,
37   CONTENT_ARTISTS,
38   CONTENT_NONE,
39 } CONTENT_TYPE;
40 
41 namespace XFILE
42 {
43   class CCurlFile;
44 }
45 
46 class CScraperUrl;
47 
48 namespace ADDON
49 {
50 class CScraper;
51 typedef std::shared_ptr<CScraper> ScraperPtr;
52 
53 std::string TranslateContent(const CONTENT_TYPE &content, bool pretty=false);
54 CONTENT_TYPE TranslateContent(const std::string &string);
55 TYPE ScraperTypeFromContent(const CONTENT_TYPE &content);
56 
57 // thrown as exception to signal abort or show error dialog
58 class CScraperError
59 {
60 public:
61   CScraperError() = default;
CScraperError(const std::string & sTitle,const std::string & sMessage)62   CScraperError(const std::string &sTitle, const std::string &sMessage) :
63     m_fAborted(false), m_sTitle(sTitle), m_sMessage(sMessage) {}
64 
FAborted()65   bool FAborted() const { return m_fAborted; }
Title()66   const std::string &Title() const { return m_sTitle; }
Message()67   const std::string &Message() const { return m_sMessage; }
68 
69 private:
70   bool m_fAborted = true;
71   std::string m_sTitle;
72   std::string m_sMessage;
73 };
74 
75 class CScraper : public CAddon
76 {
77 public:
78   explicit CScraper(const AddonInfoPtr& addonInfo, TYPE addonType);
79 
80   /*! \brief Set the scraper settings for a particular path from an XML string
81    Loads the default and user settings (if not already loaded) and, if the given XML string is non-empty,
82    overrides the user settings with the XML.
83    \param content Content type of the path
84    \param xml string of XML with the settings.  If non-empty this overrides any saved user settings.
85    \return true if settings are available, false otherwise
86    \sa GetPathSettings
87    */
88   bool SetPathSettings(CONTENT_TYPE content, const std::string& xml);
89 
90   /*! \brief Get the scraper settings for a particular path in the form of an XML string
91    Loads the default and user settings (if not already loaded) and returns the user settings in the
92    form or an XML string
93    \return a string containing the XML settings
94    \sa SetPathSettings
95    */
96   std::string GetPathSettings();
97 
98   /*! \brief Clear any previously cached results for this scraper
99    Any previously cached files are cleared if they have been cached for longer than the specified
100    cachepersistence.
101    */
102   void ClearCache();
103 
Content()104   CONTENT_TYPE Content() const { return m_pathContent; }
RequiresSettings()105   bool RequiresSettings() const { return m_requiressettings; }
106   bool Supports(const CONTENT_TYPE &content) const;
107 
108   bool IsInUse() const override;
109   bool IsNoop();
IsPython()110   bool IsPython() const { return m_isPython; }
111 
112   // scraper media functions
113   CScraperUrl NfoUrl(const std::string &sNfoContent);
114 
115   /*! \brief Resolve an external ID (e.g. MusicBrainz IDs) to a URL using scrapers
116    If we have an ID in hand, e.g. MusicBrainz IDs or TheTVDB Season IDs
117    we can get directly to a URL instead of searching by name and choosing from
118    the search results. The correct scraper type should be used to get the right
119    URL for a given ID, so we can differentiate albums, artists, TV Seasons, etc.
120    \param externalID the external ID - e.g. MusicBrainzArtist/AlbumID
121    \return a populated URL pointing to the details page for the given ID or
122            an empty URL if we couldn't resolve the ID.
123    */
124   CScraperUrl ResolveIDToUrl(const std::string &externalID);
125 
126   std::vector<CScraperUrl> FindMovie(XFILE::CCurlFile &fcurl,
127     const std::string &movieTitle, int movieYear, bool fFirst);
128   std::vector<MUSIC_GRABBER::CMusicAlbumInfo> FindAlbum(XFILE::CCurlFile &fcurl,
129     const std::string &sAlbum, const std::string &sArtist = "");
130   std::vector<MUSIC_GRABBER::CMusicArtistInfo> FindArtist(
131     XFILE::CCurlFile &fcurl, const std::string &sArtist);
132   VIDEO::EPISODELIST GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl);
133 
134   bool GetVideoDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl,
135     bool fMovie/*else episode*/, CVideoInfoTag &video);
136   bool GetAlbumDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl,
137     CAlbum &album);
138   bool GetArtistDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl,
139     const std::string &sSearch, CArtist &artist);
140   bool GetArtwork(XFILE::CCurlFile &fcurl, CVideoInfoTag &details);
141 
142 private:
143   CScraper(const CScraper &rhs) = delete;
144   CScraper& operator=(const CScraper&) = delete;
145   CScraper(CScraper&&) = delete;
146   CScraper& operator=(CScraper&&) = delete;
147 
SearchStringEncoding()148   std::string SearchStringEncoding() const
149     { return m_parser.GetSearchStringEncoding(); }
150 
151   /*! \brief Get the scraper settings for a particular path in the form of a JSON string
152    Loads the default and user settings (if not already loaded) and returns the user settings in the
153    form of an JSON string. It is used in Python scrapers.
154    \return a string containing the JSON settings
155    \sa SetPathSettings
156    */
157   std::string GetPathSettingsAsJSON();
158 
159   bool Load();
160   std::vector<std::string> Run(const std::string& function,
161                               const CScraperUrl& url,
162                               XFILE::CCurlFile& http,
163                               const std::vector<std::string>* extras = NULL);
164   std::vector<std::string> RunNoThrow(const std::string& function,
165                               const CScraperUrl& url,
166                               XFILE::CCurlFile& http,
167                               const std::vector<std::string>* extras = NULL);
168   std::string InternalRun(const std::string& function,
169                          const CScraperUrl& url,
170                          XFILE::CCurlFile& http,
171                          const std::vector<std::string>* extras);
172 
173   bool m_fLoaded;
174   bool m_isPython = false;
175   bool m_requiressettings;
176   CDateTimeSpan m_persistence;
177   CONTENT_TYPE m_pathContent;
178   CScraperParser m_parser;
179 };
180 
181 }
182 
183