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.
9 #include "LibraryDirectory.h"
11 #include "Directory.h"
13 #include "GUIInfoManager.h"
14 #include "SmartPlaylistDirectory.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
);
38 if (URIUtils::HasExtension(libNode
, ".xml"))
39 { // a filter or folder node
40 TiXmlElement
*node
= LoadXML(libNode
);
43 std::string type
= XMLUtils::GetAttribute(node
, "type");
46 CSmartPlaylist playlist
;
47 std::string type
, label
;
48 XMLUtils::GetString(node
, "content", type
);
51 CLog::Log(LOGERROR
, "<content> tag must not be empty for type=\"filter\" node '{}'",
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());
67 else if (type
== "folder")
70 if (XMLUtils::GetString(node
, "label", label
))
71 label
= CGUIControlFactory::FilterLabel(label
);
72 items
.SetLabel(label
);
74 XMLUtils::GetPath(node
, "path", path
);
77 URIUtils::AddSlashAtEnd(path
);
78 return CDirectory::GetDirectory(path
, items
, m_strFileMask
, m_flags
);
85 // just a plain node - read the folder for XML nodes and other folders
87 if (!CDirectory::GetDirectory(libNode
, nodes
, ".xml", DIR_FLAG_NO_FILE_DIRS
))
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"));
101 if (node
&& URIUtils::GetFileName(xml
) == "index.xml")
102 { // set the label on our items
104 if (XMLUtils::GetString(node
, "label", label
))
105 label
= CGUIControlFactory::FilterLabel(label
);
106 items
.SetLabel(label
);
112 std::string label
, icon
;
113 if (XMLUtils::GetString(node
, "label", label
))
114 label
= CGUIControlFactory::FilterLabel(label
);
115 XMLUtils::GetString(node
, "icon", icon
);
117 node
->Attribute("order", &order
);
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
;
131 items
.Sort(SortByPlaylistOrder
, SortOrderAscending
);
135 TiXmlElement
*CLibraryDirectory::LoadXML(const std::string
&xmlFile
)
137 if (!CFileUtils::Exists(xmlFile
))
140 if (!m_doc
.LoadFile(xmlFile
))
143 TiXmlElement
*xml
= m_doc
.RootElement();
144 if (!xml
|| xml
->ValueStr() != "node")
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
)))
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
))
174 // maybe it's an XML node?
175 std::string xmlNode
= libDir
;
176 URIUtils::RemoveSlashAtEnd(xmlNode
);
178 if (CFileUtils::Exists(xmlNode
))