2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "FileOperations.h"
22 #include "VideoLibrary.h"
23 #include "AudioLibrary.h"
24 #include "MediaSource.h"
25 #include "filesystem/Directory.h"
26 #include "filesystem/File.h"
28 #include "settings/AdvancedSettings.h"
29 #include "settings/MediaSourceSettings.h"
32 #include "utils/URIUtils.h"
33 #include "utils/FileUtils.h"
35 using namespace XFILE;
36 using namespace JSONRPC;
38 JSONRPC_STATUS CFileOperations::GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
40 CStdString media = parameterObject["media"].asString();
41 media = media.ToLower();
43 VECSOURCES *sources = CMediaSourceSettings::Get().GetSources(media);
47 for (unsigned int i = 0; i < (unsigned int)sources->size(); i++)
49 // Do not show sources which are locked
50 if (sources->at(i).m_iHasLock == 2)
53 items.Add(CFileItemPtr(new CFileItem(sources->at(i))));
56 for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
58 if (items[i]->IsSmb())
60 CURL url(items[i]->GetPath());
61 items[i]->SetPath(url.GetWithoutUserDetails());
65 CVariant param = parameterObject;
66 param["properties"] = CVariant(CVariant::VariantTypeArray);
67 param["properties"].append("file");
69 HandleFileItemList(NULL, true, "sources", items, param, result);
75 JSONRPC_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
77 CStdString media = parameterObject["media"].asString();
78 media = media.ToLower();
81 CStdString strPath = parameterObject["directory"].asString();
83 if (!CFileUtils::RemoteAccessAllowed(strPath))
86 CStdStringArray regexps;
87 CStdString extensions = "";
88 if (media.Equals("video"))
90 regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
91 extensions = g_advancedSettings.m_videoExtensions;
93 else if (media.Equals("music"))
95 regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
96 extensions = g_advancedSettings.m_musicExtensions;
98 else if (media.Equals("pictures"))
100 regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
101 extensions = g_advancedSettings.m_pictureExtensions;
104 if (CDirectory::GetDirectory(strPath, items, extensions))
106 CFileItemList filteredFiles;
107 for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
109 if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps))
112 if (items[i]->IsSmb())
114 CURL url(items[i]->GetPath());
115 items[i]->SetPath(url.GetWithoutUserDetails());
118 if ((media == "video" && items[i]->HasVideoInfoTag()) ||
119 (media == "music" && items[i]->HasMusicInfoTag()) ||
120 (media == "picture" && items[i]->HasPictureInfoTag()) ||
122 URIUtils::IsUPnP(items.GetPath()))
123 filteredFiles.Add(items[i]);
126 CFileItemPtr fileItem(new CFileItem());
127 if (FillFileItem(items[i], fileItem, media, parameterObject))
128 filteredFiles.Add(fileItem);
130 filteredFiles.Add(items[i]);
134 // Check if the "properties" list exists
135 // and make sure it contains the "file"
137 CVariant param = parameterObject;
138 if (!param.isMember("properties"))
139 param["properties"] = CVariant(CVariant::VariantTypeArray);
141 bool hasFileField = false;
142 for (CVariant::const_iterator_array itr = param["properties"].begin_array(); itr != param["properties"].end_array(); itr++)
144 if (itr->asString().compare("file") == 0)
152 param["properties"].append("file");
154 HandleFileItemList("id", true, "files", filteredFiles, param, result);
155 for (CVariant::iterator_array item = result["files"].begin_array(); item != result["files"].end_array(); ++item)
157 if (!item->isMember("file"))
160 CFileItemPtr pItem = filteredFiles.Get((*item)["file"].asString());
164 if (pItem->m_bIsFolder)
165 (*item)["filetype"] = "directory";
167 (*item)["filetype"] = "file";
173 return InvalidParams;
176 JSONRPC_STATUS CFileOperations::GetFileDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
178 CStdString file = parameterObject["file"].asString();
179 if (!CFile::Exists(file))
180 return InvalidParams;
182 if (!CFileUtils::RemoteAccessAllowed(file))
183 return InvalidParams;
186 URIUtils::GetDirectory(file, path);
189 if (path.empty() || !CDirectory::GetDirectory(path, items) || !items.Contains(file))
190 return InvalidParams;
192 CFileItemPtr item = items.Get(file);
193 if (!URIUtils::IsUPnP(file))
194 FillFileItem(item, item, parameterObject["media"].asString(), parameterObject);
196 // Check if the "properties" list exists
197 // and make sure it contains the "file"
199 CVariant param = parameterObject;
200 if (!param.isMember("properties"))
201 param["properties"] = CVariant(CVariant::VariantTypeArray);
203 bool hasFileField = false;
204 for (CVariant::const_iterator_array itr = param["properties"].begin_array(); itr != param["properties"].end_array(); itr++)
206 if (itr->asString().compare("file") == 0)
214 param["properties"].append("file");
216 HandleFileItem("id", true, "filedetails", item, parameterObject, param["properties"], result, false);
220 JSONRPC_STATUS CFileOperations::PrepareDownload(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
222 std::string protocol;
223 if (transport->PrepareDownload(parameterObject["path"].asString().c_str(), result["details"], protocol))
225 result["protocol"] = protocol;
227 if ((transport->GetCapabilities() & FileDownloadDirect) == FileDownloadDirect)
228 result["mode"] = "direct";
230 result["mode"] = "redirect";
235 return InvalidParams;
238 JSONRPC_STATUS CFileOperations::Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
240 return transport->Download(parameterObject["path"].asString().c_str(), result) ? OK : InvalidParams;
243 bool CFileOperations::FillFileItem(const CFileItemPtr &originalItem, CFileItemPtr &item, CStdString media /* = "" */, const CVariant ¶meterObject /* = CVariant(CVariant::VariantTypeArray) */)
245 if (originalItem.get() == NULL)
248 // copy all the available details
249 *item = *originalItem;
252 CStdString strFilename = originalItem->GetPath();
253 if (!strFilename.empty() && (CDirectory::Exists(strFilename) || CFile::Exists(strFilename)))
255 if (media.Equals("video"))
256 status = CVideoLibrary::FillFileItem(strFilename, item, parameterObject);
257 else if (media.Equals("music"))
258 status = CAudioLibrary::FillFileItem(strFilename, item, parameterObject);
260 if (status && item->GetLabel().empty())
262 CStdString label = originalItem->GetLabel();
265 bool isDir = CDirectory::Exists(strFilename);
266 label = CUtil::GetTitleFromPath(strFilename, isDir);
268 label = URIUtils::GetFileName(strFilename);
271 item->SetLabel(label);
275 if (originalItem->GetLabel().empty())
277 bool isDir = CDirectory::Exists(strFilename);
278 CStdString label = CUtil::GetTitleFromPath(strFilename, isDir);
282 item->SetLabel(label);
283 item->SetPath(strFilename);
284 item->m_bIsFolder = isDir;
287 *item = *originalItem;
296 bool CFileOperations::FillFileItemList(const CVariant ¶meterObject, CFileItemList &list)
298 if (parameterObject.isMember("directory"))
300 CStdString media = parameterObject["media"].asString();
301 media = media.ToLower();
303 CStdString strPath = parameterObject["directory"].asString();
304 if (!strPath.empty())
307 CStdString extensions = "";
308 CStdStringArray regexps;
310 if (media.Equals("video"))
312 regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
313 extensions = g_advancedSettings.m_videoExtensions;
315 else if (media.Equals("music"))
317 regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
318 extensions = g_advancedSettings.m_musicExtensions;
320 else if (media.Equals("pictures"))
322 regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
323 extensions = g_advancedSettings.m_pictureExtensions;
326 CDirectory directory;
327 if (directory.GetDirectory(strPath, items, extensions))
329 items.Sort(SORT_METHOD_FILE, SortOrderAscending);
330 CFileItemList filteredDirectories;
331 for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
333 if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps))
336 if (items[i]->m_bIsFolder)
337 filteredDirectories.Add(items[i]);
338 else if ((media == "video" && items[i]->HasVideoInfoTag()) ||
339 (media == "music" && items[i]->HasMusicInfoTag()))
343 CFileItemPtr fileItem(new CFileItem());
344 if (FillFileItem(items[i], fileItem, media, parameterObject))
346 else if (media == "files")
351 if (parameterObject.isMember("recursive") && parameterObject["recursive"].isBoolean())
353 for (int i = 0; i < filteredDirectories.Size(); i++)
355 CVariant val = parameterObject;
356 val["directory"] = filteredDirectories[i]->GetPath();
357 FillFileItemList(val, list);