5 #include <jsoncpp/json/json.h>
8 #include <vdr/videodir.h>
9 #include <vdr/recording.h>
11 #include <vdr/timers.h>
15 int jsonserver_request_handler(struct mg_connection *conn)
17 Log* log = Log::getInstance();
18 const struct mg_request_info *request_info = mg_get_request_info(conn);
20 if (strcmp(request_info->uri, "/jsonserver")) return 0; // not for us
23 int wvrl = mg_get_var(request_info->query_string, strlen(request_info->query_string), "req", wvrequest, 20);
26 log->log("JSONServer", Log::ERR, "Could not decode req");
31 if (!strcmp(request_info->request_method, "OPTIONS"))
33 mg_printf(conn, "%s", "HTTP/1.0 200 OK\r\n");
34 mg_printf(conn, "%s", "Access-Control-Allow-Origin: *\r\n");
35 mg_printf(conn, "%s", "Content-Type: text/plain\r\n\r\n");
43 if (!strcmp(request_info->request_method, "POST"))
45 const char* contentLength = mg_get_header(conn, "Content-Length");
46 int contentLengthI = atoi(contentLength);
47 log->log("JSONServer", Log::DEBUG, "POST data content length: %i", contentLengthI);
48 if (contentLengthI > 10000)
50 log->log("JSONServer", Log::DEBUG, "Length > 10000, rejecting");
54 if (contentLengthI > 0)
56 // FIXME - assume for now that all post data will be small enough to have arrived immediately
57 int bytesRead = mg_read(conn, postData, contentLengthI);
58 if (bytesRead != contentLengthI)
60 log->log("JSONServer", Log::DEBUG, "Could not read up to contentLength");
63 postData[contentLengthI] = '\0';
70 if (!strcmp(wvrequest, "reclist")) success = jsonserver_reclist(js);
71 else if (!strcmp(wvrequest, "recinfo")) success = jsonserver_recinfo(js, postData);
72 else if (!strcmp(wvrequest, "recdel")) success = jsonserver_recdel(js, postData);
73 else if (!strcmp(wvrequest, "recmove")) success = jsonserver_recmove(js, postData);
74 else if (!strcmp(wvrequest, "recstop")) success = jsonserver_recstop(js, postData);
75 else if (!strcmp(wvrequest, "channellist")) success = jsonserver_channellist(js);
76 else if (!strcmp(wvrequest, "channelschedule")) success = jsonserver_channelschedule(js, postData);
77 else if (!strcmp(wvrequest, "getscheduleevent")) success = jsonserver_getscheduleevent(js, postData);
78 else if (!strcmp(wvrequest, "timerlist")) success = jsonserver_timerlist(js);
79 else if (!strcmp(wvrequest, "timerdel")) success = jsonserver_timerdel(js, postData);
80 else if (!strcmp(wvrequest, "timerset")) success = jsonserver_timerset(js, postData);
82 if (!success) return 0; // the specific handler failed badly
84 // Now js will be filled
86 Json::StyledWriter sw;
87 std::string jsonout = sw.write(js);
88 mg_printf(conn, "%s", "HTTP/1.0 200 OK\r\n");
89 mg_printf(conn, "%s", "Content-Type: text/plain\r\n\r\n");
90 mg_write(conn, jsonout.c_str(), jsonout.length());
95 else if (event == MG_EVENT_LOG)
97 if (request_info->status_code == 400) // bad request
99 log->log("Mongoose", Log::DEBUG, "400 BAD REQUEST:");
100 log->log("Mongoose", Log::DEBUG, request_info->request_method);
101 log->log("Mongoose", Log::DEBUG, request_info->uri);
102 log->log("Mongoose", Log::DEBUG, request_info->http_version);
103 log->log("Mongoose", Log::DEBUG, request_info->query_string);
104 log->log("Mongoose", Log::DEBUG, request_info->log_message);
105 for (int i = 0; i < request_info->num_headers; i++)
107 log->log("Mongoose", Log::DEBUG, "%s: %s", request_info->http_headers[i].name, request_info->http_headers[i].value);
112 log->log("Mongoose", Log::DEBUG, request_info->log_message);
113 log->log("Mongoose", Log::DEBUG, request_info->uri);
118 // other events not handled:
119 // MG_HTTP_ERROR, MG_INIT_SSL
120 // Let mongoose do something with those
128 bool jsonserver_reclist(Json::Value& js)
130 Log* log = Log::getInstance();
131 log->log("JSONServer", Log::DEBUG, "reclist");
134 int Percent = VideoDiskSpace(&FreeMB);
135 int Total = (FreeMB / (100 - Percent)) * 100;
137 js["MBFree"] = FreeMB;
138 js["Percent"] = Percent;
141 Json::Value jsrecordings;
142 cRecordings Recordings;
144 for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording))
147 oneRec["StartTime"] = (Json::UInt)recording->Start();
148 oneRec["Length"] = (Json::UInt)recording->LengthInSeconds();
149 oneRec["IsNew"] = recording->IsNew();
150 oneRec["Name"] = recording->Name();
151 oneRec["Filename"] = recording->FileName();
152 oneRec["FileSizeMB"] = recording->FileSizeMB();
153 jsrecordings.append(oneRec);
155 js["Recordings"] = jsrecordings;
160 bool jsonserver_recinfo(Json::Value& js, const char* postData)
162 Log* log = Log::getInstance();
163 log->log("JSONServer", Log::DEBUG, "recinfo");
165 char reqfilename[1000];
166 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
169 log->log("JSONServer", Log::ERR, "Could not decode filename");
170 js["Result"] = false;
171 js["Error"] = "Could not decode filename";
175 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
177 cRecordings Recordings;
178 Recordings.Load(); // probably have to do this
179 cRecording *recording = Recordings.GetByName(reqfilename);
183 log->log("JSONServer", Log::ERR, "recinfo found no recording");
184 js["Result"] = false;
188 js["IsNew"] = recording->IsNew();
189 js["LengthInSeconds"] = recording->LengthInSeconds();
190 js["FileSizeMB"] = recording->FileSizeMB();
191 js["Name"] = recording->Name() ? recording->Name() : Json::Value::null;
192 js["Priority"] = recording->Priority();
193 js["LifeTime"] = recording->Lifetime();
194 js["Start"] = (Json::UInt)recording->Start();
196 js["ResumePoint"] = 0;
197 cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording());
198 if (ResumeFile.Read() >= 0) js["ResumePoint"] = ResumeFile.Read();
200 js["CurrentlyRecordingStart"] = 0;
201 js["CurrentlyRecordingStop"] = 0;
202 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
205 js["CurrentlyRecordingStart"] = (Json::UInt)rc->Timer()->StartTime();
206 js["CurrentlyRecordingStop"] = (Json::UInt)rc->Timer()->StopTime();
209 const cRecordingInfo *info = recording->Info();
212 js["ChannelName"] = info->ChannelName() ? info->ChannelName() : Json::Value::null;
213 js["Title"] = info->Title() ? info->Title() : Json::Value::null;
214 js["ShortText"] = info->ShortText() ? info->ShortText() : Json::Value::null;
215 js["Description"] = info->Description() ? info->Description() : Json::Value::null;
217 const cComponents* components = info->Components();
220 js["Components"] = Json::Value::null;
224 Json::Value jscomponents;
226 tComponent* component;
227 for (int i = 0; i < components->NumComponents(); i++)
229 component = components->Component(i);
231 Json::Value oneComponent;
232 oneComponent["Stream"] = component->stream;
233 oneComponent["Type"] = component->type;
234 oneComponent["Language"] = component->language ? component->language : Json::Value::null;
235 oneComponent["Description"] = component->description ? component->description : Json::Value::null;
236 jscomponents.append(oneComponent);
239 js["Components"] = jscomponents;
247 bool jsonserver_recstop(Json::Value& js, const char* postData)
249 Log* log = Log::getInstance();
250 log->log("JSONServer", Log::DEBUG, "recstop");
252 char reqfilename[1000];
253 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
256 log->log("JSONServer", Log::ERR, "Could not decode filename");
257 js["Result"] = false;
258 js["Error"] = "Could not decode filename";
262 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
264 cRecordings Recordings;
265 Recordings.Load(); // probably have to do this
266 cRecording *recording = Recordings.GetByName(reqfilename);
270 log->log("JSONServer", Log::ERR, "recstop found no recording");
271 js["Result"] = false;
275 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
278 log->log("JSONServer", Log::ERR, "recstop - not currently recording");
279 js["Result"] = false;
283 if (Timers.BeingEdited())
285 log->log("JSONServer", Log::ERR, "recstop - timers being edited elsewhere");
286 js["Result"] = false;
290 cTimer* timer = rc->Timer();
293 log->log("JSONServer", Log::ERR, "recstop - timer not found");
294 js["Result"] = false;
298 timer->ClrFlags(tfActive);
299 Timers.SetModified();
305 bool jsonserver_recdel(Json::Value& js, const char* postData)
307 Log* log = Log::getInstance();
308 log->log("JSONServer", Log::DEBUG, "recdel");
310 char reqfilename[1000];
311 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
314 log->log("JSONServer", Log::ERR, "Could not decode filename");
315 js["Result"] = false;
316 js["Error"] = "Could not decode filename";
320 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
322 cRecordings Recordings;
323 Recordings.Load(); // probably have to do this
324 cRecording *recording = Recordings.GetByName(reqfilename);
328 js["Result"] = false;
329 js["Error"] = "Could not find recording to delete";
333 log->log("JSONServer", Log::DEBUG, "Deleting recording: %s", recording->Name());
334 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
337 js["Result"] = false;
338 js["Error"] = "This recording is still recording.. ho ho";
342 if (recording->Delete())
344 ::Recordings.DelByName(recording->FileName());
349 js["Result"] = false;
350 js["Error"] = "Failed to delete recording";
356 bool jsonserver_recmove(Json::Value& js, const char* postData)
358 Log* log = Log::getInstance();
359 log->log("JSONServer", Log::DEBUG, "recmove");
361 char* fileNameToMove = NULL;
362 char* requestedNewPath = NULL;
363 char* dateDirName = NULL;
364 char* titleDirName = NULL;
365 char* folderName = NULL;
366 char* newContainer = NULL;
371 int postDataLen = strlen(postData)+1;
372 fileNameToMove = new char[postDataLen];
373 int mgv1 = mg_get_var(postData, postDataLen-1, "filename", fileNameToMove, postDataLen);
374 requestedNewPath = new char[postDataLen];
375 int mgv2 = mg_get_var(postData, postDataLen-1, "newpath", requestedNewPath, postDataLen);
377 if ((mgv1 == -1) || (mgv2 == -1) || !strlen(fileNameToMove) || !strlen(requestedNewPath))
379 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
383 cRecordings Recordings;
384 Recordings.Load(); // probably have to do this
385 cRecording* recordingObj = Recordings.GetByName(fileNameToMove);
386 if (!recordingObj) throw 2;
388 cRecordControl *rc = cRecordControls::GetRecordControl(recordingObj->FileName());
391 log->log("JSONServer", Log::DEBUG, "moving recording: %s", recordingObj->Name());
392 log->log("JSONServer", Log::DEBUG, "moving recording: %s", recordingObj->FileName());
393 log->log("JSONServer", Log::DEBUG, "to: %s", requestedNewPath);
395 const char* t = recordingObj->FileName();
399 // Find the datedirname
400 for(k = strlen(t) - 1; k >= 0; k--)
404 log->log("JSONServer", Log::DEBUG, "l1: %i", strlen(&t[k+1]) + 1);
405 dateDirName = new char[strlen(&t[k+1]) + 1];
406 strcpy(dateDirName, &t[k+1]);
411 // Find the titledirname
413 for(j = k-1; j >= 0; j--)
417 log->log("JSONServer", Log::DEBUG, "l2: %i", k - j);
418 titleDirName = new char[k - j];
419 memcpy(titleDirName, &t[j+1], k - j - 1);
420 titleDirName[k - j - 1] = '\0';
425 // Find the foldername
427 log->log("JSONServer", Log::DEBUG, "j = %u, strlenvd = %u", j, strlen(VideoDirectory));
428 if (j > strlen(VideoDirectory)) // Rec is in a subfolder now
430 for(m = j-1; m >= 0; m--)
434 log->log("JSONServer", Log::DEBUG, "l3: %i", j - m);
435 folderName = new char[j - m];
436 memcpy(folderName, &t[m+1], j - m - 1);
437 folderName[j - m - 1] = '\0';
443 ExchangeChars(requestedNewPath, true);
445 log->log("JSONServer", Log::DEBUG, "datedirname: %s", dateDirName);
446 log->log("JSONServer", Log::DEBUG, "titledirname: %s", titleDirName);
447 log->log("JSONServer", Log::DEBUG, "viddir: %s", VideoDirectory);
448 if (folderName) log->log("JSONServer", Log::DEBUG, "folderName: %s", folderName);
449 log->log("JSONServer", Log::DEBUG, "EC: %s", requestedNewPath);
451 // Could be a new path - construct that first and test
452 newContainer = new char[strlen(VideoDirectory) + strlen(requestedNewPath) + strlen(titleDirName) + 1];
453 sprintf(newContainer, "%s%s", VideoDirectory, requestedNewPath);
454 log->log("JSONServer", Log::DEBUG, "NPT: %s", newContainer);
456 int statret = stat(newContainer, &dstat);
457 if ((statret == -1) && (errno == ENOENT)) // Dir does not exist
459 log->log("JSONServer", Log::DEBUG, "new path does not exist (1)");
460 int mkdirret = mkdir(newContainer, 0755);
461 if (mkdirret != 0) throw 4;
463 else if ((statret == 0) && (! (dstat.st_mode && S_IFDIR)))
465 // Something exists but it's not a dir
469 // New path now created or was there already
471 sprintf(newContainer, "%s%s%s", VideoDirectory, requestedNewPath, titleDirName);
472 log->log("JSONServer", Log::DEBUG, "%s", newContainer);
474 statret = stat(newContainer, &dstat);
475 if ((statret == -1) && (errno == ENOENT)) // Dir does not exist
477 log->log("JSONServer", Log::DEBUG, "new dir does not exist (2)");
478 int mkdirret = mkdir(newContainer, 0755);
479 if (mkdirret != 0) throw 6;
481 else if ((statret == 0) && (! (dstat.st_mode && S_IFDIR)))
483 // Something exists but it's not a dir
487 // Ok, the directory container has been made, or it pre-existed.
489 newDir = new char[strlen(newContainer) + 1 + strlen(dateDirName) + 1];
490 sprintf(newDir, "%s/%s", newContainer, dateDirName);
492 log->log("JSONServer", Log::DEBUG, "doing rename '%s' '%s'", t, newDir);
493 if (rename(t, newDir) != 0) throw 8;
495 // Success. Test for remove old dir containter
496 char* tempOldTitleDir = new char[k+1];
497 memcpy(tempOldTitleDir, t, k);
498 tempOldTitleDir[k] = '\0';
499 log->log("JSONServer", Log::DEBUG, "len: %i, cp: %i, strlen: %i, oldtitledir: %s", k+1, k, strlen(tempOldTitleDir), tempOldTitleDir);
500 rmdir(tempOldTitleDir); // can't do anything about a fail result at this point.
501 delete[] tempOldTitleDir;
503 // Test for remove old foldername
506 char* tempOldFolderName = new char[j+1];
507 memcpy(tempOldFolderName, t, j);
508 tempOldFolderName[j] = '\0';
509 log->log("JSONServer", Log::DEBUG, "len: %i, cp: %i, strlen: %i, oldfoldername: %s", j+1, j, strlen(tempOldFolderName), tempOldFolderName);
512 rmdir() deletes a directory, which must be empty.
513 ENOTEMPTY - pathname contains entries other than . and ..
514 So, should be safe to call rmdir on non-empty dir
516 rmdir(tempOldFolderName); // can't do anything about a fail result at this point.
517 delete[] tempOldFolderName;
520 ::Recordings.Update();
522 js["NewRecordingFileName"] = newDir;
526 js["Result"] = false;
529 log->log("JSONServer", Log::ERR, "Bad parameters");
530 js["Error"] = "Bad request parameters";
534 log->log("JSONServer", Log::ERR, "Could not find recording to move");
535 js["Error"] = "Bad filename";
539 log->log("JSONServer", Log::ERR, "Could not move recording, it is still recording");
540 js["Error"] = "Cannot move recording in progress";
544 log->log("JSONServer", Log::ERR, "Failed to make new dir (1)");
545 js["Error"] = "Failed to create new directory (1)";
549 log->log("JSONServer", Log::ERR, "Something already exists? (1)");
550 js["Error"] = "Something already exists at the new path (1)";
554 log->log("JSONServer", Log::ERR, "Failed to make new dir (2)");
555 js["Error"] = "Failed to create new directory (2)";
559 log->log("JSONServer", Log::ERR, "Something already exists?");
560 js["Error"] = "Something already exists at the new path";
564 log->log("JSONServer", Log::ERR, "Rename failed");
565 js["Error"] = "Move failed";
569 if (fileNameToMove) delete[] fileNameToMove;
570 if (requestedNewPath) delete[] requestedNewPath;
571 if (dateDirName) delete[] dateDirName;
572 if (titleDirName) delete[] titleDirName;
573 if (folderName) delete[] folderName;
574 if (newContainer) delete[] newContainer;
575 if (newDir) delete[] newDir;
580 bool jsonserver_channellist(Json::Value& js)
582 Log* log = Log::getInstance();
583 log->log("JSONServer", Log::DEBUG, "channellist");
585 Json::Value jschannels;
588 for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
590 if (!channel->GroupSep())
592 // log->log("JSONServer", Log::DEBUG, "name: '%s'", channel->Name());
594 // if (channel->Vpid()) type = 1;
595 // else if (channel->Apid(0)) type = 2;
598 Json::Value oneChannel;
599 oneChannel["Number"] = channel->Number();
600 // oneChannel["Type"] = type;
601 oneChannel["Name"] = channel->Name();
602 //#if VDRVERSNUM < 10703
603 // oneChannel["VType"] = 2;
605 // oneChannel["VType"] = channel->Vtype();
607 jschannels.append(oneChannel);
610 js["Channels"] = jschannels;
615 bool jsonserver_channelschedule(Json::Value& js, const char* postData)
617 Log* log = Log::getInstance();
618 log->log("JSONServer", Log::DEBUG, "channelschedule '%s'", postData);
620 char sChannelNumber[15]; int mgv1 = mg_get_var(postData, strlen(postData), "channelnumber", sChannelNumber, 15);
621 char sStartTime[15]; int mgv2 = mg_get_var(postData, strlen(postData), "starttime", sStartTime, 15);
622 char sDuration[15]; int mgv3 = mg_get_var(postData, strlen(postData), "duration", sDuration, 15);
624 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) )
626 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i", mgv1, mgv2, mgv3);
627 js["Result"] = false;
628 js["Error"] = "Bad request parameters";
632 int channelNumber = atoi(sChannelNumber);
633 int startTime = atoi(sStartTime);
634 int duration = atoi(sDuration);
636 cChannel* channel = NULL;
637 for (channel = Channels.First(); channel; channel = Channels.Next(channel))
639 if (channel->GroupSep()) continue;
640 if (channel->Number() == channelNumber) break;
645 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
646 js["Result"] = false;
647 js["Error"] = "Could not find channel";
651 cSchedulesLock MutexLock;
652 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
655 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
656 js["Result"] = false;
657 js["Error"] = "Internal schedules error (1)";
660 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
663 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
664 js["Result"] = false;
665 js["Error"] = "Internal schedules error (2)";
669 Json::Value jsevents;
671 for (const cEvent* event = Schedule->Events()->First(); event; event = Schedule->Events()->Next(event))
674 if ((event->StartTime() + event->Duration()) < time(NULL)) continue;
676 if ((event->StartTime() + event->Duration()) <= startTime) continue;
678 if (event->StartTime() >= (startTime + duration)) continue;
680 Json::Value oneEvent;
681 oneEvent["ID"] = event->EventID();
682 oneEvent["Time"] = (Json::UInt)event->StartTime();
683 oneEvent["Duration"] = event->Duration();
684 oneEvent["Title"] = event->Title() ? event->Title() : "";
685 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
686 //oneEvent["Description"] = event->Description() ? event->Description() : "";
687 jsevents.append(oneEvent);
691 js["Events"] = jsevents;
695 bool jsonserver_getscheduleevent(Json::Value& js, const char* postData)
697 Log* log = Log::getInstance();
698 log->log("JSONServer", Log::DEBUG, "getscheduleevent '%s'", postData);
700 char sChannelNumber[15]; int mgv1 = mg_get_var(postData, strlen(postData), "channelnumber", sChannelNumber, 15);
701 char sEventID[15]; int mgv2 = mg_get_var(postData, strlen(postData), "eventid", sEventID, 15);
703 if ( (mgv1 == -1) || (mgv2 == -1) )
705 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
706 js["Result"] = false;
707 js["Error"] = "Bad request parameters";
711 int channelNumber = atoi(sChannelNumber);
712 int eventID = atoi(sEventID);
714 cChannel* channel = NULL;
715 for (channel = Channels.First(); channel; channel = Channels.Next(channel))
717 if (channel->GroupSep()) continue;
718 if (channel->Number() == channelNumber) break;
723 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
724 js["Result"] = false;
725 js["Error"] = "Could not find channel";
729 cSchedulesLock MutexLock;
730 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
733 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
734 js["Result"] = false;
735 js["Error"] = "Internal schedules error (1)";
738 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
741 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
742 js["Result"] = false;
743 js["Error"] = "Internal schedules error (2)";
747 cEvent* event = Schedule->GetEvent(eventID);
750 log->log("JSONServer", Log::ERR, "Could not find requested event: %i", eventID);
751 js["Result"] = false;
752 js["Error"] = "Internal schedules error (3)";
756 Json::Value oneEvent;
757 oneEvent["ID"] = event->EventID();
758 oneEvent["Time"] = (Json::UInt)event->StartTime();
759 oneEvent["Duration"] = event->Duration();
760 oneEvent["Title"] = event->Title() ? event->Title() : "";
761 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
762 oneEvent["Description"] = event->Description() ? event->Description() : "";
763 oneEvent["HasTimer"] = event->HasTimer();
764 oneEvent["RunningStatus"] = event->RunningStatus();
767 js["Event"] = oneEvent;
771 bool jsonserver_timerlist(Json::Value& js)
773 Log* log = Log::getInstance();
774 log->log("JSONServer", Log::DEBUG, "timerlist");
776 Json::Value jstimers;
779 int numTimers = Timers.Count();
781 for (int i = 0; i < numTimers; i++)
783 timer = Timers.Get(i);
784 Json::Value oneTimer;
785 oneTimer["Active"] = timer->HasFlags(tfActive);
786 oneTimer["Recording"] = timer->Recording();
787 oneTimer["Pending"] = timer->Pending();
788 oneTimer["Priority"] = timer->Priority();
789 oneTimer["Lifetime"] = timer->Lifetime();
790 oneTimer["ChannelNumber"] = timer->Channel()->Number();
791 oneTimer["StartTime"] = (int)timer->StartTime();
792 oneTimer["StopTime"] = (int)timer->StopTime();
793 oneTimer["Day"] = (int)timer->Day();
794 oneTimer["WeekDays"] = timer->WeekDays();
795 oneTimer["Name"] = timer->File();
796 jstimers.append(oneTimer);
799 js["Timers"] = jstimers;
803 bool jsonserver_timerdel(Json::Value& js, const char* postData)
805 Log* log = Log::getInstance();
806 log->log("JSONServer", Log::DEBUG, "timerdel");
808 char sdelChannel[15]; int mgv1 = mg_get_var(postData, strlen(postData), "delchannel", sdelChannel, 15);
809 char sdelWeekdays[15]; int mgv2 = mg_get_var(postData, strlen(postData), "delweekdays", sdelWeekdays, 15);
810 char sdelDay[15]; int mgv3 = mg_get_var(postData, strlen(postData), "delday", sdelDay, 15);
811 char sdelStart[15]; int mgv4 = mg_get_var(postData, strlen(postData), "delstart", sdelStart, 15);
812 char sdelStop[15]; int mgv5 = mg_get_var(postData, strlen(postData), "delstop", sdelStop, 15);
814 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) || (mgv4 == -1) || (mgv5 == -1) )
816 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i %i", mgv1, mgv2, mgv3, mgv4, mgv5);
817 js["Result"] = false;
818 js["Error"] = "Bad request parameters";
822 int delChannel = atoi(sdelChannel);
823 int delWeekdays = atoi(sdelWeekdays);
824 int delDay = atoi(sdelDay);
825 int delStart = atoi(sdelStart);
826 int delStop = atoi(sdelStop);
829 for (ti = Timers.First(); ti; ti = Timers.Next(ti))
831 if ( (ti->Channel()->Number() == delChannel)
832 && ((ti->WeekDays() && (ti->WeekDays() == delWeekdays)) || (!ti->WeekDays() && (ti->Day() == delDay)))
833 && (ti->StartTime() == delStart)
834 && (ti->StopTime() == delStop) )
840 log->log("JSONServer", Log::ERR, "Could not find timer");
841 js["Result"] = false;
842 js["Error"] = "Could not find timer";
846 if (Timers.BeingEdited())
848 log->log("JSONServer", Log::ERR, "Unable to delete timer - timers being edited at VDR");
849 js["Result"] = false;
850 js["Error"] = "Timers being edited at VDR";
856 log->log("JSONServer", Log::ERR, "Unable to delete timer - timer is running");
857 js["Result"] = false;
858 js["Error"] = "Timer is running";
863 Timers.SetModified();
869 bool jsonserver_timerset(Json::Value& js, const char* postData)
871 Log* log = Log::getInstance();
872 log->log("JSONServer", Log::DEBUG, "timerset");
874 char sTimerString[1024]; int mgv1 = mg_get_var(postData, strlen(postData), "timerstring", sTimerString, 1024);
878 log->log("JSONServer", Log::ERR, "Could not get timerstring");
879 js["Result"] = false;
880 js["Error"] = "Bad request parameters";
884 log->log("JSONServer", Log::DEBUG, "'%s'", sTimerString);
885 cTimer *timer = new cTimer;
886 if (!timer->Parse(sTimerString))
889 js["Result"] = false;
890 js["Error"] = "Failed to parse timer request details";
894 cTimer *t = Timers.GetTimer(timer);
898 js["Result"] = false;
899 js["Error"] = "Timer already exists";
904 Timers.SetModified();