6 #include <jsoncpp/json/json.h>
9 #include <vdr/videodir.h>
10 #include <vdr/recording.h>
12 #include <vdr/timers.h>
16 int jsonserver_request_handler(struct mg_connection *conn)
18 Log* log = Log::getInstance();
19 const struct mg_request_info *request_info = mg_get_request_info(conn);
21 if (strcmp(request_info->uri, "/jsonserver")) return 0; // not for us
24 int wvrl = mg_get_var(request_info->query_string, strlen(request_info->query_string), "req", wvrequest, 20);
27 log->log("JSONServer", Log::ERR, "Could not decode req");
32 if (!strcmp(request_info->request_method, "OPTIONS"))
34 mg_printf(conn, "%s", "HTTP/1.0 200 OK\r\n");
35 mg_printf(conn, "%s", "Access-Control-Allow-Origin: *\r\n");
36 mg_printf(conn, "%s", "Content-Type: text/plain\r\n\r\n");
44 if (!strcmp(request_info->request_method, "POST"))
46 const char* contentLength = mg_get_header(conn, "Content-Length");
47 int contentLengthI = atoi(contentLength);
48 log->log("JSONServer", Log::DEBUG, "POST data content length: %i", contentLengthI);
49 if (contentLengthI > 10000)
51 log->log("JSONServer", Log::DEBUG, "Length > 10000, rejecting");
55 if (contentLengthI > 0)
57 // FIXME - assume for now that all post data will be small enough to have arrived immediately
58 int bytesRead = mg_read(conn, postData, contentLengthI);
59 if (bytesRead != contentLengthI)
61 log->log("JSONServer", Log::DEBUG, "Could not read up to contentLength");
64 postData[contentLengthI] = '\0';
71 if (!strcmp(wvrequest, "gettime")) success = jsonserver_gettime(js);
72 else if (!strcmp(wvrequest, "diskstats")) success = jsonserver_diskstats(js);
73 else if (!strcmp(wvrequest, "reclist")) success = jsonserver_reclist(js);
74 else if (!strcmp(wvrequest, "recinfo")) success = jsonserver_recinfo(js, postData);
75 else if (!strcmp(wvrequest, "recdel")) success = jsonserver_recdel(js, postData);
76 else if (!strcmp(wvrequest, "recmove")) success = jsonserver_recmove(js, postData);
77 else if (!strcmp(wvrequest, "recstop")) success = jsonserver_recstop(js, postData);
78 else if (!strcmp(wvrequest, "channellist")) success = jsonserver_channellist(js);
79 else if (!strcmp(wvrequest, "channelschedule")) success = jsonserver_channelschedule(js, postData);
80 else if (!strcmp(wvrequest, "getscheduleevent")) success = jsonserver_getscheduleevent(js, postData);
81 else if (!strcmp(wvrequest, "timerlist")) success = jsonserver_timerlist(js);
82 else if (!strcmp(wvrequest, "timerdel")) success = jsonserver_timerdel(js, postData);
83 else if (!strcmp(wvrequest, "timerset")) success = jsonserver_timerset(js, postData);
84 else if (!strcmp(wvrequest, "timersetactive")) success = jsonserver_timersetactive(js, postData);
86 if (!success) return 0; // the specific handler failed badly
88 // Now js will be filled
90 Json::StyledWriter sw;
91 std::string jsonout = sw.write(js);
92 mg_printf(conn, "%s", "HTTP/1.0 200 OK\r\n");
93 mg_printf(conn, "%s", "Content-Type: text/plain\r\n\r\n");
94 mg_write(conn, jsonout.c_str(), jsonout.length());
99 else if (event == MG_EVENT_LOG)
101 if (request_info->status_code == 400) // bad request
103 log->log("Mongoose", Log::DEBUG, "400 BAD REQUEST:");
104 log->log("Mongoose", Log::DEBUG, request_info->request_method);
105 log->log("Mongoose", Log::DEBUG, request_info->uri);
106 log->log("Mongoose", Log::DEBUG, request_info->http_version);
107 log->log("Mongoose", Log::DEBUG, request_info->query_string);
108 log->log("Mongoose", Log::DEBUG, request_info->log_message);
109 for (int i = 0; i < request_info->num_headers; i++)
111 log->log("Mongoose", Log::DEBUG, "%s: %s", request_info->http_headers[i].name, request_info->http_headers[i].value);
116 log->log("Mongoose", Log::DEBUG, request_info->log_message);
117 log->log("Mongoose", Log::DEBUG, request_info->uri);
122 // other events not handled:
123 // MG_HTTP_ERROR, MG_INIT_SSL
124 // Let mongoose do something with those
132 bool jsonserver_gettime(Json::Value& js)
134 Log* log = Log::getInstance();
135 log->log("JSONServer", Log::DEBUG, "gettime");
138 gettimeofday(&tv, NULL);
140 js["Time"] = (Json::UInt64)tv.tv_sec;
141 js["MTime"] = (Json::UInt)(tv.tv_usec/1000);
146 bool jsonserver_diskstats(Json::Value& js)
148 Log* log = Log::getInstance();
149 log->log("JSONServer", Log::DEBUG, "diskstats");
153 int Percent = VideoDiskSpace(&FreeMB, &UsedMB);
155 js["FreeMiB"] = FreeMB;
156 js["UsedMiB"] = UsedMB;
157 js["Percent"] = Percent;
163 bool jsonserver_reclist(Json::Value& js)
165 Log* log = Log::getInstance();
166 log->log("JSONServer", Log::DEBUG, "reclist");
168 Json::Value jsrecordings;
169 cRecordings Recordings;
171 for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording))
174 oneRec["StartTime"] = (Json::UInt)recording->Start();
175 oneRec["Length"] = (Json::UInt)recording->LengthInSeconds();
176 oneRec["IsNew"] = recording->IsNew();
177 oneRec["Name"] = recording->Name();
178 oneRec["Filename"] = recording->FileName();
179 oneRec["FileSizeMB"] = recording->FileSizeMB();
180 jsrecordings.append(oneRec);
182 js["Recordings"] = jsrecordings;
187 bool jsonserver_recinfo(Json::Value& js, const char* postData)
189 Log* log = Log::getInstance();
190 log->log("JSONServer", Log::DEBUG, "recinfo");
192 char reqfilename[1000];
193 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
196 log->log("JSONServer", Log::ERR, "Could not decode filename");
197 js["Result"] = false;
198 js["Error"] = "Could not decode filename";
202 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
204 cRecordings Recordings;
205 Recordings.Load(); // probably have to do this
206 cRecording *recording = Recordings.GetByName(reqfilename);
210 log->log("JSONServer", Log::ERR, "recinfo found no recording");
211 js["Result"] = false;
215 js["IsNew"] = recording->IsNew();
216 js["LengthInSeconds"] = recording->LengthInSeconds();
217 js["FileSizeMB"] = recording->FileSizeMB();
218 js["Name"] = recording->Name() ? recording->Name() : Json::Value::null;
219 js["Priority"] = recording->Priority();
220 js["LifeTime"] = recording->Lifetime();
221 js["Start"] = (Json::UInt)recording->Start();
223 js["ResumePoint"] = 0;
224 cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording());
225 if (ResumeFile.Read() >= 0) js["ResumePoint"] = ResumeFile.Read();
227 js["CurrentlyRecordingStart"] = 0;
228 js["CurrentlyRecordingStop"] = 0;
229 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
232 js["CurrentlyRecordingStart"] = (Json::UInt)rc->Timer()->StartTime();
233 js["CurrentlyRecordingStop"] = (Json::UInt)rc->Timer()->StopTime();
236 const cRecordingInfo *info = recording->Info();
239 js["ChannelName"] = info->ChannelName() ? info->ChannelName() : Json::Value::null;
240 js["Title"] = info->Title() ? info->Title() : Json::Value::null;
241 js["ShortText"] = info->ShortText() ? info->ShortText() : Json::Value::null;
242 js["Description"] = info->Description() ? info->Description() : Json::Value::null;
244 const cComponents* components = info->Components();
247 js["Components"] = Json::Value::null;
251 Json::Value jscomponents;
253 tComponent* component;
254 for (int i = 0; i < components->NumComponents(); i++)
256 component = components->Component(i);
258 Json::Value oneComponent;
259 oneComponent["Stream"] = component->stream;
260 oneComponent["Type"] = component->type;
261 oneComponent["Language"] = component->language ? component->language : Json::Value::null;
262 oneComponent["Description"] = component->description ? component->description : Json::Value::null;
263 jscomponents.append(oneComponent);
266 js["Components"] = jscomponents;
274 bool jsonserver_recstop(Json::Value& js, const char* postData)
276 Log* log = Log::getInstance();
277 log->log("JSONServer", Log::DEBUG, "recstop");
279 char reqfilename[1000];
280 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
283 log->log("JSONServer", Log::ERR, "Could not decode filename");
284 js["Result"] = false;
285 js["Error"] = "Could not decode filename";
289 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
291 cRecordings Recordings;
292 Recordings.Load(); // probably have to do this
293 cRecording *recording = Recordings.GetByName(reqfilename);
297 log->log("JSONServer", Log::ERR, "recstop found no recording");
298 js["Result"] = false;
302 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
305 log->log("JSONServer", Log::ERR, "recstop - not currently recording");
306 js["Result"] = false;
310 if (Timers.BeingEdited())
312 log->log("JSONServer", Log::ERR, "recstop - timers being edited elsewhere");
313 js["Result"] = false;
317 cTimer* timer = rc->Timer();
320 log->log("JSONServer", Log::ERR, "recstop - timer not found");
321 js["Result"] = false;
325 timer->ClrFlags(tfActive);
326 Timers.SetModified();
332 bool jsonserver_recdel(Json::Value& js, const char* postData)
334 Log* log = Log::getInstance();
335 log->log("JSONServer", Log::DEBUG, "recdel");
337 char reqfilename[1000];
338 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
341 log->log("JSONServer", Log::ERR, "Could not decode filename");
342 js["Result"] = false;
343 js["Error"] = "Could not decode filename";
347 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
349 cRecordings Recordings;
350 Recordings.Load(); // probably have to do this
351 cRecording *recording = Recordings.GetByName(reqfilename);
355 js["Result"] = false;
356 js["Error"] = "Could not find recording to delete";
360 log->log("JSONServer", Log::DEBUG, "Deleting recording: %s", recording->Name());
361 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
364 js["Result"] = false;
365 js["Error"] = "This recording is still recording.. ho ho";
369 if (recording->Delete())
371 ::Recordings.DelByName(recording->FileName());
376 js["Result"] = false;
377 js["Error"] = "Failed to delete recording";
383 bool jsonserver_recmove(Json::Value& js, const char* postData)
385 Log* log = Log::getInstance();
386 log->log("JSONServer", Log::DEBUG, "recmove");
388 char* fileNameToMove = NULL;
389 char* requestedNewPath = NULL;
390 char* dateDirName = NULL;
391 char* titleDirName = NULL;
392 char* folderName = NULL;
393 char* newContainer = NULL;
398 int postDataLen = strlen(postData)+1;
399 fileNameToMove = new char[postDataLen];
400 int mgv1 = mg_get_var(postData, postDataLen-1, "filename", fileNameToMove, postDataLen);
401 requestedNewPath = new char[postDataLen];
402 int mgv2 = mg_get_var(postData, postDataLen-1, "newpath", requestedNewPath, postDataLen);
404 if ((mgv1 == -1) || (mgv2 == -1) || !strlen(fileNameToMove) || !strlen(requestedNewPath))
406 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
410 cRecordings Recordings;
411 Recordings.Load(); // probably have to do this
412 cRecording* recordingObj = Recordings.GetByName(fileNameToMove);
413 if (!recordingObj) throw 2;
415 cRecordControl *rc = cRecordControls::GetRecordControl(recordingObj->FileName());
418 log->log("JSONServer", Log::DEBUG, "moving recording: %s", recordingObj->Name());
419 log->log("JSONServer", Log::DEBUG, "moving recording: %s", recordingObj->FileName());
420 log->log("JSONServer", Log::DEBUG, "to: %s", requestedNewPath);
422 const char* t = recordingObj->FileName();
426 // Find the datedirname
427 for(k = strlen(t) - 1; k >= 0; k--)
431 log->log("JSONServer", Log::DEBUG, "l1: %i", strlen(&t[k+1]) + 1);
432 dateDirName = new char[strlen(&t[k+1]) + 1];
433 strcpy(dateDirName, &t[k+1]);
438 // Find the titledirname
440 for(j = k-1; j >= 0; j--)
444 log->log("JSONServer", Log::DEBUG, "l2: %i", k - j);
445 titleDirName = new char[k - j];
446 memcpy(titleDirName, &t[j+1], k - j - 1);
447 titleDirName[k - j - 1] = '\0';
452 // Find the foldername
454 log->log("JSONServer", Log::DEBUG, "j = %u, strlenvd = %u", j, strlen(VideoDirectory));
455 if (j > (int)strlen(VideoDirectory)) // Rec is in a subfolder now
457 for(m = j-1; m >= 0; m--)
461 log->log("JSONServer", Log::DEBUG, "l3: %i", j - m);
462 folderName = new char[j - m];
463 memcpy(folderName, &t[m+1], j - m - 1);
464 folderName[j - m - 1] = '\0';
470 ExchangeChars(requestedNewPath, true);
472 log->log("JSONServer", Log::DEBUG, "datedirname: %s", dateDirName);
473 log->log("JSONServer", Log::DEBUG, "titledirname: %s", titleDirName);
474 log->log("JSONServer", Log::DEBUG, "viddir: %s", VideoDirectory);
475 if (folderName) log->log("JSONServer", Log::DEBUG, "folderName: %s", folderName);
476 log->log("JSONServer", Log::DEBUG, "EC: %s", requestedNewPath);
478 // Could be a new path - construct that first and test
479 newContainer = new char[strlen(VideoDirectory) + strlen(requestedNewPath) + strlen(titleDirName) + 1];
480 sprintf(newContainer, "%s%s", VideoDirectory, requestedNewPath);
481 log->log("JSONServer", Log::DEBUG, "NPT: %s", newContainer);
483 int statret = stat(newContainer, &dstat);
484 if ((statret == -1) && (errno == ENOENT)) // Dir does not exist
486 log->log("JSONServer", Log::DEBUG, "new path does not exist (1)");
487 int mkdirret = mkdir(newContainer, 0755);
488 if (mkdirret != 0) throw 4;
490 else if ((statret == 0) && (! (dstat.st_mode && S_IFDIR)))
492 // Something exists but it's not a dir
496 // New path now created or was there already
498 sprintf(newContainer, "%s%s%s", VideoDirectory, requestedNewPath, titleDirName);
499 log->log("JSONServer", Log::DEBUG, "%s", newContainer);
501 statret = stat(newContainer, &dstat);
502 if ((statret == -1) && (errno == ENOENT)) // Dir does not exist
504 log->log("JSONServer", Log::DEBUG, "new dir does not exist (2)");
505 int mkdirret = mkdir(newContainer, 0755);
506 if (mkdirret != 0) throw 6;
508 else if ((statret == 0) && (! (dstat.st_mode && S_IFDIR)))
510 // Something exists but it's not a dir
514 // Ok, the directory container has been made, or it pre-existed.
516 newDir = new char[strlen(newContainer) + 1 + strlen(dateDirName) + 1];
517 sprintf(newDir, "%s/%s", newContainer, dateDirName);
519 log->log("JSONServer", Log::DEBUG, "doing rename '%s' '%s'", t, newDir);
520 if (rename(t, newDir) != 0) throw 8;
522 // Success. Test for remove old dir containter
523 char* tempOldTitleDir = new char[k+1];
524 memcpy(tempOldTitleDir, t, k);
525 tempOldTitleDir[k] = '\0';
526 log->log("JSONServer", Log::DEBUG, "len: %i, cp: %i, strlen: %i, oldtitledir: %s", k+1, k, strlen(tempOldTitleDir), tempOldTitleDir);
527 rmdir(tempOldTitleDir); // can't do anything about a fail result at this point.
528 delete[] tempOldTitleDir;
530 // Test for remove old foldername
533 char* tempOldFolderName = new char[j+1];
534 memcpy(tempOldFolderName, t, j);
535 tempOldFolderName[j] = '\0';
536 log->log("JSONServer", Log::DEBUG, "len: %i, cp: %i, strlen: %i, oldfoldername: %s", j+1, j, strlen(tempOldFolderName), tempOldFolderName);
539 rmdir() deletes a directory, which must be empty.
540 ENOTEMPTY - pathname contains entries other than . and ..
541 So, should be safe to call rmdir on non-empty dir
543 rmdir(tempOldFolderName); // can't do anything about a fail result at this point.
544 delete[] tempOldFolderName;
547 ::Recordings.Update();
549 js["NewRecordingFileName"] = newDir;
553 js["Result"] = false;
556 log->log("JSONServer", Log::ERR, "Bad parameters");
557 js["Error"] = "Bad request parameters";
561 log->log("JSONServer", Log::ERR, "Could not find recording to move");
562 js["Error"] = "Bad filename";
566 log->log("JSONServer", Log::ERR, "Could not move recording, it is still recording");
567 js["Error"] = "Cannot move recording in progress";
571 log->log("JSONServer", Log::ERR, "Failed to make new dir (1)");
572 js["Error"] = "Failed to create new directory (1)";
576 log->log("JSONServer", Log::ERR, "Something already exists? (1)");
577 js["Error"] = "Something already exists at the new path (1)";
581 log->log("JSONServer", Log::ERR, "Failed to make new dir (2)");
582 js["Error"] = "Failed to create new directory (2)";
586 log->log("JSONServer", Log::ERR, "Something already exists?");
587 js["Error"] = "Something already exists at the new path";
591 log->log("JSONServer", Log::ERR, "Rename failed");
592 js["Error"] = "Move failed";
596 if (fileNameToMove) delete[] fileNameToMove;
597 if (requestedNewPath) delete[] requestedNewPath;
598 if (dateDirName) delete[] dateDirName;
599 if (titleDirName) delete[] titleDirName;
600 if (folderName) delete[] folderName;
601 if (newContainer) delete[] newContainer;
602 if (newDir) delete[] newDir;
607 bool jsonserver_channellist(Json::Value& js)
609 Log* log = Log::getInstance();
610 log->log("JSONServer", Log::DEBUG, "channellist");
612 Json::Value jschannels;
615 for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
617 if (!channel->GroupSep())
619 // log->log("JSONServer", Log::DEBUG, "name: '%s'", channel->Name());
621 // if (channel->Vpid()) type = 1;
622 // else if (channel->Apid(0)) type = 2;
625 Json::Value oneChannel;
626 oneChannel["Number"] = channel->Number();
627 // oneChannel["Type"] = type;
628 oneChannel["Name"] = channel->Name();
629 //#if VDRVERSNUM < 10703
630 // oneChannel["VType"] = 2;
632 // oneChannel["VType"] = channel->Vtype();
634 jschannels.append(oneChannel);
637 js["Channels"] = jschannels;
642 bool jsonserver_channelschedule(Json::Value& js, const char* postData)
644 Log* log = Log::getInstance();
645 log->log("JSONServer", Log::DEBUG, "channelschedule '%s'", postData);
647 char sChannelNumber[15]; int mgv1 = mg_get_var(postData, strlen(postData), "channelnumber", sChannelNumber, 15);
648 char sStartTime[15]; int mgv2 = mg_get_var(postData, strlen(postData), "starttime", sStartTime, 15);
649 char sDuration[15]; int mgv3 = mg_get_var(postData, strlen(postData), "duration", sDuration, 15);
651 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) )
653 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i", mgv1, mgv2, mgv3);
654 js["Result"] = false;
655 js["Error"] = "Bad request parameters";
659 int channelNumber = atoi(sChannelNumber);
660 int startTime = atoi(sStartTime);
661 int duration = atoi(sDuration);
663 cChannel* channel = NULL;
664 for (channel = Channels.First(); channel; channel = Channels.Next(channel))
666 if (channel->GroupSep()) continue;
667 if (channel->Number() == channelNumber) break;
672 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
673 js["Result"] = false;
674 js["Error"] = "Could not find channel";
678 cSchedulesLock MutexLock;
679 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
682 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
683 js["Result"] = false;
684 js["Error"] = "Internal schedules error (1)";
687 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
690 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
691 js["Result"] = false;
692 js["Error"] = "Internal schedules error (2)";
696 Json::Value jsevents;
698 for (const cEvent* event = Schedule->Events()->First(); event; event = Schedule->Events()->Next(event))
701 if ((event->StartTime() + event->Duration()) < time(NULL)) continue;
703 if ((event->StartTime() + event->Duration()) <= startTime) continue;
705 if (event->StartTime() >= (startTime + duration)) continue;
707 Json::Value oneEvent;
708 oneEvent["ID"] = event->EventID();
709 oneEvent["Time"] = (Json::UInt)event->StartTime();
710 oneEvent["Duration"] = event->Duration();
711 oneEvent["Title"] = event->Title() ? event->Title() : "";
712 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
713 //oneEvent["Description"] = event->Description() ? event->Description() : "";
714 jsevents.append(oneEvent);
718 js["Events"] = jsevents;
722 bool jsonserver_getscheduleevent(Json::Value& js, const char* postData)
724 Log* log = Log::getInstance();
725 log->log("JSONServer", Log::DEBUG, "getscheduleevent '%s'", postData);
727 char sChannelNumber[15]; int mgv1 = mg_get_var(postData, strlen(postData), "channelnumber", sChannelNumber, 15);
728 char sEventID[15]; int mgv2 = mg_get_var(postData, strlen(postData), "eventid", sEventID, 15);
730 if ( (mgv1 == -1) || (mgv2 == -1) )
732 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
733 js["Result"] = false;
734 js["Error"] = "Bad request parameters";
738 int channelNumber = atoi(sChannelNumber);
739 int eventID = atoi(sEventID);
741 cChannel* channel = NULL;
742 for (channel = Channels.First(); channel; channel = Channels.Next(channel))
744 if (channel->GroupSep()) continue;
745 if (channel->Number() == channelNumber) break;
750 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
751 js["Result"] = false;
752 js["Error"] = "Could not find channel";
756 cSchedulesLock MutexLock;
757 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
760 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
761 js["Result"] = false;
762 js["Error"] = "Internal schedules error (1)";
765 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
768 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
769 js["Result"] = false;
770 js["Error"] = "Internal schedules error (2)";
774 const cEvent* event = Schedule->GetEvent(eventID);
777 log->log("JSONServer", Log::ERR, "Could not find requested event: %i", eventID);
778 js["Result"] = false;
779 js["Error"] = "Internal schedules error (3)";
783 Json::Value oneEvent;
784 oneEvent["ID"] = event->EventID();
785 oneEvent["Time"] = (Json::UInt)event->StartTime();
786 oneEvent["Duration"] = event->Duration();
787 oneEvent["Title"] = event->Title() ? event->Title() : "";
788 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
789 oneEvent["Description"] = event->Description() ? event->Description() : "";
790 oneEvent["HasTimer"] = event->HasTimer();
791 oneEvent["RunningStatus"] = event->RunningStatus();
794 js["Event"] = oneEvent;
798 bool jsonserver_timerlist(Json::Value& js)
800 Log* log = Log::getInstance();
801 log->log("JSONServer", Log::DEBUG, "timerlist");
803 Json::Value jstimers;
806 int numTimers = Timers.Count();
808 for (int i = 0; i < numTimers; i++)
810 timer = Timers.Get(i);
811 Json::Value oneTimer;
812 oneTimer["Active"] = timer->HasFlags(tfActive);
813 oneTimer["Recording"] = timer->Recording();
814 oneTimer["Pending"] = timer->Pending();
815 oneTimer["Priority"] = timer->Priority();
816 oneTimer["Lifetime"] = timer->Lifetime();
817 oneTimer["ChannelNumber"] = timer->Channel()->Number();
818 oneTimer["ChannelID"] = (const char *)timer->Channel()->GetChannelID().ToString();
819 oneTimer["StartTime"] = (int)timer->StartTime();
820 oneTimer["StopTime"] = (int)timer->StopTime();
821 oneTimer["Day"] = (int)timer->Day();
822 oneTimer["WeekDays"] = timer->WeekDays();
823 oneTimer["Name"] = timer->File();
824 jstimers.append(oneTimer);
827 js["Timers"] = jstimers;
832 bool jsonserver_timerdel(Json::Value& js, const char* postData)
834 Log* log = Log::getInstance();
835 log->log("JSONServer", Log::DEBUG, "timerdel");
837 char sdelChannel[15]; int mgv1 = mg_get_var(postData, strlen(postData), "delchannel", sdelChannel, 15);
838 char sdelWeekdays[15]; int mgv2 = mg_get_var(postData, strlen(postData), "delweekdays", sdelWeekdays, 15);
839 char sdelDay[15]; int mgv3 = mg_get_var(postData, strlen(postData), "delday", sdelDay, 15);
840 char sdelStart[15]; int mgv4 = mg_get_var(postData, strlen(postData), "delstart", sdelStart, 15);
841 char sdelStop[15]; int mgv5 = mg_get_var(postData, strlen(postData), "delstop", sdelStop, 15);
843 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) || (mgv4 == -1) || (mgv5 == -1) )
845 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i %i", mgv1, mgv2, mgv3, mgv4, mgv5);
846 js["Result"] = false;
847 js["Error"] = "Bad request parameters";
851 int delChannel = atoi(sdelChannel);
852 int delWeekdays = atoi(sdelWeekdays);
853 int delDay = atoi(sdelDay);
854 int delStart = atoi(sdelStart);
855 int delStop = atoi(sdelStop);
858 for (ti = Timers.First(); ti; ti = Timers.Next(ti))
860 if ( (ti->Channel()->Number() == delChannel)
861 && ((ti->WeekDays() && (ti->WeekDays() == delWeekdays)) || (!ti->WeekDays() && (ti->Day() == delDay)))
862 && (ti->StartTime() == delStart)
863 && (ti->StopTime() == delStop) )
869 log->log("JSONServer", Log::ERR, "Could not find timer");
870 js["Result"] = false;
871 js["Error"] = "Could not find timer";
875 if (Timers.BeingEdited())
877 log->log("JSONServer", Log::ERR, "Unable to delete timer - timers being edited at VDR");
878 js["Result"] = false;
879 js["Error"] = "Timers being edited at VDR";
885 log->log("JSONServer", Log::ERR, "Unable to delete timer - timer is running");
886 js["Result"] = false;
887 js["Error"] = "Timer is running";
892 Timers.SetModified();
898 bool jsonserver_timerset(Json::Value& js, const char* postData)
900 Log* log = Log::getInstance();
901 log->log("JSONServer", Log::DEBUG, "timerset");
903 char sTimerString[1024]; int mgv1 = mg_get_var(postData, strlen(postData), "timerstring", sTimerString, 1024);
907 log->log("JSONServer", Log::ERR, "Could not get timerstring");
908 js["Result"] = false;
909 js["Error"] = "Bad request parameters";
913 log->log("JSONServer", Log::DEBUG, "'%s'", sTimerString);
914 cTimer *timer = new cTimer;
915 if (!timer->Parse(sTimerString))
918 js["Result"] = false;
919 js["Error"] = "Failed to parse timer request details";
923 cTimer *t = Timers.GetTimer(timer);
927 js["Result"] = false;
928 js["Error"] = "Timer already exists";
933 Timers.SetModified();
938 bool jsonserver_timersetactive(Json::Value& js, const char* postData)
940 Log* log = Log::getInstance();
941 log->log("JSONServer", Log::DEBUG, "timersetactive");
943 char tChannelID[30]; int mgv1 = mg_get_var(postData, strlen(postData), "ChannelID", tChannelID, 30);
944 char tStartTime[15]; int mgv2 = mg_get_var(postData, strlen(postData), "StartTime", tStartTime, 15);
945 char tStopTime[15]; int mgv3 = mg_get_var(postData, strlen(postData), "StopTime", tStopTime, 15);
946 char tNewActive[15]; int mgv4 = mg_get_var(postData, strlen(postData), "SetActive", tNewActive, 15);
948 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) || (mgv4 == -1) )
950 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i", mgv1, mgv2, mgv3, mgv4);
951 js["Result"] = false;
952 js["Error"] = "Bad request parameters";
956 log->log("JSONServer", Log::DEBUG, "timersetactive: %s %s %s %s", tChannelID, tStartTime, tStopTime, tNewActive);
958 int StartTime = atoi(tStartTime);
959 int StopTime = atoi(tStopTime);
962 int numTimers = Timers.Count();
963 for (int i = 0; i < numTimers; i++)
965 timer = Timers.Get(i);
966 if ( (strcmp(timer->Channel()->GetChannelID().ToString(), tChannelID) == 0)
967 && (timer->StartTime() == StartTime)
968 && (timer->StopTime() == StopTime)
973 if (strcmp(tNewActive, "true") == 0)
975 timer->SetFlags(tfActive);
977 else if (strcmp(tNewActive, "false") == 0)
979 timer->ClrFlags(tfActive);
983 js["Result"] = false;
984 js["Error"] = "Bad request parameters";
987 Timers.SetModified();
994 js["Result"] = false;
995 js["Error"] = "Timer not found";