[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / filesystem / LibraryDirectory.cpp
blob8f814950ae0eead9612a237318c4657d6aae9570
1 /*
2 * Copyright (C) 2011-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 "LibraryDirectory.h"
11 #include "Directory.h"
12 #include "FileItem.h"
13 #include "GUIInfoManager.h"
14 #include "SmartPlaylistDirectory.h"
15 #include "URL.h"
16 #include "guilib/GUIControlFactory.h" // for label parsing
17 #include "guilib/TextureManager.h"
18 #include "playlists/SmartPlayList.h"
19 #include "profiles/ProfileManager.h"
20 #include "utils/FileUtils.h"
21 #include "utils/StringUtils.h"
22 #include "utils/URIUtils.h"
23 #include "utils/XMLUtils.h"
24 #include "utils/log.h"
26 using namespace XFILE;
28 CLibraryDirectory::CLibraryDirectory(void) = default;
30 CLibraryDirectory::~CLibraryDirectory(void) = default;
32 bool CLibraryDirectory::GetDirectory(const CURL& url, CFileItemList &items)
34 std::string libNode = GetNode(url);
35 if (libNode.empty())
36 return false;
38 if (URIUtils::HasExtension(libNode, ".xml"))
39 { // a filter or folder node
40 TiXmlElement *node = LoadXML(libNode);
41 if (node)
43 std::string type = XMLUtils::GetAttribute(node, "type");
44 if (type == "filter")
46 CSmartPlaylist playlist;
47 std::string type, label;
48 XMLUtils::GetString(node, "content", type);
49 if (type.empty())
51 CLog::Log(LOGERROR, "<content> tag must not be empty for type=\"filter\" node '{}'",
52 libNode);
53 return false;
55 if (XMLUtils::GetString(node, "label", label))
56 label = CGUIControlFactory::FilterLabel(label);
57 playlist.SetType(type);
58 playlist.SetName(label);
59 if (playlist.LoadFromXML(node) &&
60 CSmartPlaylistDirectory::GetDirectory(playlist, items))
62 items.SetProperty("library.filter", "true");
63 items.SetPath(items.GetProperty("path.db").asString());
64 return true;
67 else if (type == "folder")
69 std::string label;
70 if (XMLUtils::GetString(node, "label", label))
71 label = CGUIControlFactory::FilterLabel(label);
72 items.SetLabel(label);
73 std::string path;
74 XMLUtils::GetPath(node, "path", path);
75 if (!path.empty())
77 URIUtils::AddSlashAtEnd(path);
78 return CDirectory::GetDirectory(path, items, m_strFileMask, m_flags);
82 return false;
85 // just a plain node - read the folder for XML nodes and other folders
86 CFileItemList nodes;
87 if (!CDirectory::GetDirectory(libNode, nodes, ".xml", DIR_FLAG_NO_FILE_DIRS))
88 return false;
90 // iterate over our nodes
91 std::string basePath = url.Get();
92 for (int i = 0; i < nodes.Size(); i++)
94 const TiXmlElement *node = NULL;
95 std::string xml = nodes[i]->GetPath();
96 if (nodes[i]->m_bIsFolder)
97 node = LoadXML(URIUtils::AddFileToFolder(xml, "index.xml"));
98 else
100 node = LoadXML(xml);
101 if (node && URIUtils::GetFileName(xml) == "index.xml")
102 { // set the label on our items
103 std::string label;
104 if (XMLUtils::GetString(node, "label", label))
105 label = CGUIControlFactory::FilterLabel(label);
106 items.SetLabel(label);
107 continue;
110 if (node)
112 std::string label, icon;
113 if (XMLUtils::GetString(node, "label", label))
114 label = CGUIControlFactory::FilterLabel(label);
115 XMLUtils::GetString(node, "icon", icon);
116 int order = 0;
117 node->Attribute("order", &order);
119 // create item
120 URIUtils::RemoveSlashAtEnd(xml);
121 std::string folder = URIUtils::GetFileName(xml);
122 CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(basePath, folder), true));
124 item->SetLabel(label);
125 if (!icon.empty() && CServiceBroker::GetGUI()->GetTextureManager().HasTexture(icon))
126 item->SetArt("icon", icon);
127 item->m_iprogramCount = order;
128 items.Add(item);
131 items.Sort(SortByPlaylistOrder, SortOrderAscending);
132 return true;
135 TiXmlElement *CLibraryDirectory::LoadXML(const std::string &xmlFile)
137 if (!CFileUtils::Exists(xmlFile))
138 return nullptr;
140 if (!m_doc.LoadFile(xmlFile))
141 return nullptr;
143 TiXmlElement *xml = m_doc.RootElement();
144 if (!xml || xml->ValueStr() != "node")
145 return nullptr;
147 // check the condition
148 std::string condition = XMLUtils::GetAttribute(xml, "visible");
149 CGUIComponent* gui = CServiceBroker::GetGUI();
150 if (condition.empty() ||
151 (gui && gui->GetInfoManager().EvaluateBool(condition, INFO::DEFAULT_CONTEXT)))
152 return xml;
154 return nullptr;
157 bool CLibraryDirectory::Exists(const CURL& url)
159 return !GetNode(url).empty();
162 std::string CLibraryDirectory::GetNode(const CURL& url)
164 std::string libDir = URIUtils::AddFileToFolder(m_profileManager->GetLibraryFolder(), url.GetHostName() + "/");
165 if (!CDirectory::Exists(libDir))
166 libDir = URIUtils::AddFileToFolder("special://xbmc/system/library/", url.GetHostName() + "/");
168 libDir = URIUtils::AddFileToFolder(libDir, url.GetFileName());
170 // is this a virtual node (aka actual folder on disk?)
171 if (CDirectory::Exists(libDir))
172 return libDir;
174 // maybe it's an XML node?
175 std::string xmlNode = libDir;
176 URIUtils::RemoveSlashAtEnd(xmlNode);
178 if (CFileUtils::Exists(xmlNode))
179 return xmlNode;
181 return "";