[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / filesystem / DAVDirectory.cpp
blob48d48655cc23ef2700d2f5bc0fdbf1b3546812f8
1 /*
2 * Copyright (C) 2005-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 "DAVDirectory.h"
11 #include "CurlFile.h"
12 #include "DAVCommon.h"
13 #include "DAVFile.h"
14 #include "FileItem.h"
15 #include "URL.h"
16 #include "utils/StringUtils.h"
17 #include "utils/URIUtils.h"
18 #include "utils/log.h"
20 using namespace XFILE;
22 CDAVDirectory::CDAVDirectory(void) = default;
23 CDAVDirectory::~CDAVDirectory(void) = default;
26 * Parses a <response>
28 * <!ELEMENT response (href, ((href*, status)|(propstat+)), responsedescription?) >
29 * <!ELEMENT propstat (prop, status, responsedescription?) >
32 void CDAVDirectory::ParseResponse(const TiXmlElement *pElement, CFileItem &item)
34 const TiXmlElement *pResponseChild;
35 const TiXmlNode *pPropstatChild;
36 const TiXmlElement *pPropChild;
38 /* Iterate response children elements */
39 for (pResponseChild = pElement->FirstChildElement(); pResponseChild != 0; pResponseChild = pResponseChild->NextSiblingElement())
41 if (CDAVCommon::ValueWithoutNamespace(pResponseChild, "href") && !pResponseChild->NoChildren())
43 std::string path(pResponseChild->FirstChild()->ValueStr());
44 URIUtils::RemoveSlashAtEnd(path);
45 item.SetPath(path);
47 else
48 if (CDAVCommon::ValueWithoutNamespace(pResponseChild, "propstat"))
50 if (CDAVCommon::GetStatusTag(pResponseChild->ToElement()).find("200 OK") != std::string::npos)
52 /* Iterate propstat children elements */
53 for (pPropstatChild = pResponseChild->FirstChild(); pPropstatChild != 0; pPropstatChild = pPropstatChild->NextSibling())
55 if (CDAVCommon::ValueWithoutNamespace(pPropstatChild, "prop"))
57 /* Iterate all properties available */
58 for (pPropChild = pPropstatChild->FirstChildElement(); pPropChild != 0; pPropChild = pPropChild->NextSiblingElement())
60 if (CDAVCommon::ValueWithoutNamespace(pPropChild, "getcontentlength") && !pPropChild->NoChildren())
62 item.m_dwSize = strtoll(pPropChild->FirstChild()->Value(), NULL, 10);
64 else
65 if (CDAVCommon::ValueWithoutNamespace(pPropChild, "getlastmodified") && !pPropChild->NoChildren())
67 struct tm timeDate = {};
68 strptime(pPropChild->FirstChild()->Value(), "%a, %d %b %Y %T", &timeDate);
69 item.m_dateTime = mktime(&timeDate);
71 else
72 if (CDAVCommon::ValueWithoutNamespace(pPropChild, "displayname") && !pPropChild->NoChildren())
74 item.SetLabel(CURL::Decode(pPropChild->FirstChild()->ValueStr()));
76 else
77 if (!item.m_dateTime.IsValid() && CDAVCommon::ValueWithoutNamespace(pPropChild, "creationdate") && !pPropChild->NoChildren())
79 struct tm timeDate = {};
80 strptime(pPropChild->FirstChild()->Value(), "%Y-%m-%dT%T", &timeDate);
81 item.m_dateTime = mktime(&timeDate);
83 else
84 if (CDAVCommon::ValueWithoutNamespace(pPropChild, "resourcetype"))
86 if (CDAVCommon::ValueWithoutNamespace(pPropChild->FirstChild(), "collection"))
88 item.m_bIsFolder = true;
99 bool CDAVDirectory::GetDirectory(const CURL& url, CFileItemList &items)
101 CCurlFile dav;
102 std::string strRequest = "PROPFIND";
104 dav.SetCustomRequest(strRequest);
105 dav.SetMimeType("text/xml; charset=\"utf-8\"");
106 dav.SetRequestHeader("depth", 1);
107 dav.SetPostData(
108 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
109 " <D:propfind xmlns:D=\"DAV:\">"
110 " <D:prop>"
111 " <D:resourcetype/>"
112 " <D:getcontentlength/>"
113 " <D:getlastmodified/>"
114 " <D:creationdate/>"
115 " <D:displayname/>"
116 " </D:prop>"
117 " </D:propfind>");
119 if (!dav.Open(url))
121 CLog::Log(LOGERROR, "{} - Unable to get dav directory ({})", __FUNCTION__, url.GetRedacted());
122 return false;
125 std::string strResponse;
126 dav.ReadData(strResponse);
128 std::string fileCharset(dav.GetProperty(XFILE::FILE_PROPERTY_CONTENT_CHARSET));
129 CXBMCTinyXML davResponse;
130 davResponse.Parse(strResponse, fileCharset);
132 if (!davResponse.Parse(strResponse))
134 CLog::Log(LOGERROR, "{} - Unable to process dav directory ({})", __FUNCTION__,
135 url.GetRedacted());
136 dav.Close();
137 return false;
140 TiXmlNode *pChild;
141 // Iterate over all responses
142 for (pChild = davResponse.RootElement()->FirstChild(); pChild != 0; pChild = pChild->NextSibling())
144 if (CDAVCommon::ValueWithoutNamespace(pChild, "response"))
146 CFileItem item;
147 ParseResponse(pChild->ToElement(), item);
148 const CURL& url2(url);
149 CURL url3(item.GetPath());
151 std::string itemPath(URIUtils::AddFileToFolder(url2.GetWithoutFilename(), url3.GetFileName()));
153 if (item.GetLabel().empty())
155 std::string name(itemPath);
156 URIUtils::RemoveSlashAtEnd(name);
157 item.SetLabel(CURL::Decode(URIUtils::GetFileName(name)));
160 if (item.m_bIsFolder)
161 URIUtils::AddSlashAtEnd(itemPath);
163 // Add back protocol options
164 if (!url2.GetProtocolOptions().empty())
165 itemPath += "|" + url2.GetProtocolOptions();
166 item.SetPath(itemPath);
168 if (!item.IsURL(url))
170 CFileItemPtr pItem(new CFileItem(item));
171 items.Add(pItem);
176 dav.Close();
178 return true;
181 bool CDAVDirectory::Create(const CURL& url)
183 CDAVFile dav;
184 std::string strRequest = "MKCOL";
186 dav.SetCustomRequest(strRequest);
188 if (!dav.Execute(url))
190 CLog::Log(LOGERROR, "{} - Unable to create dav directory ({}) - {}", __FUNCTION__,
191 url.GetRedacted(), dav.GetLastResponseCode());
192 return false;
195 dav.Close();
197 return true;
200 bool CDAVDirectory::Exists(const CURL& url)
202 CCurlFile dav;
204 // Set the PROPFIND custom request else we may not find folders, depending
205 // on the server's configuration
206 std::string strRequest = "PROPFIND";
207 dav.SetCustomRequest(strRequest);
208 dav.SetRequestHeader("depth", 0);
210 return dav.Exists(url);
213 bool CDAVDirectory::Remove(const CURL& url)
215 CDAVFile dav;
216 std::string strRequest = "DELETE";
218 dav.SetCustomRequest(strRequest);
220 if (!dav.Execute(url))
222 CLog::Log(LOGERROR, "{} - Unable to delete dav directory ({}) - {}", __FUNCTION__,
223 url.GetRedacted(), dav.GetLastResponseCode());
224 return false;
227 dav.Close();
229 return true;