Merge pull request #473 from Montellese/onplaybackspeedchanged
[vuplus_xbmc] / xbmc / interfaces / json-rpc / FileOperations.cpp
1 /*
2  *      Copyright (C) 2005-2010 Team XBMC
3  *      http://www.xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include "FileOperations.h"
23 #include "VideoLibrary.h"
24 #include "AudioLibrary.h"
25 #include "settings/Settings.h"
26 #include "MediaSource.h"
27 #include "filesystem/Directory.h"
28 #include "filesystem/File.h"
29 #include "FileItem.h"
30 #include "settings/AdvancedSettings.h"
31 #include "Util.h"
32 #include "URL.h"
33
34 using namespace XFILE;
35 using namespace JSONRPC;
36
37 JSON_STATUS CFileOperations::GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
38 {
39   CStdString media = parameterObject["media"].asString();
40   media = media.ToLower();
41
42   VECSOURCES *sources = g_settings.GetSourcesFromType(media);
43   if (sources)
44   {
45     CFileItemList items;
46     for (unsigned int i = 0; i < (unsigned int)sources->size(); i++)
47       items.Add(CFileItemPtr(new CFileItem(sources->at(i))));
48
49     for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
50     {
51       if (items[i]->IsSmb())
52       {
53         CURL url(items[i]->GetPath());
54         items[i]->SetPath(url.GetWithoutUserDetails());
55       }
56     }
57
58     CVariant param(CVariant::VariantTypeObject);
59     param["properties"] = CVariant(CVariant::VariantTypeArray);
60     param["properties"].append("file");
61
62     HandleFileItemList(NULL, true, "sources", items, param, result);
63   }
64
65   return OK;
66 }
67
68 JSON_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
69 {
70   CStdString media = parameterObject["media"].asString();
71   media = media.ToLower();
72
73   CDirectory directory;
74   CFileItemList items;
75   CStdString strPath = parameterObject["directory"].asString();
76
77   CStdStringArray regexps;
78   CStdString extensions = "";
79   if (media.Equals("video"))
80   {
81     regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
82     extensions = g_settings.m_videoExtensions;
83   }
84   else if (media.Equals("music"))
85   {
86     regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
87     extensions = g_settings.m_musicExtensions;
88   }
89   else if (media.Equals("pictures"))
90   {
91     regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
92     extensions = g_settings.m_pictureExtensions;
93   }
94
95   if (directory.GetDirectory(strPath, items, extensions))
96   {
97     CFileItemList filteredDirectories, filteredFiles;
98     for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
99     {
100       if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps))
101         continue;
102
103       if (items[i]->IsSmb())
104       {
105         CURL url(items[i]->GetPath());
106         items[i]->SetPath(url.GetWithoutUserDetails());
107       }
108
109       if (items[i]->m_bIsFolder)
110         filteredDirectories.Add(items[i]);
111       else if ((media == "video" && items[i]->HasVideoInfoTag()) ||
112                (media == "music" && items[i]->HasMusicInfoTag()))
113         filteredFiles.Add(items[i]);
114       else
115       {
116         CFileItem fileItem;
117         if (FillFileItem(items[i]->GetPath(), fileItem, media))
118           filteredFiles.Add(CFileItemPtr(new CFileItem(fileItem)));
119       }
120     }
121
122     // Check if the "properties" list exists
123     // and make sure it contains the "file"
124     // field
125     CVariant param = parameterObject;
126     if (!param.isMember("properties"))
127       param["properties"] = CVariant(CVariant::VariantTypeArray);
128
129     bool hasFileField = false;
130     for (CVariant::const_iterator_array itr = param["properties"].begin_array(); itr != param["properties"].end_array(); itr++)
131     {
132       if (*itr == CVariant("file"))
133       {
134         hasFileField = true;
135         break;
136       }
137     }
138
139     if (!hasFileField)
140       param["properties"].append("file");
141
142     HandleFileItemList(NULL, true, "files", filteredDirectories, param, result);
143     for (unsigned int index = 0; index < result["files"].size(); index++)
144     {
145       result["files"][index]["filetype"] = "directory";
146     }
147     int count = (int)result["limits"]["total"].asInteger();
148
149     HandleFileItemList("id", true, "files", filteredFiles, param, result);
150     for (unsigned int index = count; index < result["files"].size(); index++)
151     {
152       result["files"][index]["filetype"] = "file";
153     }
154     count += (int)result["limits"]["total"].asInteger();
155
156     result["limits"]["end"] = count;
157     result["limits"]["total"] = count;
158
159     return OK;
160   }
161
162   return InvalidParams;
163 }
164
165 JSON_STATUS CFileOperations::Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
166 {
167   return transport->Download(parameterObject["path"].asString().c_str(), result) ? OK : InvalidParams;
168 }
169
170 bool CFileOperations::FillFileItem(const CStdString &strFilename, CFileItem &item, CStdString media /* = "" */)
171 {
172   bool status = false;
173   if (!strFilename.empty() && !CDirectory::Exists(strFilename) && CFile::Exists(strFilename))
174   {
175     if (media.Equals("video"))
176       status |= CVideoLibrary::FillFileItem(strFilename, item);
177     else if (media.Equals("music"))
178       status |= CAudioLibrary::FillFileItem(strFilename, item);
179
180     if (!status)
181     {
182       item = CFileItem(strFilename, false);
183       if (item.GetLabel().IsEmpty())
184         item.SetLabel(CUtil::GetTitleFromPath(strFilename, false));
185     }
186
187     status = true;
188   }
189
190   return status;
191 }
192
193 bool CFileOperations::FillFileItemList(const CVariant &parameterObject, CFileItemList &list)
194 {
195   if (parameterObject.isMember("directory"))
196   {
197     CStdString media =  parameterObject["media"].asString();
198     media = media.ToLower();
199
200     CStdString strPath = parameterObject["directory"].asString();
201     if (!strPath.empty())
202     {
203       CFileItemList items;
204       CStdString extensions = "";
205       CStdStringArray regexps;
206
207       if (media.Equals("video") || media.Equals("music") || media.Equals("pictures"))
208       {
209         if (media.Equals("video"))
210         {
211           regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
212           extensions = g_settings.m_videoExtensions;
213         }
214         else if (media.Equals("music"))
215         {
216           regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
217           extensions = g_settings.m_musicExtensions;
218         }
219         else if (media.Equals("pictures"))
220         {
221           regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
222           extensions = g_settings.m_pictureExtensions;
223         }
224       }
225
226       CDirectory directory;
227       if (directory.GetDirectory(strPath, items, extensions))
228       {
229         items.Sort(SORT_METHOD_FILE, SORT_ORDER_ASC);
230         CFileItemList filteredDirectories;
231         for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
232         {
233           if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps))
234             continue;
235
236           if (items[i]->m_bIsFolder)
237             filteredDirectories.Add(items[i]);
238           else if ((media == "video" && items[i]->HasVideoInfoTag()) ||
239                    (media == "music" && items[i]->HasMusicInfoTag()))
240             list.Add(items[i]);
241           else
242           {
243             CFileItem fileItem;
244             if (FillFileItem(items[i]->GetPath(), fileItem, media))
245               list.Add(CFileItemPtr(new CFileItem(fileItem)));
246           }
247         }
248
249         if (parameterObject.isMember("recursive") && parameterObject["recursive"].isBoolean())
250         {
251           for (int i = 0; i < filteredDirectories.Size(); i++)
252           {
253             CVariant val = parameterObject;
254             val["directory"] = filteredDirectories[i]->GetPath();
255             FillFileItemList(val, list);
256           }
257         }
258
259         return true;
260       }
261     }
262   }
263
264   return false;
265 }