Merge pull request #4314 from MartijnKaijser/beta1
[vuplus_xbmc] / xbmc / interfaces / json-rpc / PVROperations.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://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, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "PVROperations.h"
22 #include "ApplicationMessenger.h"
23 #include "utils/log.h"
24
25 #include "pvr/PVRManager.h"
26 #include "pvr/channels/PVRChannelGroupsContainer.h"
27 #include "pvr/channels/PVRChannel.h"
28 #include "pvr/timers/PVRTimers.h"
29 #include "pvr/timers/PVRTimerInfoTag.h"
30 #include "pvr/recordings/PVRRecordings.h"
31 #include "pvr/timers/PVRTimers.h"
32 #include "epg/Epg.h"
33 #include "epg/EpgContainer.h"
34
35 using namespace std;
36 using namespace JSONRPC;
37 using namespace PVR;
38 using namespace EPG;
39
40 JSONRPC_STATUS CPVROperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
41 {
42   if (!g_PVRManager.IsStarted())
43     return FailedToExecute;
44   
45   CVariant properties = CVariant(CVariant::VariantTypeObject);
46   for (unsigned int index = 0; index < parameterObject["properties"].size(); index++)
47   {
48     CStdString propertyName = parameterObject["properties"][index].asString();
49     CVariant property;
50     JSONRPC_STATUS ret;
51     if ((ret = GetPropertyValue(propertyName, property)) != OK)
52       return ret;
53
54     properties[propertyName] = property;
55   }
56
57   result = properties;
58
59   return OK;
60 }
61
62 JSONRPC_STATUS CPVROperations::GetChannelGroups(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
63 {
64   if (!g_PVRManager.IsStarted())
65     return FailedToExecute;
66   
67   CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups;
68   if (channelGroupContainer == NULL)
69     return FailedToExecute;
70
71   CPVRChannelGroups *channelGroups = channelGroupContainer->Get(parameterObject["channeltype"].asString().compare("radio") == 0);
72   if (channelGroups == NULL)
73     return FailedToExecute;
74
75   int start, end;
76
77   vector<CPVRChannelGroupPtr> groupList = channelGroups->GetMembers();
78   HandleLimits(parameterObject, result, groupList.size(), start, end);
79   for (int index = start; index < end; index++)
80     FillChannelGroupDetails(groupList.at(index), parameterObject, result["channelgroups"], true);
81
82   return OK;
83 }
84
85 JSONRPC_STATUS CPVROperations::GetChannelGroupDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
86 {
87   if (!g_PVRManager.IsStarted())
88     return FailedToExecute;
89
90   CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups;
91   if (channelGroupContainer == NULL)
92     return FailedToExecute;
93   
94   CPVRChannelGroupPtr channelGroup;
95   CVariant id = parameterObject["channelgroupid"];
96   if (id.isInteger())
97     channelGroup = channelGroupContainer->GetByIdFromAll((int)id.asInteger());
98   else if (id.isString())
99     channelGroup = channelGroupContainer->GetGroupAll(id.asString() == "allradio");
100
101   if (channelGroup == NULL)
102     return InvalidParams;
103   
104   FillChannelGroupDetails(channelGroup, parameterObject, result["channelgroupdetails"], false);
105   
106   return OK;
107 }
108
109 JSONRPC_STATUS CPVROperations::GetChannels(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
110 {
111   if (!g_PVRManager.IsStarted())
112     return FailedToExecute;
113   
114   CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups;
115   if (channelGroupContainer == NULL)
116     return FailedToExecute;
117   
118   CPVRChannelGroupPtr channelGroup;
119   CVariant id = parameterObject["channelgroupid"];
120   if (id.isInteger())
121     channelGroup = channelGroupContainer->GetByIdFromAll((int)id.asInteger());
122   else if (id.isString())
123     channelGroup = channelGroupContainer->GetGroupAll(id.asString() == "allradio");
124   
125   if (channelGroup == NULL)
126     return InvalidParams;
127   
128   CFileItemList channels;
129   if (channelGroup->GetMembers(channels) < 0)
130     return InvalidParams;
131   
132   HandleFileItemList("channelid", false, "channels", channels, parameterObject, result, true);
133     
134   return OK;
135 }
136
137 JSONRPC_STATUS CPVROperations::GetChannelDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
138 {
139   if (!g_PVRManager.IsStarted())
140     return FailedToExecute;
141   
142   CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups;
143   if (channelGroupContainer == NULL)
144     return FailedToExecute;
145   
146   CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["channelid"].asInteger());
147   if (channel == NULL)
148     return InvalidParams;
149
150   HandleFileItem("channelid", false, "channeldetails", CFileItemPtr(new CFileItem(*channel)), parameterObject, parameterObject["properties"], result, false);
151     
152   return OK;
153 }
154
155 JSONRPC_STATUS CPVROperations::GetBroadcasts(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
156 {
157   if (!g_PVRManager.IsStarted())
158     return FailedToExecute;
159
160   CPVRChannelGroupsContainer *channelGroupContainer = g_PVRManager.ChannelGroups();
161   if (channelGroupContainer == NULL)
162     return FailedToExecute;
163
164   CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["channelid"].asInteger());
165   if (channel == NULL)
166     return InvalidParams;
167
168   CEpg *channelEpg = channel->GetEPG();
169   if (channelEpg == NULL)
170     return InternalError;
171
172   CFileItemList programFull;
173   channelEpg->Get(programFull);
174
175   HandleFileItemList("broadcastid", false, "broadcasts", programFull, parameterObject, result, programFull.Size(), true);
176
177   return OK;
178 }
179
180 JSONRPC_STATUS CPVROperations::GetBroadcastDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
181 {
182   if (!g_PVRManager.IsStarted())
183     return FailedToExecute;
184
185   EpgSearchFilter filter;
186   filter.Reset();
187   filter.m_iUniqueBroadcastId = (int)parameterObject["broadcastid"].asInteger();
188
189   CFileItemList broadcasts;
190   int resultSize = g_EpgContainer.GetEPGSearch(broadcasts, filter);
191
192   if (resultSize <= 0)
193     return InvalidParams;
194   else if (resultSize > 1)
195     return InternalError;
196
197   CFileItemPtr broadcast = broadcasts.Get(0);
198   HandleFileItem("broadcastid", false, "broadcastdetails", broadcast, parameterObject, parameterObject["properties"], result, false);
199
200   return OK;
201 }
202
203
204 JSONRPC_STATUS CPVROperations::Record(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
205 {
206   if (!g_PVRManager.IsStarted())
207     return FailedToExecute;
208
209   CPVRChannelPtr pChannel;
210   CVariant channel = parameterObject["channel"];
211   if (channel.isString() && channel.asString() == "current")
212   {
213     if (!g_PVRManager.GetCurrentChannel(pChannel))
214       return InternalError;
215   }
216   else if (channel.isInteger())
217   {
218     CPVRChannelGroupsContainer *channelGroupContainer = g_PVRManager.ChannelGroups();
219     if (channelGroupContainer == NULL)
220       return FailedToExecute;
221
222     pChannel = channelGroupContainer->GetChannelById((int)channel.asInteger());
223   }
224   else
225     return InvalidParams;
226
227   if (pChannel == NULL)
228     return InvalidParams;
229   else if (!pChannel->CanRecord())
230     return FailedToExecute;
231
232   CVariant record = parameterObject["record"];
233   bool toggle = true;
234   if (record.isBoolean() && record.asBoolean() == pChannel->IsRecording())
235     toggle = false;
236
237   if (toggle)
238   {
239     if (!g_PVRManager.ToggleRecordingOnChannel(pChannel->ChannelID()))
240       return FailedToExecute;
241   }
242
243   return ACK;
244 }
245
246 JSONRPC_STATUS CPVROperations::Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
247 {
248   if (!g_PVRManager.IsStarted())
249     return FailedToExecute;
250
251   if (!g_PVRManager.IsRunningChannelScan())
252     g_PVRManager.StartChannelScan();
253
254   return ACK;
255 }
256
257 JSONRPC_STATUS CPVROperations::GetPropertyValue(const CStdString &property, CVariant &result)
258 {
259   bool started = g_PVRManager.IsStarted();
260
261   if (property.Equals("available"))
262     result = started;
263   else if (property.Equals("recording"))
264   {
265     if (started)
266       result = g_PVRManager.IsRecording();
267     else
268       result = false;
269   }
270   else if (property.Equals("scanning"))
271   {
272     if (started)
273       result = g_PVRManager.IsRunningChannelScan();
274     else
275       result = false;
276   }
277   else
278     return InvalidParams;
279
280   return OK;
281 }
282
283 void CPVROperations::FillChannelGroupDetails(const CPVRChannelGroupPtr &channelGroup, const CVariant &parameterObject, CVariant &result, bool append /* = false */)
284 {
285   if (channelGroup == NULL)
286     return;
287
288   CVariant object(CVariant::VariantTypeObject);
289   object["channelgroupid"] = channelGroup->GroupID();
290   object["channeltype"] = channelGroup->IsRadio() ? "radio" : "tv";
291   object["label"] = channelGroup->GroupName();
292
293   if (append)
294     result.append(object);
295   else
296   {
297     CFileItemList channels;
298     channelGroup->GetMembers(channels);
299     object["channels"] = CVariant(CVariant::VariantTypeArray);
300     HandleFileItemList("channelid", false, "channels", channels, parameterObject["channels"], object, false);
301
302     result = object;
303   }
304 }
305
306 JSONRPC_STATUS CPVROperations::GetTimers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
307 {
308   if (!g_PVRManager.IsStarted())
309     return FailedToExecute;
310
311   CPVRTimers* timers = g_PVRTimers;
312   if (!timers)
313     return FailedToExecute;
314
315   CFileItemList timerList;
316   timers->GetAll(timerList);
317
318   HandleFileItemList("timerid", false, "timers", timerList, parameterObject, result, true);
319
320   return OK;
321 }
322
323 JSONRPC_STATUS CPVROperations::GetTimerDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
324 {
325   if (!g_PVRManager.IsStarted())
326     return FailedToExecute;
327
328   CPVRTimers* timers = g_PVRTimers;
329   if (!timers)
330     return FailedToExecute;
331
332   CPVRTimerInfoTagPtr timer = timers->GetById((int)parameterObject["timerid"].asInteger());
333   if (!timer)
334     return InvalidParams;
335
336   HandleFileItem("timerid", false, "timerdetails", CFileItemPtr(new CFileItem(*timer)), parameterObject, parameterObject["properties"], result, false);
337
338   return OK;
339 }
340
341 JSONRPC_STATUS CPVROperations::GetRecordings(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
342 {
343   if (!g_PVRManager.IsStarted())
344     return FailedToExecute;
345
346   CPVRRecordings* recordings = g_PVRRecordings;
347   if (!recordings)
348     return FailedToExecute;
349
350   CFileItemList recordingsList;
351   recordings->GetAll(recordingsList);
352
353   HandleFileItemList("recordingid", true, "recordings", recordingsList, parameterObject, result, true);
354
355   return OK;
356 }
357
358 JSONRPC_STATUS CPVROperations::GetRecordingDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
359 {
360   if (!g_PVRManager.IsStarted())
361     return FailedToExecute;
362
363   CPVRRecordings* recordings = g_PVRRecordings;
364   if (!recordings)
365     return FailedToExecute;
366
367   CFileItemPtr recording = recordings->GetById((int)parameterObject["recordingid"].asInteger());
368   if (!recording)
369     return InvalidParams;
370
371   HandleFileItem("recordingid", true, "recordingdetails", recording, parameterObject, parameterObject["properties"], result, false);
372
373   return OK;
374 }