summaryrefslogtreecommitdiffstats
path: root/xbmc/filesystem/LibraryDirectory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/filesystem/LibraryDirectory.cpp')
-rw-r--r--xbmc/filesystem/LibraryDirectory.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/xbmc/filesystem/LibraryDirectory.cpp b/xbmc/filesystem/LibraryDirectory.cpp
new file mode 100644
index 0000000..8f81495
--- /dev/null
+++ b/xbmc/filesystem/LibraryDirectory.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2011-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "LibraryDirectory.h"
+
+#include "Directory.h"
+#include "FileItem.h"
+#include "GUIInfoManager.h"
+#include "SmartPlaylistDirectory.h"
+#include "URL.h"
+#include "guilib/GUIControlFactory.h" // for label parsing
+#include "guilib/TextureManager.h"
+#include "playlists/SmartPlayList.h"
+#include "profiles/ProfileManager.h"
+#include "utils/FileUtils.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "utils/XMLUtils.h"
+#include "utils/log.h"
+
+using namespace XFILE;
+
+CLibraryDirectory::CLibraryDirectory(void) = default;
+
+CLibraryDirectory::~CLibraryDirectory(void) = default;
+
+bool CLibraryDirectory::GetDirectory(const CURL& url, CFileItemList &items)
+{
+ std::string libNode = GetNode(url);
+ if (libNode.empty())
+ return false;
+
+ if (URIUtils::HasExtension(libNode, ".xml"))
+ { // a filter or folder node
+ TiXmlElement *node = LoadXML(libNode);
+ if (node)
+ {
+ std::string type = XMLUtils::GetAttribute(node, "type");
+ if (type == "filter")
+ {
+ CSmartPlaylist playlist;
+ std::string type, label;
+ XMLUtils::GetString(node, "content", type);
+ if (type.empty())
+ {
+ CLog::Log(LOGERROR, "<content> tag must not be empty for type=\"filter\" node '{}'",
+ libNode);
+ return false;
+ }
+ if (XMLUtils::GetString(node, "label", label))
+ label = CGUIControlFactory::FilterLabel(label);
+ playlist.SetType(type);
+ playlist.SetName(label);
+ if (playlist.LoadFromXML(node) &&
+ CSmartPlaylistDirectory::GetDirectory(playlist, items))
+ {
+ items.SetProperty("library.filter", "true");
+ items.SetPath(items.GetProperty("path.db").asString());
+ return true;
+ }
+ }
+ else if (type == "folder")
+ {
+ std::string label;
+ if (XMLUtils::GetString(node, "label", label))
+ label = CGUIControlFactory::FilterLabel(label);
+ items.SetLabel(label);
+ std::string path;
+ XMLUtils::GetPath(node, "path", path);
+ if (!path.empty())
+ {
+ URIUtils::AddSlashAtEnd(path);
+ return CDirectory::GetDirectory(path, items, m_strFileMask, m_flags);
+ }
+ }
+ }
+ return false;
+ }
+
+ // just a plain node - read the folder for XML nodes and other folders
+ CFileItemList nodes;
+ if (!CDirectory::GetDirectory(libNode, nodes, ".xml", DIR_FLAG_NO_FILE_DIRS))
+ return false;
+
+ // iterate over our nodes
+ std::string basePath = url.Get();
+ for (int i = 0; i < nodes.Size(); i++)
+ {
+ const TiXmlElement *node = NULL;
+ std::string xml = nodes[i]->GetPath();
+ if (nodes[i]->m_bIsFolder)
+ node = LoadXML(URIUtils::AddFileToFolder(xml, "index.xml"));
+ else
+ {
+ node = LoadXML(xml);
+ if (node && URIUtils::GetFileName(xml) == "index.xml")
+ { // set the label on our items
+ std::string label;
+ if (XMLUtils::GetString(node, "label", label))
+ label = CGUIControlFactory::FilterLabel(label);
+ items.SetLabel(label);
+ continue;
+ }
+ }
+ if (node)
+ {
+ std::string label, icon;
+ if (XMLUtils::GetString(node, "label", label))
+ label = CGUIControlFactory::FilterLabel(label);
+ XMLUtils::GetString(node, "icon", icon);
+ int order = 0;
+ node->Attribute("order", &order);
+
+ // create item
+ URIUtils::RemoveSlashAtEnd(xml);
+ std::string folder = URIUtils::GetFileName(xml);
+ CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(basePath, folder), true));
+
+ item->SetLabel(label);
+ if (!icon.empty() && CServiceBroker::GetGUI()->GetTextureManager().HasTexture(icon))
+ item->SetArt("icon", icon);
+ item->m_iprogramCount = order;
+ items.Add(item);
+ }
+ }
+ items.Sort(SortByPlaylistOrder, SortOrderAscending);
+ return true;
+}
+
+TiXmlElement *CLibraryDirectory::LoadXML(const std::string &xmlFile)
+{
+ if (!CFileUtils::Exists(xmlFile))
+ return nullptr;
+
+ if (!m_doc.LoadFile(xmlFile))
+ return nullptr;
+
+ TiXmlElement *xml = m_doc.RootElement();
+ if (!xml || xml->ValueStr() != "node")
+ return nullptr;
+
+ // check the condition
+ std::string condition = XMLUtils::GetAttribute(xml, "visible");
+ CGUIComponent* gui = CServiceBroker::GetGUI();
+ if (condition.empty() ||
+ (gui && gui->GetInfoManager().EvaluateBool(condition, INFO::DEFAULT_CONTEXT)))
+ return xml;
+
+ return nullptr;
+}
+
+bool CLibraryDirectory::Exists(const CURL& url)
+{
+ return !GetNode(url).empty();
+}
+
+std::string CLibraryDirectory::GetNode(const CURL& url)
+{
+ std::string libDir = URIUtils::AddFileToFolder(m_profileManager->GetLibraryFolder(), url.GetHostName() + "/");
+ if (!CDirectory::Exists(libDir))
+ libDir = URIUtils::AddFileToFolder("special://xbmc/system/library/", url.GetHostName() + "/");
+
+ libDir = URIUtils::AddFileToFolder(libDir, url.GetFileName());
+
+ // is this a virtual node (aka actual folder on disk?)
+ if (CDirectory::Exists(libDir))
+ return libDir;
+
+ // maybe it's an XML node?
+ std::string xmlNode = libDir;
+ URIUtils::RemoveSlashAtEnd(xmlNode);
+
+ if (CFileUtils::Exists(xmlNode))
+ return xmlNode;
+
+ return "";
+}