[videodb] Remove nested transaction when saving state after stopping PVR playback
[xbmc.git] / xbmc / filesystem / VideoDatabaseDirectory.cpp
blob0afa2986ddc2ba0acf3206a3f92f2de345dbc21d
1 /*
2 * Copyright (C) 2016-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.
7 */
9 #include "VideoDatabaseDirectory.h"
11 #include "File.h"
12 #include "FileItem.h"
13 #include "FileItemList.h"
14 #include "ServiceBroker.h"
15 #include "VideoDatabaseDirectory/QueryParams.h"
16 #include "guilib/LocalizeStrings.h"
17 #include "guilib/TextureManager.h"
18 #include "settings/Settings.h"
19 #include "settings/SettingsComponent.h"
20 #include "utils/Crc32.h"
21 #include "utils/LegacyPathTranslation.h"
22 #include "utils/StringUtils.h"
23 #include "utils/URIUtils.h"
24 #include "video/VideoDatabase.h"
26 using namespace XFILE;
27 using namespace VIDEODATABASEDIRECTORY;
29 CVideoDatabaseDirectory::CVideoDatabaseDirectory(void) = default;
31 CVideoDatabaseDirectory::~CVideoDatabaseDirectory(void) = default;
33 namespace
35 std::string GetChildContentType(const std::unique_ptr<CDirectoryNode>& node)
37 switch (node->GetChildType())
39 case NODE_TYPE_EPISODES:
40 case NODE_TYPE_RECENTLY_ADDED_EPISODES:
41 return "episodes";
42 case NODE_TYPE_SEASONS:
43 return "seasons";
44 case NODE_TYPE_TITLE_MOVIES:
45 case NODE_TYPE_RECENTLY_ADDED_MOVIES:
46 return "movies";
47 case NODE_TYPE_TITLE_TVSHOWS:
48 case NODE_TYPE_INPROGRESS_TVSHOWS:
49 return "tvshows";
50 case NODE_TYPE_TITLE_MUSICVIDEOS:
51 case NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS:
52 return "musicvideos";
53 case NODE_TYPE_GENRE:
54 return "genres";
55 case NODE_TYPE_COUNTRY:
56 return "countries";
57 case NODE_TYPE_ACTOR:
59 CQueryParams params;
60 node->CollectQueryParams(params);
61 if (static_cast<VideoDbContentType>(params.GetContentType()) ==
62 VideoDbContentType::MUSICVIDEOS)
63 return "artists";
65 return "actors";
67 case NODE_TYPE_DIRECTOR:
68 return "directors";
69 case NODE_TYPE_STUDIO:
70 return "studios";
71 case NODE_TYPE_YEAR:
72 return "years";
73 case NODE_TYPE_MUSICVIDEOS_ALBUM:
74 return "albums";
75 case NODE_TYPE_SETS:
76 return "sets";
77 case NODE_TYPE_TAGS:
78 return "tags";
79 case NODE_TYPE_VIDEOVERSIONS:
80 return "videoversions";
81 default:
82 break;
84 return {};
87 } // unnamed namespace
89 bool CVideoDatabaseDirectory::GetDirectory(const CURL& url, CFileItemList &items)
91 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(url);
92 items.SetPath(path);
93 items.m_dwSize = -1; // No size
94 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
96 if (!pNode)
97 return false;
99 bool bResult = pNode->GetChilds(items);
100 for (int i=0;i<items.Size();++i)
102 CFileItemPtr item = items[i];
103 if (item->m_bIsFolder && !item->HasArt("icon") && !item->HasArt("thumb"))
105 std::string strImage = GetIcon(item->GetPath());
106 if (!strImage.empty() && CServiceBroker::GetGUI()->GetTextureManager().HasTexture(strImage))
107 item->SetArt("icon", strImage);
109 if (item->HasVideoInfoTag())
111 item->SetDynPath(item->GetVideoInfoTag()->GetPath());
114 if (items.HasProperty("customtitle"))
115 items.SetLabel(items.GetProperty("customtitle").asString());
116 else
117 items.SetLabel(pNode->GetLocalizedName());
119 items.SetContent(GetChildContentType(pNode));
121 return bResult;
124 NODE_TYPE CVideoDatabaseDirectory::GetDirectoryChildType(const std::string& strPath)
126 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strPath);
127 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
129 if (!pNode)
130 return NODE_TYPE_NONE;
132 return pNode->GetChildType();
135 NODE_TYPE CVideoDatabaseDirectory::GetDirectoryType(const std::string& strPath)
137 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strPath);
138 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
140 if (!pNode)
141 return NODE_TYPE_NONE;
143 return pNode->GetType();
146 NODE_TYPE CVideoDatabaseDirectory::GetDirectoryParentType(const std::string& strPath)
148 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strPath);
149 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
151 if (!pNode)
152 return NODE_TYPE_NONE;
154 CDirectoryNode* pParentNode=pNode->GetParent();
156 if (!pParentNode)
157 return NODE_TYPE_NONE;
159 return pParentNode->GetChildType();
162 bool CVideoDatabaseDirectory::GetQueryParams(const std::string& strPath, CQueryParams& params)
164 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strPath);
165 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
167 if (!pNode)
168 return false;
170 CDirectoryNode::GetDatabaseInfo(strPath,params);
171 return true;
174 void CVideoDatabaseDirectory::ClearDirectoryCache(const std::string& strDirectory)
176 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strDirectory);
177 URIUtils::RemoveSlashAtEnd(path);
179 uint32_t crc = Crc32::ComputeFromLowerCase(path);
181 std::string strFileName = StringUtils::Format("special://temp/archive_cache/{:08x}.fi", crc);
182 CFile::Delete(strFileName);
185 bool CVideoDatabaseDirectory::IsAllItem(const std::string& strDirectory)
187 if (StringUtils::EndsWith(strDirectory, "/-1/"))
188 return true;
189 return false;
192 bool CVideoDatabaseDirectory::GetLabel(const std::string& strDirectory, std::string& strLabel)
194 strLabel = "";
196 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strDirectory);
197 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
198 if (!pNode || path.empty())
199 return false;
201 // first see if there's any filter criteria
202 CQueryParams params;
203 CDirectoryNode::GetDatabaseInfo(path, params);
205 CVideoDatabase videodatabase;
206 if (!videodatabase.Open())
207 return false;
209 // get genre
210 if (params.GetGenreId() != -1)
211 strLabel += videodatabase.GetGenreById(params.GetGenreId());
213 // get country
214 if (params.GetCountryId() != -1)
215 strLabel += videodatabase.GetCountryById(params.GetCountryId());
217 // get set
218 if (params.GetSetId() != -1)
219 strLabel += videodatabase.GetSetById(params.GetSetId());
221 // get tag
222 if (params.GetTagId() != -1)
223 strLabel += videodatabase.GetTagById(params.GetTagId());
225 // get year
226 if (params.GetYear() != -1)
228 std::string strTemp = std::to_string(params.GetYear());
229 if (!strLabel.empty())
230 strLabel += " / ";
231 strLabel += strTemp;
234 // get videoversions
235 if (params.GetVideoVersionId() != -1)
236 strLabel += videodatabase.GetVideoVersionById(params.GetVideoVersionId());
238 if (strLabel.empty())
240 switch (pNode->GetChildType())
242 case NODE_TYPE_TITLE_MOVIES:
243 case NODE_TYPE_TITLE_TVSHOWS:
244 case NODE_TYPE_TITLE_MUSICVIDEOS:
245 strLabel = g_localizeStrings.Get(369); break;
246 case NODE_TYPE_ACTOR: // Actor
247 strLabel = g_localizeStrings.Get(344); break;
248 case NODE_TYPE_GENRE: // Genres
249 strLabel = g_localizeStrings.Get(135); break;
250 case NODE_TYPE_COUNTRY: // Countries
251 strLabel = g_localizeStrings.Get(20451); break;
252 case NODE_TYPE_YEAR: // Year
253 strLabel = g_localizeStrings.Get(562); break;
254 case NODE_TYPE_DIRECTOR: // Director
255 strLabel = g_localizeStrings.Get(20348); break;
256 case NODE_TYPE_SETS: // Sets
257 strLabel = g_localizeStrings.Get(20434); break;
258 case NODE_TYPE_TAGS: // Tags
259 strLabel = g_localizeStrings.Get(20459); break;
260 case NODE_TYPE_VIDEOVERSIONS: // Video versions
261 strLabel = g_localizeStrings.Get(40000);
262 break;
263 case NODE_TYPE_MOVIES_OVERVIEW: // Movies
264 strLabel = g_localizeStrings.Get(342); break;
265 case NODE_TYPE_TVSHOWS_OVERVIEW: // TV Shows
266 strLabel = g_localizeStrings.Get(20343); break;
267 case NODE_TYPE_RECENTLY_ADDED_MOVIES: // Recently Added Movies
268 strLabel = g_localizeStrings.Get(20386); break;
269 case NODE_TYPE_RECENTLY_ADDED_EPISODES: // Recently Added Episodes
270 strLabel = g_localizeStrings.Get(20387); break;
271 case NODE_TYPE_STUDIO: // Studios
272 strLabel = g_localizeStrings.Get(20388); break;
273 case NODE_TYPE_MUSICVIDEOS_OVERVIEW: // Music Videos
274 strLabel = g_localizeStrings.Get(20389); break;
275 case NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS: // Recently Added Music Videos
276 strLabel = g_localizeStrings.Get(20390); break;
277 case NODE_TYPE_SEASONS: // Seasons
278 strLabel = g_localizeStrings.Get(33054); break;
279 case NODE_TYPE_EPISODES: // Episodes
280 strLabel = g_localizeStrings.Get(20360); break;
281 case NODE_TYPE_INPROGRESS_TVSHOWS: // InProgress TvShows
282 strLabel = g_localizeStrings.Get(626); break;
283 default:
284 return false;
288 return true;
291 std::string CVideoDatabaseDirectory::GetIcon(const std::string &strDirectory)
293 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strDirectory);
294 switch (GetDirectoryChildType(path))
296 case NODE_TYPE_TITLE_MOVIES:
297 if (URIUtils::PathEquals(path, "videodb://movies/titles/"))
299 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_FLATTEN))
300 return "DefaultMovies.png";
301 return "DefaultMovieTitle.png";
303 return "";
304 case NODE_TYPE_TITLE_TVSHOWS:
305 if (URIUtils::PathEquals(path, "videodb://tvshows/titles/"))
307 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_FLATTEN))
308 return "DefaultTVShows.png";
309 return "DefaultTVShowTitle.png";
311 return "";
312 case NODE_TYPE_TITLE_MUSICVIDEOS:
313 if (URIUtils::PathEquals(path, "videodb://musicvideos/titles/"))
315 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_FLATTEN))
316 return "DefaultMusicVideos.png";
317 return "DefaultMusicVideoTitle.png";
319 return "";
320 case NODE_TYPE_ACTOR: // Actor
321 return "DefaultActor.png";
322 case NODE_TYPE_GENRE: // Genres
323 return "DefaultGenre.png";
324 case NODE_TYPE_COUNTRY: // Countries
325 return "DefaultCountry.png";
326 case NODE_TYPE_SETS: // Sets
327 return "DefaultSets.png";
328 case NODE_TYPE_TAGS: // Tags
329 return "DefaultTags.png";
330 case NODE_TYPE_VIDEOVERSIONS: // Video versions
331 return "DefaultVideoVersions.png";
332 case NODE_TYPE_YEAR: // Year
333 return "DefaultYear.png";
334 case NODE_TYPE_DIRECTOR: // Director
335 return "DefaultDirector.png";
336 case NODE_TYPE_MOVIES_OVERVIEW: // Movies
337 return "DefaultMovies.png";
338 case NODE_TYPE_TVSHOWS_OVERVIEW: // TV Shows
339 return "DefaultTVShows.png";
340 case NODE_TYPE_RECENTLY_ADDED_MOVIES: // Recently Added Movies
341 return "DefaultRecentlyAddedMovies.png";
342 case NODE_TYPE_RECENTLY_ADDED_EPISODES: // Recently Added Episodes
343 return "DefaultRecentlyAddedEpisodes.png";
344 case NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS: // Recently Added Episodes
345 return "DefaultRecentlyAddedMusicVideos.png";
346 case NODE_TYPE_INPROGRESS_TVSHOWS: // InProgress TvShows
347 return "DefaultInProgressShows.png";
348 case NODE_TYPE_STUDIO: // Studios
349 return "DefaultStudios.png";
350 case NODE_TYPE_MUSICVIDEOS_OVERVIEW: // Music Videos
351 return "DefaultMusicVideos.png";
352 case NODE_TYPE_MUSICVIDEOS_ALBUM: // Music Videos - Albums
353 return "DefaultMusicAlbums.png";
354 default:
355 break;
358 return "";
361 bool CVideoDatabaseDirectory::ContainsMovies(const std::string &path)
363 VIDEODATABASEDIRECTORY::NODE_TYPE type = GetDirectoryChildType(path);
364 if (type == VIDEODATABASEDIRECTORY::NODE_TYPE_TITLE_MOVIES ||
365 type == VIDEODATABASEDIRECTORY::NODE_TYPE_EPISODES ||
366 type == VIDEODATABASEDIRECTORY::NODE_TYPE_TITLE_MUSICVIDEOS ||
367 type == VIDEODATABASEDIRECTORY::NODE_TYPE_VIDEOVERSIONS)
368 return true;
369 return false;
372 bool CVideoDatabaseDirectory::Exists(const CURL& url)
374 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(url);
375 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
377 if (!pNode)
378 return false;
380 if (pNode->GetChildType() == VIDEODATABASEDIRECTORY::NODE_TYPE_NONE)
381 return false;
383 return true;
386 bool CVideoDatabaseDirectory::CanCache(const std::string& strPath)
388 std::string path = CLegacyPathTranslation::TranslateVideoDbPath(strPath);
389 std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path));
390 if (!pNode)
391 return false;
392 return pNode->CanCache();