3 * Copyright (C) 2005-2013 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
21 #include "threads/Thread.h"
22 #include "VideoDatabase.h"
23 #include "addons/Scraper.h"
32 typedef struct SScanSettings
34 SScanSettings() { parent_name = parent_name_root = noupdate = exclude = false; recurse = 1;}
35 bool parent_name; /* use the parent dirname as name of lookup */
36 bool parent_name_root; /* use the name of directory where scan started as name for files in that dir */
37 int recurse; /* recurse into sub folders (indicate levels) */
38 bool noupdate; /* exclude from update library function */
39 bool exclude; /* exclude this path from scraping */
42 /*! \brief return values from the information lookup functions
44 enum INFO_RET { INFO_CANCELLED,
51 class CVideoInfoScanner : CThread
55 virtual ~CVideoInfoScanner();
57 /*! \brief Scan a folder using the background scanner
58 \param strDirectory path to scan
59 \param scanAll whether to scan everything not already scanned (regardless of whether the user normally doesn't want a folder scanned.) Defaults to false.
61 void Start(const CStdString& strDirectory, bool scanAll = false);
63 void CleanDatabase(CGUIDialogProgressBarHandle* handle=NULL, const std::set<int>* paths=NULL, bool showProgress=true);
66 //! \brief Set whether or not to show a progress dialog
67 void ShowDialog(bool show) { m_showDialog = show; }
69 /*! \brief Add an item to the database.
70 \param pItem item to add to the database.
71 \param content content type of the item.
72 \param videoFolder whether the video is represented by a folder (single movie per folder). Defaults to false.
73 \param useLocal whether to use local information for artwork etc.
74 \param showInfo pointer to CVideoInfoTag details for the show if this is an episode. Defaults to NULL.
75 \param libraryImport Whether this call belongs to a full library import or not. Defaults to false.
76 \return database id of the added item, or -1 on failure.
78 long AddVideo(CFileItem *pItem, const CONTENT_TYPE &content, bool videoFolder = false, bool useLocal = true, const CVideoInfoTag *showInfo = NULL, bool libraryImport = false);
80 /*! \brief Retrieve information for a list of items and add them to the database.
81 \param items list of items to retrieve info for.
82 \param bDirNames whether we should use folder or file names for lookups.
83 \param content type of content to retrieve.
84 \param useLocal should local data (.nfo and art) be used. Defaults to true.
85 \param pURL an optional URL to use to retrieve online info. Defaults to NULL.
86 \param fetchEpisodes whether we are fetching episodes with shows. Defaults to true.
87 \param pDlgProgress progress dialog to update and check for cancellation during processing. Defaults to NULL.
88 \return true if we successfully found information for some items, false otherwise
90 bool RetrieveVideoInfo(CFileItemList& items, bool bDirNames, CONTENT_TYPE content, bool useLocal = true, CScraperUrl *pURL = NULL, bool fetchEpisodes = true, CGUIDialogProgress* pDlgProgress = NULL);
92 static void ApplyThumbToFolder(const CStdString &folder, const CStdString &imdbThumb);
93 static bool DownloadFailed(CGUIDialogProgress* pDlgProgress);
94 CNfoFile::NFOResult CheckForNFOFile(CFileItem* pItem, bool bGrabAny, ADDON::ScraperPtr& scraper, CScraperUrl& scrUrl);
96 /*! \brief Retrieve any artwork associated with an item
97 \param pItem item to find artwork for.
98 \param content content type of the item.
99 \param bApplyToDir whether we should apply any thumbs to a folder. Defaults to false.
100 \param useLocal whether we should use local thumbs. Defaults to true.
101 \param actorArtPath the path to search for actor thumbs. Defaults to empty.
103 void GetArtwork(CFileItem *pItem, const CONTENT_TYPE &content, bool bApplyToDir=false, bool useLocal=true, const std::string &actorArtPath = "");
105 /*! \brief Retrieve the art type for an image from the given size.
106 \param width the width of the image.
107 \param height the height of the image.
108 \return "poster" if the aspect ratio is at most 4:5, "banner" if the aspect ratio
109 is at least 1:4, "thumb" otherwise.
111 static std::string GetArtTypeFromSize(unsigned int width, unsigned int height);
113 /*! \brief Get season thumbs for a tvshow.
114 All seasons (regardless of whether the user has episodes) are added to the art map.
115 \param show tvshow info tag
116 \param art artwork map to which season thumbs are added.
117 \param useLocal whether to use local thumbs, defaults to true
119 static void GetSeasonThumbs(const CVideoInfoTag &show, std::map<int, std::map<std::string, std::string> > &art, const std::vector<std::string> &artTypes, bool useLocal = true);
120 static std::string GetImage(CFileItem *pItem, bool useLocal, bool bApplyToDir, const std::string &type = "");
121 static std::string GetFanart(CFileItem *pItem, bool useLocal);
124 virtual void Process();
125 bool DoScan(const CStdString& strDirectory);
127 INFO_RET RetrieveInfoForTvShow(CFileItem *pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, bool fetchEpisodes, CGUIDialogProgress* pDlgProgress);
128 INFO_RET RetrieveInfoForMovie(CFileItem *pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress);
129 INFO_RET RetrieveInfoForMusicVideo(CFileItem *pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress);
130 INFO_RET RetrieveInfoForEpisodes(CFileItem *item, long showID, const ADDON::ScraperPtr &scraper, bool useLocal, CGUIDialogProgress *progress = NULL);
132 /*! \brief Update the progress bar with the heading and line and check for cancellation
133 \param progress CGUIDialogProgress bar
134 \param heading string id of heading
135 \param line1 string to set for the first line
136 \return true if the user has cancelled the scanner, false otherwise
138 bool ProgressCancelled(CGUIDialogProgress* progress, int heading, const CStdString &line1);
140 /*! \brief Find a url for the given video using the given scraper
141 \param videoName name of the video to lookup
142 \param scraper scraper to use for the lookup
143 \param url [out] returned url from the scraper
144 \param progress CGUIDialogProgress bar
145 \return >0 on success, <0 on failure (cancellation), and 0 on no info found
147 int FindVideo(const CStdString &videoName, const ADDON::ScraperPtr &scraper, CScraperUrl &url, CGUIDialogProgress *progress);
149 /*! \brief Retrieve detailed information for an item from an online source, optionally supplemented with local data
150 TODO: sort out some better return codes.
151 \param pItem item to retrieve online details for.
152 \param url URL to use to retrieve online details.
153 \param scraper Scraper that handles parsing the online data.
154 \param nfoFile if set, we override the online data with the locally supplied data. Defaults to NULL.
155 \param pDialog progress dialog to update and check for cancellation during processing. Defaults to NULL.
156 \return true if information is found, false if an error occurred, the lookup was cancelled, or no information was found.
158 bool GetDetails(CFileItem *pItem, CScraperUrl &url, const ADDON::ScraperPtr &scraper, CNfoFile *nfoFile=NULL, CGUIDialogProgress* pDialog=NULL);
160 /*! \brief Extract episode and season numbers from a processed regexp
161 \param reg Regular expression object with at least 2 matches
162 \param episodeInfo Episode information to fill in.
163 \param defaultSeason Season to use if not found in reg.
164 \return true on success (2 matches), false on failure (fewer than 2 matches)
166 bool GetEpisodeAndSeasonFromRegExp(CRegExp ®, EPISODE &episodeInfo, int defaultSeason);
168 /*! \brief Extract episode air-date from a processed regexp
169 \param reg Regular expression object with at least 3 matches
170 \param episodeInfo Episode information to fill in.
171 \return true on success (3 matches), false on failure (fewer than 3 matches)
173 bool GetAirDateFromRegExp(CRegExp ®, EPISODE &episodeInfo);
175 /*! \brief Fetch thumbs for actors
176 Updates each actor with their thumb (local or online)
177 \param actors - vector of SActorInfo
178 \param strPath - path on filesystem to look for local thumbs
180 void FetchActorThumbs(std::vector<SActorInfo>& actors, const CStdString& strPath);
182 static int GetPathHash(const CFileItemList &items, CStdString &hash);
184 /*! \brief Retrieve a "fast" hash of the given directory (if available)
185 Performs a stat() on the directory, and uses modified time to create a "fast"
186 hash of the folder. If no modified time is available, the create time is used,
187 and if neither are available, an empty hash is returned.
188 \param directory folder to hash
189 \return the hash of the folder of the form "fast<datetime>"
191 CStdString GetFastHash(const CStdString &directory) const;
193 /*! \brief Decide whether a folder listing could use the "fast" hash
194 Fast hashing can be done whenever the folder contains no scannable subfolders, as the
195 fast hash technique uses modified time to determine when folder content changes, which
196 is generally not propogated up the directory tree.
197 \param items the directory listing
198 \return true if this directory listing can be fast hashed, false otherwise
200 bool CanFastHash(const CFileItemList &items) const;
202 /*! \brief Process a series folder, filling in episode details and adding them to the database.
203 TODO: Ideally we would return INFO_HAVE_ALREADY if we don't have to update any episodes
204 and we should return INFO_NOT_FOUND only if no information is found for any of
205 the episodes. INFO_ADDED then indicates we've added one or more episodes.
206 \param files the episode files to process.
207 \param scraper scraper to use for finding online info
208 \param showInfo information for the show.
209 \param pDlgProcess progress dialog to update during processing. Defaults to NULL.
210 \return INFO_ERROR on failure, INFO_CANCELLED on cancellation,
211 INFO_NOT_FOUND if an episode isn't found, or INFO_ADDED if all episodes are added.
213 INFO_RET OnProcessSeriesFolder(EPISODELIST& files, const ADDON::ScraperPtr &scraper, bool useLocal, const CVideoInfoTag& showInfo, CGUIDialogProgress* pDlgProgress = NULL);
215 void EnumerateSeriesFolder(CFileItem* item, EPISODELIST& episodeList);
216 bool EnumerateEpisodeItem(const CFileItem *item, EPISODELIST& episodeList);
217 bool ProcessItemByVideoInfoTag(const CFileItem *item, EPISODELIST &episodeList);
219 CStdString GetnfoFile(CFileItem *item, bool bGrabAny=false) const;
221 /*! \brief Retrieve the parent folder of an item, accounting for stacks and files in rars.
222 \param item a media item.
223 \return the folder that contains the item.
225 CStdString GetParentDir(const CFileItem &item) const;
228 CGUIDialogProgressBarHandle* m_handle;
232 bool m_bCanInterrupt;
235 CStdString m_strStartDir;
236 CVideoDatabase m_database;
237 std::set<CStdString> m_pathsToScan;
238 std::set<CStdString> m_pathsToCount;
239 std::set<int> m_pathsToClean;
240 CNfoFile m_nfoReader;