Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

337 lines (291 sloc) 10.564 kb
/*
* Copyright (C) 2005-2010 Team XBMC
* http://www.xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "FileOperations.h"
#include "VideoLibrary.h"
#include "AudioLibrary.h"
#include "settings/Settings.h"
#include "MediaSource.h"
#include "filesystem/Directory.h"
#include "filesystem/File.h"
#include "FileItem.h"
#include "settings/AdvancedSettings.h"
#include "Util.h"
#include "URL.h"
using namespace XFILE;
using namespace JSONRPC;
static const unsigned int SourcesSize = 5;
static CStdString SourceNames[] = { "programs", "files", "video", "music", "pictures" };
JSONRPC_STATUS CFileOperations::GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
CStdString media = parameterObject["media"].asString();
media = media.ToLower();
VECSOURCES *sources = g_settings.GetSourcesFromType(media);
if (sources)
{
CFileItemList items;
for (unsigned int i = 0; i < (unsigned int)sources->size(); i++)
{
// Do not show sources which are locked
if (sources->at(i).m_iHasLock == 2)
continue;
items.Add(CFileItemPtr(new CFileItem(sources->at(i))));
}
for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
{
if (items[i]->IsSmb())
{
CURL url(items[i]->GetPath());
items[i]->SetPath(url.GetWithoutUserDetails());
}
}
CVariant param = parameterObject;
param["properties"] = CVariant(CVariant::VariantTypeArray);
param["properties"].append("file");
HandleFileItemList(NULL, true, "sources", items, param, result);
}
return OK;
}
JSONRPC_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
CStdString media = parameterObject["media"].asString();
media = media.ToLower();
CFileItemList items;
CStdString strPath = parameterObject["directory"].asString();
// Check if this directory is part of a source and whether it's locked
VECSOURCES *sources;
bool isSource;
for (unsigned int index = 0; index < SourcesSize; index++)
{
sources = g_settings.GetSourcesFromType(SourceNames[index]);
int sourceIndex = CUtil::GetMatchingSource(strPath, *sources, isSource);
if (sourceIndex >= 0 && sourceIndex < (int)sources->size() && sources->at(sourceIndex).m_iHasLock == 2)
return InvalidParams;
}
CStdStringArray regexps;
CStdString extensions = "";
if (media.Equals("video"))
{
regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
extensions = g_settings.m_videoExtensions;
}
else if (media.Equals("music"))
{
regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
extensions = g_settings.m_musicExtensions;
}
else if (media.Equals("pictures"))
{
regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
extensions = g_settings.m_pictureExtensions;
}
if (CDirectory::GetDirectory(strPath, items, extensions))
{
CFileItemList filteredDirectories, filteredFiles;
for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
{
if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps))
continue;
if (items[i]->IsSmb())
{
CURL url(items[i]->GetPath());
items[i]->SetPath(url.GetWithoutUserDetails());
}
if ((media == "video" && items[i]->HasVideoInfoTag()) ||
(media == "music" && items[i]->HasMusicInfoTag()) ||
(media == "picture" && items[i]->HasPictureInfoTag()) ||
media == "files")
{
if (items[i]->m_bIsFolder)
filteredDirectories.Add(items[i]);
else
filteredFiles.Add(items[i]);
}
else
{
CFileItem fileItem;
if (FillFileItem(items[i], fileItem, media))
{
fileItem.m_bIsFolder = items[i]->m_bIsFolder;
fileItem.m_dateTime = items[i]->m_dateTime;
fileItem.m_dwSize = items[i]->m_dwSize;
fileItem.SetMimeType(items[i]->GetMimeType());
if (items[i]->m_bIsFolder)
filteredDirectories.Add(CFileItemPtr(new CFileItem(fileItem)));
else
filteredFiles.Add(CFileItemPtr(new CFileItem(fileItem)));
}
else
{
if (items[i]->m_bIsFolder)
filteredDirectories.Add(items[i]);
else
filteredFiles.Add(items[i]);
}
}
}
// Check if the "properties" list exists
// and make sure it contains the "file"
// field
CVariant param = parameterObject;
if (!param.isMember("properties"))
param["properties"] = CVariant(CVariant::VariantTypeArray);
bool hasFileField = false;
for (CVariant::const_iterator_array itr = param["properties"].begin_array(); itr != param["properties"].end_array(); itr++)
{
if (itr->asString().compare("file") == 0)
{
hasFileField = true;
break;
}
}
if (!hasFileField)
param["properties"].append("file");
HandleFileItemList("id", true, "files", filteredDirectories, param, result);
for (unsigned int index = 0; index < result["files"].size(); index++)
{
result["files"][index]["filetype"] = "directory";
}
int count = (int)result["limits"]["total"].asInteger();
HandleFileItemList("id", true, "files", filteredFiles, param, result);
for (unsigned int index = count; index < result["files"].size(); index++)
{
result["files"][index]["filetype"] = "file";
}
count += (int)result["limits"]["total"].asInteger();
result["limits"]["end"] = count;
result["limits"]["total"] = count;
return OK;
}
return InvalidParams;
}
JSONRPC_STATUS CFileOperations::PrepareDownload(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
std::string protocol;
if (transport->PrepareDownload(parameterObject["path"].asString().c_str(), result["details"], protocol))
{
result["protocol"] = protocol;
if ((transport->GetCapabilities() & FileDownloadDirect) == FileDownloadDirect)
result["mode"] = "direct";
else
result["mode"] = "redirect";
return OK;
}
return InvalidParams;
}
JSONRPC_STATUS CFileOperations::Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
return transport->Download(parameterObject["path"].asString().c_str(), result) ? OK : InvalidParams;
}
bool CFileOperations::FillFileItem(const CFileItemPtr &originalItem, CFileItem &item, CStdString media /* = "" */)
{
if (originalItem.get() == NULL)
return false;
bool status = false;
CStdString strFilename = originalItem->GetPath();
if (!strFilename.empty() && (CDirectory::Exists(strFilename) || CFile::Exists(strFilename)))
{
if (media.Equals("video"))
status = CVideoLibrary::FillFileItem(strFilename, item);
else if (media.Equals("music"))
status = CAudioLibrary::FillFileItem(strFilename, item);
if (!status)
{
bool isDir = CDirectory::Exists(strFilename);
if (originalItem->GetLabel().empty())
{
CStdString label = CUtil::GetTitleFromPath(strFilename, isDir);
if (label.empty())
return false;
item = CFileItem(strFilename, isDir);
item.SetLabel(label);
}
else
item = *originalItem.get();
status = true;
}
}
return status;
}
bool CFileOperations::FillFileItemList(const CVariant &parameterObject, CFileItemList &list)
{
if (parameterObject.isMember("directory"))
{
CStdString media = parameterObject["media"].asString();
media = media.ToLower();
CStdString strPath = parameterObject["directory"].asString();
if (!strPath.empty())
{
CFileItemList items;
CStdString extensions = "";
CStdStringArray regexps;
if (media.Equals("video"))
{
regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
extensions = g_settings.m_videoExtensions;
}
else if (media.Equals("music"))
{
regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
extensions = g_settings.m_musicExtensions;
}
else if (media.Equals("pictures"))
{
regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
extensions = g_settings.m_pictureExtensions;
}
CDirectory directory;
if (directory.GetDirectory(strPath, items, extensions))
{
items.Sort(SORT_METHOD_FILE, SortOrderAscending);
CFileItemList filteredDirectories;
for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
{
if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps))
continue;
if (items[i]->m_bIsFolder)
filteredDirectories.Add(items[i]);
else if ((media == "video" && items[i]->HasVideoInfoTag()) ||
(media == "music" && items[i]->HasMusicInfoTag()))
list.Add(items[i]);
else
{
CFileItem fileItem;
if (FillFileItem(items[i], fileItem, media))
list.Add(CFileItemPtr(new CFileItem(fileItem)));
else if (media == "files")
list.Add(items[i]);
}
}
if (parameterObject.isMember("recursive") && parameterObject["recursive"].isBoolean())
{
for (int i = 0; i < filteredDirectories.Size(); i++)
{
CVariant val = parameterObject;
val["directory"] = filteredDirectories[i]->GetPath();
FillFileItemList(val, list);
}
}
return true;
}
}
}
return false;
}
Jump to Line
Something went wrong with that request. Please try again.