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, "recrename")) success = jsonserver_recrename(js, postData);
78 else if (!strcmp(wvrequest, "recstop")) success = jsonserver_recstop(js, postData);
79 else if (!strcmp(wvrequest, "recresetresume")) success = jsonserver_recresetresume(js, postData);
80 else if (!strcmp(wvrequest, "channellist")) success = jsonserver_channellist(js);
81 else if (!strcmp(wvrequest, "channelschedule")) success = jsonserver_channelschedule(js, postData);
82 else if (!strcmp(wvrequest, "getscheduleevent")) success = jsonserver_getscheduleevent(js, postData);
83 else if (!strcmp(wvrequest, "timerlist")) success = jsonserver_timerlist(js);
84 else if (!strcmp(wvrequest, "timerdel")) success = jsonserver_timerdel(js, postData);
85 else if (!strcmp(wvrequest, "timerset")) success = jsonserver_timerset(js, postData);
86 else if (!strcmp(wvrequest, "timersetactive")) success = jsonserver_timersetactive(js, postData);
87 else if (!strcmp(wvrequest, "timerisrecording")) success = jsonserver_timerisrecording(js, postData);
88 else if (!strcmp(wvrequest, "timeredit")) success = jsonserver_timeredit(js, postData);
89 else if (!strcmp(wvrequest, "tunersstatus")) success = jsonserver_tunersstatus(js, postData);
90 else if (!strcmp(wvrequest, "epgsearchsame")) success = jsonserver_epgsearchsame(js, postData);
91 else if (!strcmp(wvrequest, "epgdownload")) success = jsonserver_epgdownload(js, postData);
92 else if (!strcmp(wvrequest, "epgsearch")) success = jsonserver_epgsearch(js, postData);
94 if (!success) return 0; // the specific handler failed badly
96 // Now js will be filled
98 Json::StyledWriter sw;
99 std::string jsonout = sw.write(js);
100 mg_printf(conn, "%s", "HTTP/1.0 200 OK\r\n");
101 mg_printf(conn, "%s", "Content-Type: text/plain\r\n\r\n");
102 mg_write(conn, jsonout.c_str(), jsonout.length());
107 else if (event == MG_EVENT_LOG)
109 if (request_info->status_code == 400) // bad request
111 log->log("Mongoose", Log::DEBUG, "400 BAD REQUEST:");
112 log->log("Mongoose", Log::DEBUG, request_info->request_method);
113 log->log("Mongoose", Log::DEBUG, request_info->uri);
114 log->log("Mongoose", Log::DEBUG, request_info->http_version);
115 log->log("Mongoose", Log::DEBUG, request_info->query_string);
116 log->log("Mongoose", Log::DEBUG, request_info->log_message);
117 for (int i = 0; i < request_info->num_headers; i++)
119 log->log("Mongoose", Log::DEBUG, "%s: %s", request_info->http_headers[i].name, request_info->http_headers[i].value);
124 log->log("Mongoose", Log::DEBUG, request_info->log_message);
125 log->log("Mongoose", Log::DEBUG, request_info->uri);
130 // other events not handled:
131 // MG_HTTP_ERROR, MG_INIT_SSL
132 // Let mongoose do something with those
140 bool jsonserver_gettime(Json::Value& js)
142 Log* log = Log::getInstance();
143 log->log("JSONServer", Log::DEBUG, "gettime");
146 gettimeofday(&tv, NULL);
148 js["Time"] = (Json::UInt64)tv.tv_sec;
149 js["MTime"] = (Json::UInt)(tv.tv_usec/1000);
154 bool jsonserver_diskstats(Json::Value& js)
156 Log* log = Log::getInstance();
157 log->log("JSONServer", Log::DEBUG, "diskstats");
162 #if APIVERSNUM > 20101
163 int Percent = cVideoDirectory::VideoDiskSpace(&FreeMB, &UsedMB);
165 int Percent = VideoDiskSpace(&FreeMB, &UsedMB);
168 js["FreeMiB"] = FreeMB;
169 js["UsedMiB"] = UsedMB;
170 js["Percent"] = Percent;
176 bool jsonserver_reclist(Json::Value& js)
178 Log* log = Log::getInstance();
179 log->log("JSONServer", Log::DEBUG, "reclist");
181 Json::Value jsrecordings(Json::arrayValue);
182 cRecordings Recordings;
184 for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording))
187 oneRec["StartTime"] = (Json::UInt)recording->Start();
188 oneRec["Length"] = (Json::UInt)recording->LengthInSeconds();
189 oneRec["IsNew"] = recording->IsNew();
190 oneRec["Name"] = recording->Name();
191 oneRec["Filename"] = recording->FileName();
192 oneRec["FileSizeMB"] = recording->FileSizeMB();
194 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
195 if (rc) oneRec["CurrentlyRecording"] = true;
196 else oneRec["CurrentlyRecording"] = false;
198 jsrecordings.append(oneRec);
200 js["Recordings"] = jsrecordings;
205 bool jsonserver_recinfo(Json::Value& js, const char* postData)
207 Log* log = Log::getInstance();
208 log->log("JSONServer", Log::DEBUG, "recinfo");
210 char reqfilename[1000];
211 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
214 log->log("JSONServer", Log::ERR, "Could not decode filename");
215 js["Result"] = false;
216 js["Error"] = "Could not decode filename";
220 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
222 cRecordings Recordings;
223 Recordings.Load(); // probably have to do this
224 cRecording *recording = Recordings.GetByName(reqfilename);
228 log->log("JSONServer", Log::ERR, "recinfo found no recording");
229 js["Result"] = false;
233 js["IsNew"] = recording->IsNew();
234 js["LengthInSeconds"] = recording->LengthInSeconds();
235 js["FileSizeMB"] = recording->FileSizeMB();
236 js["Name"] = recording->Name() ? recording->Name() : Json::Value::null;
237 js["Priority"] = recording->Priority();
238 js["LifeTime"] = recording->Lifetime();
239 js["Start"] = (Json::UInt)recording->Start();
241 js["CurrentlyRecordingStart"] = 0;
242 js["CurrentlyRecordingStop"] = 0;
243 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
246 js["CurrentlyRecordingStart"] = (Json::UInt)rc->Timer()->StartTime();
247 js["CurrentlyRecordingStop"] = (Json::UInt)rc->Timer()->StopTime();
250 js["ResumePoint"] = 0;
252 const cRecordingInfo *info = recording->Info();
255 js["ChannelName"] = info->ChannelName() ? info->ChannelName() : Json::Value::null;
256 js["Title"] = info->Title() ? info->Title() : Json::Value::null;
257 js["ShortText"] = info->ShortText() ? info->ShortText() : Json::Value::null;
258 js["Description"] = info->Description() ? info->Description() : Json::Value::null;
260 const cComponents* components = info->Components();
263 js["Components"] = Json::Value::null;
267 Json::Value jscomponents;
269 tComponent* component;
270 for (int i = 0; i < components->NumComponents(); i++)
272 component = components->Component(i);
274 Json::Value oneComponent;
275 oneComponent["Stream"] = component->stream;
276 oneComponent["Type"] = component->type;
277 oneComponent["Language"] = component->language ? component->language : Json::Value::null;
278 oneComponent["Description"] = component->description ? component->description : Json::Value::null;
279 jscomponents.append(oneComponent);
282 js["Components"] = jscomponents;
285 cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording());
286 if (ResumeFile.Read() >= 0) js["ResumePoint"] = floor(ResumeFile.Read() / info->FramesPerSecond());
293 bool jsonserver_recstop(Json::Value& js, const char* postData)
295 Log* log = Log::getInstance();
296 log->log("JSONServer", Log::DEBUG, "recstop");
298 char reqfilename[1000];
299 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
302 log->log("JSONServer", Log::ERR, "Could not decode filename");
303 js["Result"] = false;
304 js["Error"] = "Could not decode filename";
308 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
310 cRecordings Recordings;
311 Recordings.Load(); // probably have to do this
312 cRecording *recording = Recordings.GetByName(reqfilename);
316 log->log("JSONServer", Log::ERR, "recstop found no recording");
317 js["Result"] = false;
321 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
324 log->log("JSONServer", Log::ERR, "recstop - not currently recording");
325 js["Result"] = false;
329 if (Timers.BeingEdited())
331 log->log("JSONServer", Log::ERR, "recstop - timers being edited elsewhere");
332 js["Result"] = false;
336 cTimer* timer = rc->Timer();
339 log->log("JSONServer", Log::ERR, "recstop - timer not found");
340 js["Result"] = false;
344 timer->ClrFlags(tfActive);
345 Timers.SetModified();
351 bool jsonserver_recdel(Json::Value& js, const char* postData)
353 Log* log = Log::getInstance();
354 log->log("JSONServer", Log::DEBUG, "recdel");
356 char reqfilename[1000];
357 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
360 log->log("JSONServer", Log::ERR, "Could not decode filename");
361 js["Result"] = false;
362 js["Error"] = "Could not decode filename";
366 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
368 cRecordings Recordings;
369 Recordings.Load(); // probably have to do this
370 cRecording *recording = Recordings.GetByName(reqfilename);
374 js["Result"] = false;
375 js["Error"] = "Could not find recording to delete";
379 log->log("JSONServer", Log::DEBUG, "Deleting recording: %s", recording->Name());
380 cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
383 js["Result"] = false;
384 js["Error"] = "This recording is still recording.. ho ho";
388 if (recording->Delete())
390 ::Recordings.DelByName(recording->FileName());
395 js["Result"] = false;
396 js["Error"] = "Failed to delete recording";
402 bool jsonserver_recmove(Json::Value& js, const char* postData)
404 Log* log = Log::getInstance();
405 log->log("JSONServer", Log::DEBUG, "recmove");
407 char* fileNameToMove = NULL;
408 char* requestedNewPath = NULL;
409 char* dateDirName = NULL;
410 char* titleDirName = NULL;
411 char* folderName = NULL;
412 char* newContainer = NULL;
417 int postDataLen = strlen(postData)+1;
418 fileNameToMove = new char[postDataLen];
419 int mgv1 = mg_get_var(postData, postDataLen-1, "filename", fileNameToMove, postDataLen);
420 requestedNewPath = new char[postDataLen];
421 int mgv2 = mg_get_var(postData, postDataLen-1, "newpath", requestedNewPath, postDataLen);
423 if ((mgv1 == -1) || (mgv2 == -1) || !strlen(fileNameToMove) || !strlen(requestedNewPath))
425 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
429 cRecordings Recordings;
430 Recordings.Load(); // probably have to do this
431 cRecording* recordingObj = Recordings.GetByName(fileNameToMove);
432 if (!recordingObj) throw 2;
434 cRecordControl *rc = cRecordControls::GetRecordControl(recordingObj->FileName());
437 log->log("JSONServer", Log::DEBUG, "moving recording: %s", recordingObj->Name());
438 log->log("JSONServer", Log::DEBUG, "moving recording: %s", recordingObj->FileName());
439 log->log("JSONServer", Log::DEBUG, "to: %s", requestedNewPath);
441 const char* t = recordingObj->FileName();
445 // Find the datedirname
446 for(k = strlen(t) - 1; k >= 0; k--)
450 log->log("JSONServer", Log::DEBUG, "l1: %i", strlen(&t[k+1]) + 1);
451 dateDirName = new char[strlen(&t[k+1]) + 1];
452 strcpy(dateDirName, &t[k+1]);
457 // Find the titledirname
459 for(j = k-1; j >= 0; j--)
463 log->log("JSONServer", Log::DEBUG, "l2: %i", k - j);
464 titleDirName = new char[k - j];
465 memcpy(titleDirName, &t[j+1], k - j - 1);
466 titleDirName[k - j - 1] = '\0';
471 // Find the foldername
473 #if APIVERSNUM > 20101
474 const char* vidDirStr = cVideoDirectory::Name();
476 const char* vidDirStr = VideoDirectory;
478 int vidDirStrLen = strlen(vidDirStr);
480 log->log("JSONServer", Log::DEBUG, "j = %u, strlenvd = %u", j, vidDirStrLen);
481 if (j > vidDirStrLen) // Rec is in a subfolder now
483 for(m = j-1; m >= 0; m--)
487 log->log("JSONServer", Log::DEBUG, "l3: %i", j - m);
488 folderName = new char[j - m];
489 memcpy(folderName, &t[m+1], j - m - 1);
490 folderName[j - m - 1] = '\0';
496 ExchangeChars(requestedNewPath, true);
498 log->log("JSONServer", Log::DEBUG, "datedirname: %s", dateDirName);
499 log->log("JSONServer", Log::DEBUG, "titledirname: %s", titleDirName);
500 log->log("JSONServer", Log::DEBUG, "viddir: %s", vidDirStr);
501 if (folderName) log->log("JSONServer", Log::DEBUG, "folderName: %s", folderName);
502 log->log("JSONServer", Log::DEBUG, "EC: %s", requestedNewPath);
504 // Could be a new path - construct that first and test
505 newContainer = new char[vidDirStrLen + strlen(requestedNewPath) + strlen(titleDirName) + 1];
506 sprintf(newContainer, "%s%s", vidDirStr, requestedNewPath);
507 log->log("JSONServer", Log::DEBUG, "NPT: %s", newContainer);
509 int statret = stat(newContainer, &dstat);
510 if ((statret == -1) && (errno == ENOENT)) // Dir does not exist
512 log->log("JSONServer", Log::DEBUG, "new path does not exist (1)");
513 int mkdirret = mkdir(newContainer, 0755);
514 if (mkdirret != 0) throw 4;
516 else if ((statret == 0) && (! (dstat.st_mode && S_IFDIR)))
518 // Something exists but it's not a dir
522 // New path now created or was there already
524 sprintf(newContainer, "%s%s%s", vidDirStr, requestedNewPath, titleDirName);
525 log->log("JSONServer", Log::DEBUG, "%s", newContainer);
527 statret = stat(newContainer, &dstat);
528 if ((statret == -1) && (errno == ENOENT)) // Dir does not exist
530 log->log("JSONServer", Log::DEBUG, "new dir does not exist (2)");
531 int mkdirret = mkdir(newContainer, 0755);
532 if (mkdirret != 0) throw 6;
534 else if ((statret == 0) && (! (dstat.st_mode && S_IFDIR)))
536 // Something exists but it's not a dir
540 // Ok, the directory container has been made, or it pre-existed.
542 newDir = new char[strlen(newContainer) + 1 + strlen(dateDirName) + 1];
543 sprintf(newDir, "%s/%s", newContainer, dateDirName);
545 log->log("JSONServer", Log::DEBUG, "doing rename '%s' '%s'", t, newDir);
546 if (rename(t, newDir) != 0) throw 8;
548 // Success. Test for remove old dir containter
549 char* tempOldTitleDir = new char[k+1];
550 memcpy(tempOldTitleDir, t, k);
551 tempOldTitleDir[k] = '\0';
552 log->log("JSONServer", Log::DEBUG, "len: %i, cp: %i, strlen: %i, oldtitledir: %s", k+1, k, strlen(tempOldTitleDir), tempOldTitleDir);
553 rmdir(tempOldTitleDir); // can't do anything about a fail result at this point.
554 delete[] tempOldTitleDir;
556 // Test for remove old foldername
559 char* tempOldFolderName = new char[j+1];
560 memcpy(tempOldFolderName, t, j);
561 tempOldFolderName[j] = '\0';
562 log->log("JSONServer", Log::DEBUG, "len: %i, cp: %i, strlen: %i, oldfoldername: %s", j+1, j, strlen(tempOldFolderName), tempOldFolderName);
565 rmdir() deletes a directory, which must be empty.
566 ENOTEMPTY - pathname contains entries other than . and ..
567 So, should be safe to call rmdir on non-empty dir
569 rmdir(tempOldFolderName); // can't do anything about a fail result at this point.
570 delete[] tempOldFolderName;
573 ::Recordings.Update();
575 js["NewRecordingFileName"] = newDir;
579 js["Result"] = false;
582 log->log("JSONServer", Log::ERR, "Bad parameters");
583 js["Error"] = "Bad request parameters";
587 log->log("JSONServer", Log::ERR, "Could not find recording to move");
588 js["Error"] = "Bad filename";
592 log->log("JSONServer", Log::ERR, "Could not move recording, it is still recording");
593 js["Error"] = "Cannot move recording in progress";
597 log->log("JSONServer", Log::ERR, "Failed to make new dir (1)");
598 js["Error"] = "Failed to create new directory (1)";
602 log->log("JSONServer", Log::ERR, "Something already exists? (1)");
603 js["Error"] = "Something already exists at the new path (1)";
607 log->log("JSONServer", Log::ERR, "Failed to make new dir (2)");
608 js["Error"] = "Failed to create new directory (2)";
612 log->log("JSONServer", Log::ERR, "Something already exists?");
613 js["Error"] = "Something already exists at the new path";
617 log->log("JSONServer", Log::ERR, "Rename failed");
618 js["Error"] = "Move failed";
622 if (fileNameToMove) delete[] fileNameToMove;
623 if (requestedNewPath) delete[] requestedNewPath;
624 if (dateDirName) delete[] dateDirName;
625 if (titleDirName) delete[] titleDirName;
626 if (folderName) delete[] folderName;
627 if (newContainer) delete[] newContainer;
628 if (newDir) delete[] newDir;
633 bool jsonserver_recrename(Json::Value& js, const char* postData)
635 Log* log = Log::getInstance();
636 log->log("JSONServer", Log::DEBUG, "recrename");
638 char* fileNameToRename = NULL;
639 char* requestedNewName = NULL;
640 char* dateDirName = NULL;
641 char* titleDirName = NULL;
642 char* folderName = NULL;
643 char* newContainer = NULL;
648 int postDataLen = strlen(postData)+1;
649 fileNameToRename = new char[postDataLen];
650 int mgv1 = mg_get_var(postData, postDataLen-1, "filename", fileNameToRename, postDataLen);
651 requestedNewName = new char[postDataLen];
652 int mgv2 = mg_get_var(postData, postDataLen-1, "newname", requestedNewName, postDataLen);
654 if ((mgv1 == -1) || (mgv2 == -1) || !strlen(fileNameToRename) || !strlen(requestedNewName))
656 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
660 cRecordings Recordings;
661 Recordings.Load(); // probably have to do this
662 cRecording* recordingObj = Recordings.GetByName(fileNameToRename);
663 if (!recordingObj) throw 2;
665 cRecordControl *rc = cRecordControls::GetRecordControl(recordingObj->FileName());
668 log->log("JSONServer", Log::DEBUG, "renaming recording: %s", recordingObj->Name());
669 log->log("JSONServer", Log::DEBUG, "renaming recording: %s", recordingObj->FileName());
670 log->log("JSONServer", Log::DEBUG, "to: %s", requestedNewName);
672 const char* t = recordingObj->FileName();
676 // Find the datedirname
677 for(k = strlen(t) - 1; k >= 0; k--)
681 log->log("JSONServer", Log::DEBUG, "l1: %i", strlen(&t[k+1]) + 1);
682 dateDirName = new char[strlen(&t[k+1]) + 1];
683 strcpy(dateDirName, &t[k+1]);
688 // Find the titledirname
690 for(j = k-1; j >= 0; j--)
694 log->log("JSONServer", Log::DEBUG, "l2: %i", k - j);
695 titleDirName = new char[k - j];
696 memcpy(titleDirName, &t[j+1], k - j - 1);
697 titleDirName[k - j - 1] = '\0';
702 // Find the foldername
704 #if APIVERSNUM > 20101
705 const char* vidDirStr = cVideoDirectory::Name();
707 const char* vidDirStr = VideoDirectory;
709 int vidDirStrLen = strlen(vidDirStr);
711 log->log("JSONServer", Log::DEBUG, "j = %u, strlenvd = %u", j, vidDirStrLen);
712 if (j > vidDirStrLen) // Rec is in a subfolder now
714 for(m = j-1; m >= 0; m--)
718 log->log("JSONServer", Log::DEBUG, "l3: %i", j - m);
719 folderName = new char[j - m];
720 memcpy(folderName, &t[m+1], j - m - 1);
721 folderName[j - m - 1] = '\0';
727 ExchangeChars(requestedNewName, true);
729 log->log("JSONServer", Log::DEBUG, "datedirname: %s", dateDirName);
730 log->log("JSONServer", Log::DEBUG, "titledirname: %s", titleDirName);
731 log->log("JSONServer", Log::DEBUG, "viddir: %s", vidDirStr);
732 if (folderName) log->log("JSONServer", Log::DEBUG, "folderName: %s", folderName);
733 log->log("JSONServer", Log::DEBUG, "EC: %s", requestedNewName);
735 // Could be a new path - construct that first and test
739 newContainer = new char[vidDirStrLen + 1 + strlen(folderName) + 1 + strlen(requestedNewName) + 1];
740 sprintf(newContainer, "%s/%s/%s", vidDirStr, folderName, requestedNewName);
744 newContainer = new char[vidDirStrLen + 1 + strlen(requestedNewName) + 1];
745 sprintf(newContainer, "%s/%s", vidDirStr, requestedNewName);
747 log->log("JSONServer", Log::DEBUG, "NPT: %s", newContainer);
749 int statret = stat(newContainer, &dstat);
750 if ((statret == -1) && (errno == ENOENT)) // Dir does not exist
752 log->log("JSONServer", Log::DEBUG, "new path does not exist (1)");
753 int mkdirret = mkdir(newContainer, 0755);
754 if (mkdirret != 0) throw 4;
756 else if ((statret == 0) && (! (dstat.st_mode && S_IFDIR)))
758 // Something exists but it's not a dir
762 // New path now created or was there already
764 newDir = new char[strlen(newContainer) + 1 + strlen(dateDirName) + 1];
765 sprintf(newDir, "%s/%s", newContainer, dateDirName);
767 log->log("JSONServer", Log::DEBUG, "doing rename '%s' '%s'", t, newDir);
768 if (rename(t, newDir) != 0) throw 8;
770 // Success. Test for remove old dir containter
771 char* tempOldTitleDir = new char[k+1];
772 memcpy(tempOldTitleDir, t, k);
773 tempOldTitleDir[k] = '\0';
774 log->log("JSONServer", Log::DEBUG, "len: %i, cp: %i, strlen: %i, oldtitledir: %s", k+1, k, strlen(tempOldTitleDir), tempOldTitleDir);
775 rmdir(tempOldTitleDir); // can't do anything about a fail result at this point.
776 delete[] tempOldTitleDir;
778 ::Recordings.Update();
780 js["NewRecordingFileName"] = newDir;
784 js["Result"] = false;
787 log->log("JSONServer", Log::ERR, "Bad parameters");
788 js["Error"] = "Bad request parameters";
792 log->log("JSONServer", Log::ERR, "Could not find recording to move");
793 js["Error"] = "Bad filename";
797 log->log("JSONServer", Log::ERR, "Could not move recording, it is still recording");
798 js["Error"] = "Cannot move recording in progress";
802 log->log("JSONServer", Log::ERR, "Failed to make new dir (1)");
803 js["Error"] = "Failed to create new directory (1)";
807 log->log("JSONServer", Log::ERR, "Something already exists? (1)");
808 js["Error"] = "Something already exists at the new path (1)";
812 log->log("JSONServer", Log::ERR, "Rename failed");
813 js["Error"] = "Move failed";
817 if (fileNameToRename) delete[] fileNameToRename;
818 if (requestedNewName) delete[] requestedNewName;
819 if (dateDirName) delete[] dateDirName;
820 if (titleDirName) delete[] titleDirName;
821 if (folderName) delete[] folderName;
822 if (newContainer) delete[] newContainer;
823 if (newDir) delete[] newDir;
828 bool jsonserver_recresetresume(Json::Value& js, const char* postData)
830 Log* log = Log::getInstance();
831 log->log("JSONServer", Log::DEBUG, "recresetresume");
833 char reqfilename[1000];
834 int mgv1 = mg_get_var(postData, strlen(postData), "filename", reqfilename, 1000);
837 log->log("JSONServer", Log::ERR, "Could not decode filename");
838 js["Result"] = false;
839 js["Error"] = "Could not decode filename";
843 log->log("JSONServer", Log::DEBUG, "%s", reqfilename);
845 cRecordings Recordings;
846 Recordings.Load(); // probably have to do this
847 cRecording *recording = Recordings.GetByName(reqfilename);
851 js["Result"] = false;
852 js["Error"] = "Could not find recording to reset resume";
856 log->log("JSONServer", Log::DEBUG, "Reset resume for: %s", recording->Name());
858 cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording());
859 if (ResumeFile.Read() >= 0)
867 js["Result"] = false;
868 js["Error"] = "Recording has no resume point";
873 bool jsonserver_channellist(Json::Value& js)
875 Log* log = Log::getInstance();
876 log->log("JSONServer", Log::DEBUG, "channellist");
878 Json::Value jschannels(Json::arrayValue);
881 for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
883 if (!channel->GroupSep())
885 // log->log("JSONServer", Log::DEBUG, "name: '%s'", channel->Name());
887 // if (channel->Vpid()) type = 1;
888 // else if (channel->Apid(0)) type = 2;
891 Json::Value oneChannel;
892 oneChannel["ID"] = (const char *)channel->GetChannelID().ToString();
893 oneChannel["Number"] = channel->Number();
894 // oneChannel["Type"] = type;
895 oneChannel["Name"] = channel->Name();
896 //#if VDRVERSNUM < 10703
897 // oneChannel["VType"] = 2;
899 // oneChannel["VType"] = channel->Vtype();
901 jschannels.append(oneChannel);
904 js["Channels"] = jschannels;
909 bool jsonserver_channelschedule(Json::Value& js, const char* postData)
911 Log* log = Log::getInstance();
912 log->log("JSONServer", Log::DEBUG, "channelschedule '%s'", postData);
914 char sChannelNumber[15]; int mgv1 = mg_get_var(postData, strlen(postData), "channelnumber", sChannelNumber, 15);
915 char sStartTime[15]; int mgv2 = mg_get_var(postData, strlen(postData), "starttime", sStartTime, 15);
916 char sDuration[15]; int mgv3 = mg_get_var(postData, strlen(postData), "duration", sDuration, 15);
918 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) )
920 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i", mgv1, mgv2, mgv3);
921 js["Result"] = false;
922 js["Error"] = "Bad request parameters";
926 int channelNumber = atoi(sChannelNumber);
927 int startTime = atoi(sStartTime);
928 int duration = atoi(sDuration);
930 cChannel* channel = NULL;
931 for (channel = Channels.First(); channel; channel = Channels.Next(channel))
933 if (channel->GroupSep()) continue;
934 if (channel->Number() == channelNumber) break;
939 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
940 js["Result"] = false;
941 js["Error"] = "Could not find channel";
945 cSchedulesLock MutexLock;
946 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
949 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
950 js["Result"] = false;
951 js["Error"] = "Internal schedules error (1)";
954 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
957 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
958 js["Result"] = false;
959 js["Error"] = "Internal schedules error (2)";
963 Json::Value jsevents(Json::arrayValue);
965 for (const cEvent* event = Schedule->Events()->First(); event; event = Schedule->Events()->Next(event))
968 if ((event->StartTime() + event->Duration()) < time(NULL)) continue;
970 if ((event->StartTime() + event->Duration()) <= startTime) continue;
972 if (event->StartTime() >= (startTime + duration)) continue;
974 Json::Value oneEvent;
975 oneEvent["ID"] = event->EventID();
976 oneEvent["Time"] = (Json::UInt)event->StartTime();
977 oneEvent["Duration"] = event->Duration();
978 oneEvent["Title"] = event->Title() ? event->Title() : "";
979 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
980 oneEvent["HasTimer"] = event->HasTimer();
981 //oneEvent["Description"] = event->Description() ? event->Description() : "";
982 jsevents.append(oneEvent);
986 js["Events"] = jsevents;
990 bool jsonserver_getscheduleevent(Json::Value& js, const char* postData)
992 Log* log = Log::getInstance();
993 log->log("JSONServer", Log::DEBUG, "getscheduleevent '%s'", postData);
995 char sChannelNumber[15]; int mgv1 = mg_get_var(postData, strlen(postData), "channelnumber", sChannelNumber, 15);
996 char sEventID[15]; int mgv2 = mg_get_var(postData, strlen(postData), "eventid", sEventID, 15);
998 if ( (mgv1 == -1) || (mgv2 == -1) )
1000 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
1001 js["Result"] = false;
1002 js["Error"] = "Bad request parameters";
1006 int channelNumber = atoi(sChannelNumber);
1007 int eventID = atoi(sEventID);
1009 const cEvent* event = jsonserver_getEvent(js, channelNumber, eventID, 0);
1012 js["Result"] = false;
1016 Json::Value oneEvent;
1017 oneEvent["ID"] = event->EventID();
1018 oneEvent["Time"] = (Json::UInt)event->StartTime();
1019 oneEvent["Duration"] = event->Duration();
1020 oneEvent["Title"] = event->Title() ? event->Title() : "";
1021 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
1022 oneEvent["Description"] = event->Description() ? event->Description() : "";
1023 oneEvent["HasTimer"] = event->HasTimer();
1024 oneEvent["RunningStatus"] = event->RunningStatus();
1026 js["Result"] = true;
1027 js["Event"] = oneEvent;
1031 const cEvent* jsonserver_getEvent(Json::Value& js, int channelNumber, int eventID, int aroundTime)
1033 Log* log = Log::getInstance();
1035 cChannel* channel = NULL;
1036 for (channel = Channels.First(); channel; channel = Channels.Next(channel))
1038 if (channel->GroupSep()) continue;
1039 if (channel->Number() == channelNumber) break;
1044 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
1045 js["Error"] = "Could not find channel";
1049 cSchedulesLock MutexLock;
1050 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
1053 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
1054 js["Error"] = "Internal schedules error (1)";
1058 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
1061 log->log("JSONServer", Log::ERR, "Could not find requested channel: %i", channelNumber);
1062 js["Error"] = "Internal schedules error (2)";
1066 const cEvent* event = NULL;
1069 event = Schedule->GetEvent(eventID);
1073 event = Schedule->GetEventAround(aroundTime);
1078 log->log("JSONServer", Log::ERR, "Could not find requested event: %i", eventID);
1079 js["Error"] = "Internal schedules error (3)";
1086 bool jsonserver_timerlist(Json::Value& js)
1088 Log* log = Log::getInstance();
1089 log->log("JSONServer", Log::DEBUG, "timerlist");
1091 Json::Value jstimers(Json::arrayValue);
1094 int numTimers = Timers.Count();
1096 for (int i = 0; i < numTimers; i++)
1098 timer = Timers.Get(i);
1099 Json::Value oneTimer;
1100 oneTimer["Active"] = timer->HasFlags(tfActive);
1101 oneTimer["Recording"] = timer->Recording();
1102 oneTimer["Pending"] = timer->Pending();
1103 oneTimer["Priority"] = timer->Priority();
1104 oneTimer["Lifetime"] = timer->Lifetime();
1105 oneTimer["ChannelNumber"] = timer->Channel()->Number();
1106 oneTimer["ChannelID"] = (const char *)timer->Channel()->GetChannelID().ToString();
1107 oneTimer["StartTime"] = (int)timer->StartTime();
1108 oneTimer["StopTime"] = (int)timer->StopTime();
1109 oneTimer["Day"] = (int)timer->Day();
1110 oneTimer["WeekDays"] = timer->WeekDays();
1111 oneTimer["Name"] = timer->File();
1113 const cEvent* event = timer->Event();
1116 oneTimer["EventID"] = event->EventID();
1120 int channelNumber = timer->Channel()->Number();
1121 int aroundTime = timer->StartTime() + 1;
1122 log->log("JSONServer", Log::DEBUG, "%i", aroundTime);
1124 const cEvent* eventAround = jsonserver_getEvent(js, channelNumber, 0, aroundTime);
1127 oneTimer["EventID"] = eventAround->EventID();
1131 oneTimer["EventID"] = 0;
1135 jstimers.append(oneTimer);
1138 js["Timers"] = jstimers;
1139 js["Result"] = true;
1143 bool jsonserver_timerset(Json::Value& js, const char* postData)
1145 Log* log = Log::getInstance();
1146 log->log("JSONServer", Log::DEBUG, "timerset");
1148 char sTimerString[1024]; int mgv1 = mg_get_var(postData, strlen(postData), "timerstring", sTimerString, 1024);
1152 log->log("JSONServer", Log::ERR, "Could not get timerstring");
1153 js["Result"] = false;
1154 js["Error"] = "Bad request parameters";
1158 log->log("JSONServer", Log::DEBUG, "'%s'", sTimerString);
1159 cTimer *timer = new cTimer;
1160 if (!timer->Parse(sTimerString))
1163 js["Result"] = false;
1164 js["Error"] = "Failed to parse timer request details";
1168 cTimer *t = Timers.GetTimer(timer);
1172 js["Result"] = false;
1173 js["Error"] = "Timer already exists";
1178 Timers.SetModified();
1179 js["Result"] = true;
1183 bool jsonserver_timersetactive(Json::Value& js, const char* postData)
1185 Log* log = Log::getInstance();
1186 log->log("JSONServer", Log::DEBUG, "timersetactive");
1188 char rChannelID[50]; int mgv1 = mg_get_var(postData, strlen(postData), "ChannelID", rChannelID, 50);
1189 char rName[1024]; int mgv2 = mg_get_var(postData, strlen(postData), "Name", rName, 1024);
1190 char rStartTime[20]; int mgv3 = mg_get_var(postData, strlen(postData), "StartTime", rStartTime, 20);
1191 char rStopTime[20]; int mgv4 = mg_get_var(postData, strlen(postData), "StopTime", rStopTime, 20);
1192 char rWeekDays[50]; int mgv5 = mg_get_var(postData, strlen(postData), "WeekDays", rWeekDays, 20);
1193 char tNewActive[20]; int mgv6 = mg_get_var(postData, strlen(postData), "SetActive", tNewActive, 20);
1195 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) || (mgv4 == -1) || (mgv5 == -1) || (mgv6 == -1))
1197 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i %i %i", mgv1, mgv2, mgv3, mgv4, mgv5, mgv6);
1198 js["Result"] = false;
1199 js["Error"] = "Bad request parameters";
1203 log->log("JSONServer", Log::DEBUG, "timersetactive: %s %s:%s:%s:%s:%s", tNewActive, rChannelID, rName, rStartTime, rStopTime, rWeekDays);
1205 cTimer* timer = jsonserver_findTimer(rChannelID, rName, rStartTime, rStopTime, rWeekDays);
1208 if (strcmp(tNewActive, "true") == 0)
1210 timer->SetFlags(tfActive);
1212 else if (strcmp(tNewActive, "false") == 0)
1214 timer->ClrFlags(tfActive);
1218 js["Result"] = false;
1219 js["Error"] = "Bad request parameters";
1223 js["Result"] = true;
1225 Timers.SetModified();
1230 js["Result"] = false;
1231 js["Error"] = "Timer not found";
1235 bool jsonserver_timeredit(Json::Value& js, const char* postData)
1237 Log* log = Log::getInstance();
1238 log->log("JSONServer", Log::DEBUG, "timeredit");
1241 char oldName[1024]; int mgv1 = mg_get_var(postData, strlen(postData), "OldName", oldName, 1024);
1242 char oldActive[20]; int mgv2 = mg_get_var(postData, strlen(postData), "OldActive", oldActive, 20);
1243 char oldChannelID[50]; int mgv3 = mg_get_var(postData, strlen(postData), "OldChannelID", oldChannelID, 50);
1244 char oldDay[20]; int mgv4 = mg_get_var(postData, strlen(postData), "OldDay", oldDay, 20);
1245 char oldWeekDays[50]; int mgv5 = mg_get_var(postData, strlen(postData), "OldWeekDays", oldWeekDays, 20);
1246 char oldStartTime[20]; int mgv6 = mg_get_var(postData, strlen(postData), "OldStartTime", oldStartTime, 20);
1247 char oldStopTime[20]; int mgv7 = mg_get_var(postData, strlen(postData), "OldStopTime", oldStopTime, 20);
1248 char oldPriority[20]; int mgv8 = mg_get_var(postData, strlen(postData), "OldPriority", oldPriority, 20);
1249 char oldLifetime[20]; int mgv9 = mg_get_var(postData, strlen(postData), "OldLifetime", oldLifetime, 20);
1251 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) || (mgv4 == -1) || (mgv5 == -1) || (mgv6 == -1) || (mgv7 == -1) || (mgv8 == -1) || (mgv9 == -1))
1253 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i %i %i %i %i %i", mgv1, mgv2, mgv3, mgv4, mgv5, mgv6, mgv7, mgv8, mgv9);
1254 js["Result"] = false;
1255 js["Error"] = "Bad request parameters";
1259 log->log("JSONServer", Log::DEBUG, "timeredit: %s %s %s %s %s %s %s %s %s", oldName, oldActive, oldChannelID, oldDay, oldWeekDays, oldStartTime, oldStopTime, oldPriority, oldLifetime);
1263 char newName[1024]; int mgv11 = mg_get_var(postData, strlen(postData), "NewName", newName, 1024);
1264 char newActive[20]; int mgv12 = mg_get_var(postData, strlen(postData), "NewActive", newActive, 20);
1265 char newChannelID[50]; int mgv13 = mg_get_var(postData, strlen(postData), "NewChannelID", newChannelID, 50);
1266 char newDay[20]; int mgv14 = mg_get_var(postData, strlen(postData), "NewDay", newDay, 20);
1267 char newWeekDays[50]; int mgv15 = mg_get_var(postData, strlen(postData), "NewWeekDays", newWeekDays, 20);
1268 char newStartTime[20]; int mgv16 = mg_get_var(postData, strlen(postData), "NewStartTime", newStartTime, 20);
1269 char newStopTime[20]; int mgv17 = mg_get_var(postData, strlen(postData), "NewStopTime", newStopTime, 20);
1270 char newPriority[20]; int mgv18 = mg_get_var(postData, strlen(postData), "NewPriority", newPriority, 20);
1271 char newLifetime[20]; int mgv19 = mg_get_var(postData, strlen(postData), "NewLifetime", newLifetime, 20);
1273 if ( (mgv11 == -1) || (mgv12 == -1) || (mgv13 == -1) || (mgv14 == -1) || (mgv15 == -1) || (mgv16 == -1) || (mgv17 == -1) || (mgv18 == -1) || (mgv19 == -1))
1275 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i %i %i %i %i %i", mgv11, mgv12, mgv13, mgv14, mgv15, mgv16, mgv17, mgv18, mgv19);
1276 js["Result"] = false;
1277 js["Error"] = "Bad request parameters";
1281 log->log("JSONServer", Log::DEBUG, "timeredit: %s %s %s %s %s %s %s %s %s", newName, newActive, newChannelID, newDay, newWeekDays, newStartTime, newStopTime, newPriority, newLifetime);
1284 cTimer* timer = jsonserver_findTimer2(oldName, oldActive, oldChannelID, oldDay, oldWeekDays, oldStartTime, oldStopTime, oldPriority, oldLifetime);
1287 js["Result"] = false;
1288 js["Error"] = "Timer not found";
1292 // Old version commented below used to set each thing individually based on whether it had changed. However, since
1293 // the only way to change the timer channel appears to be with the cTimer::Parse function, might as well use that
1294 // for everything it supports
1295 // Except flags. Get current flags, set using Parse, then add/remove active as needed the other way.
1297 time_t nstt = atoi(newStartTime);
1299 localtime_r(&nstt, &nstm);
1300 int nssf = (nstm.tm_hour * 100) + nstm.tm_min;
1302 time_t nztt = atoi(newStopTime);
1304 localtime_r(&nztt, &nztm);
1305 int nzsf = (nztm.tm_hour * 100) + nztm.tm_min;
1307 strreplace(newName, ':', '|');
1309 cString parseBuffer = cString::sprintf("%u:%s:%s:%04d:%04d:%d:%d:%s:%s",
1310 timer->Flags(), newChannelID, *(cTimer::PrintDay(atoi(newDay), atoi(newWeekDays), true)),
1311 nssf, nzsf, atoi(newPriority), atoi(newLifetime), newName, timer->Aux() ? timer->Aux() : "");
1313 log->log("JSONServer", Log::DEBUG, "timeredit new parse: %s", *parseBuffer);
1315 bool parseResult = timer->Parse(*parseBuffer);
1318 js["Result"] = false;
1319 js["Error"] = "Timer parsing failed";
1323 if (timer->HasFlags(tfActive) != !(strcasecmp(newActive, "true")))
1325 log->log("JSONServer", Log::DEBUG, "%i %i timeredit set new active: %s", timer->HasFlags(tfActive), !(strcasecmp(newActive, "true")), newActive);
1327 if (strcasecmp(newActive, "true") == 0)
1329 timer->SetFlags(tfActive);
1331 else if (strcasecmp(newActive, "false") == 0)
1333 timer->ClrFlags(tfActive);
1337 js["Result"] = false;
1338 js["Error"] = "Bad request parameters";
1343 js["Result"] = true;
1344 Timers.SetModified();
1349 if (strcmp(timer->File(), newName))
1351 log->log("JSONServer", Log::DEBUG, "timeredit set new name: %s", newName);
1352 timer->SetFile(newName);
1355 if (timer->Day() != atoi(newDay))
1357 log->log("JSONServer", Log::DEBUG, "timeredit set new day: %s", newDay);
1358 timer->SetDay(atoi(newDay));
1361 if (timer->WeekDays() != atoi(newWeekDays))
1363 log->log("JSONServer", Log::DEBUG, "timeredit set new week days: %s", newWeekDays);
1364 timer->SetWeekDays(atoi(newWeekDays));
1367 if (timer->StartTime() != atoi(newStartTime))
1369 log->log("JSONServer", Log::DEBUG, "timeredit set new start time: %s", newStartTime);
1370 time_t nstt = atoi(newStartTime);
1372 localtime_r(&nstt, &nstm);
1373 int nssf = (nstm.tm_hour * 100) + nstm.tm_min;
1374 timer->SetStart(nssf);
1377 if (timer->StopTime() != atoi(newStopTime))
1379 log->log("JSONServer", Log::DEBUG, "timeredit set new stop time: %s", newStopTime);
1380 time_t nztt = atoi(newStopTime);
1382 localtime_r(&nztt, &nztm);
1383 int nzsf = (nztm.tm_hour * 100) + nztm.tm_min;
1384 timer->SetStop(nzsf);
1387 if (timer->Priority() != atoi(newPriority))
1389 log->log("JSONServer", Log::DEBUG, "timeredit set new priority: %s", newPriority);
1390 timer->SetPriority(atoi(newPriority));
1393 if (timer->Lifetime() != atoi(newLifetime))
1395 log->log("JSONServer", Log::DEBUG, "timeredit set new lifetime: %s", newLifetime);
1396 timer->SetLifetime(atoi(newLifetime));
1401 cTimer* jsonserver_findTimer2(const char* rName, const char* rActive, const char* rChannelID, const char* rDay, const char* rWeekDays, const char* rStartTime, const char* rStopTime, const char* rPriority, const char* rLifetime)
1403 Log* log = Log::getInstance();
1405 int numTimers = Timers.Count();
1407 log->log("JSONServer", Log::DEBUG, "findtimer2: %s %s %s %s %s %s %s %s %s", rName, rActive, rChannelID, rDay, rWeekDays, rStartTime, rStopTime, rPriority, rLifetime);
1408 for (int i = 0; i < numTimers; i++)
1410 timer = Timers.Get(i);
1412 log->log("JSONServer", Log::DEBUG, "findtimer2 search: %s %i %s %i %i %i %i %i %i", timer->File(), timer->HasFlags(tfActive), (const char*)timer->Channel()->GetChannelID().ToString(),
1413 (int)timer->Day(), timer->WeekDays(), (int)timer->StartTime(), (int)timer->StopTime(),
1414 timer->Priority(), timer->Lifetime());
1416 if ( (strcmp(timer->File(), rName) == 0)
1417 && (timer->HasFlags(tfActive) == !(strcasecmp(rActive, "true")))
1418 && (strcmp(timer->Channel()->GetChannelID().ToString(), rChannelID) == 0)
1419 && (timer->Day() == atoi(rDay))
1420 && (timer->WeekDays() == atoi(rWeekDays))
1421 && (timer->StartTime() == atoi(rStartTime))
1422 && (timer->StopTime() == atoi(rStopTime))
1423 && (timer->Priority() == atoi(rPriority))
1424 && (timer->Lifetime() == atoi(rLifetime))
1427 log->log("JSONServer", Log::DEBUG, "found");
1431 log->log("JSONServer", Log::DEBUG, "no timer found");
1435 cTimer* jsonserver_findTimer(const char* rChannelID, const char* rName, const char* rStartTime, const char* rStopTime, const char* rWeekDays)
1437 Log* log = Log::getInstance();
1439 int numTimers = Timers.Count();
1441 for (int i = 0; i < numTimers; i++)
1443 timer = Timers.Get(i);
1445 log->log("JSONServer", Log::DEBUG, "findtimer current: %s", (const char*)timer->ToText(true));
1446 log->log("JSONServer", Log::DEBUG, "findtimer: %s", (const char*)timer->Channel()->GetChannelID().ToString());
1447 log->log("JSONServer", Log::DEBUG, "findtimer: %s", rChannelID);
1448 log->log("JSONServer", Log::DEBUG, "findtimer: %s", timer->File());
1449 log->log("JSONServer", Log::DEBUG, "findtimer: %s", rName);
1450 log->log("JSONServer", Log::DEBUG, "findtimer: %i", timer->StartTime());
1451 log->log("JSONServer", Log::DEBUG, "findtimer: %s", rStartTime);
1452 log->log("JSONServer", Log::DEBUG, "findtimer: %i", timer->StopTime());
1453 log->log("JSONServer", Log::DEBUG, "findtimer: %s", rStopTime);
1454 log->log("JSONServer", Log::DEBUG, "findtimer: %i", timer->WeekDays());
1455 log->log("JSONServer", Log::DEBUG, "findtimer: %s", rWeekDays);
1458 (strcmp(timer->Channel()->GetChannelID().ToString(), rChannelID) == 0)
1459 && (strcmp(timer->File(), rName) == 0)
1460 && (timer->StartTime() == atoi(rStartTime))
1461 && (timer->StopTime() == atoi(rStopTime))
1462 && (timer->WeekDays() == atoi(rWeekDays))
1465 log->log("JSONServer", Log::DEBUG, "found");
1469 log->log("JSONServer", Log::DEBUG, "no timer found");
1473 bool jsonserver_timerdel(Json::Value& js, const char* postData)
1475 Log* log = Log::getInstance();
1476 log->log("JSONServer", Log::DEBUG, "timerdel");
1478 char rChannelID[50]; int mgv1 = mg_get_var(postData, strlen(postData), "ChannelID", rChannelID, 50);
1479 char rName[1024]; int mgv2 = mg_get_var(postData, strlen(postData), "Name", rName, 1024);
1480 char rStartTime[20]; int mgv3 = mg_get_var(postData, strlen(postData), "StartTime", rStartTime, 20);
1481 char rStopTime[20]; int mgv4 = mg_get_var(postData, strlen(postData), "StopTime", rStopTime, 20);
1482 char rWeekDays[50]; int mgv5 = mg_get_var(postData, strlen(postData), "WeekDays", rWeekDays, 20);
1484 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) || (mgv4 == -1) || (mgv5 == -1))
1486 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i %i", mgv1, mgv2, mgv3, mgv4, mgv5);
1487 js["Result"] = false;
1488 js["Error"] = "Bad request parameters";
1492 log->log("JSONServer", Log::DEBUG, "timerdel: %s:%s:%s:%s:%s", rChannelID, rName, rStartTime, rStopTime, rWeekDays);
1494 if (Timers.BeingEdited())
1496 log->log("JSONServer", Log::ERR, "Unable to delete timer - timers being edited at VDR");
1497 js["Result"] = false;
1498 js["Error"] = "Timers being edited at VDR";
1502 cTimer* timer = jsonserver_findTimer(rChannelID, rName, rStartTime, rStopTime, rWeekDays);
1505 if (timer->Recording())
1507 log->log("JSONServer", Log::ERR, "Unable to delete timer - timer is running");
1508 js["Result"] = false;
1509 js["Error"] = "Timer is running";
1516 Timers.SetModified();
1517 js["Result"] = true;
1521 js["Result"] = false;
1522 js["Error"] = "Timer not found";
1526 bool jsonserver_timerisrecording(Json::Value& js, const char* postData)
1528 Log* log = Log::getInstance();
1529 log->log("JSONServer", Log::DEBUG, "timerisrecording");
1531 char rChannelID[50]; int mgv1 = mg_get_var(postData, strlen(postData), "ChannelID", rChannelID, 50);
1532 char rName[1024]; int mgv2 = mg_get_var(postData, strlen(postData), "Name", rName, 1024);
1533 char rStartTime[20]; int mgv3 = mg_get_var(postData, strlen(postData), "StartTime", rStartTime, 20);
1534 char rStopTime[20]; int mgv4 = mg_get_var(postData, strlen(postData), "StopTime", rStopTime, 20);
1535 char rWeekDays[50]; int mgv5 = mg_get_var(postData, strlen(postData), "WeekDays", rWeekDays, 20);
1537 if ( (mgv1 == -1) || (mgv2 == -1) || (mgv3 == -1) || (mgv4 == -1) || (mgv5 == -1))
1539 log->log("JSONServer", Log::ERR, "request mgvs: %i %i %i %i %i", mgv1, mgv2, mgv3, mgv4, mgv5);
1540 js["Result"] = false;
1541 js["Error"] = "Bad request parameters";
1545 log->log("JSONServer", Log::DEBUG, "timerisrecording: %s:%s:%s:%s:%s", rChannelID, rName, rStartTime, rStopTime, rWeekDays);
1547 cTimer* timer = jsonserver_findTimer(rChannelID, rName, rStartTime, rStopTime, rWeekDays);
1550 js["Recording"] = timer->Recording();
1551 js["Pending"] = timer->Pending();
1552 js["Result"] = true;
1556 js["Result"] = false;
1557 js["Error"] = "Timer not found";
1561 bool jsonserver_tunersstatus(Json::Value& js, const char* postData)
1563 Log* log = Log::getInstance();
1564 log->log("JSONServer", Log::DEBUG, "tunerstatus");
1566 js["NumDevices"] = cDevice::NumDevices();
1568 Json::Value jsdevices(Json::arrayValue);
1570 for (int i = 0; i < cDevice::NumDevices(); i++)
1572 Json::Value oneDevice;
1573 cDevice *d = cDevice::GetDevice(i);
1574 oneDevice["Number"] = d->DeviceNumber();
1575 oneDevice["Type"] = (const char*)d->DeviceType();
1576 oneDevice["Name"] = (const char*)d->DeviceName();
1577 oneDevice["IsPrimary"] = d->IsPrimaryDevice();
1579 const cChannel* cchannel = d->GetCurrentlyTunedTransponder();
1582 oneDevice["Frequency"] = cchannel->Frequency();
1583 oneDevice["SignalStrength"] = d->SignalStrength();
1584 oneDevice["SignalQuality"] = d->SignalQuality();
1589 oneDevice["Frequency"] = 0;
1590 oneDevice["SignalStrength"] = 0;
1591 oneDevice["SignalQuality"] = 0;
1594 jsdevices.append(oneDevice);
1597 js["Devices"] = jsdevices;
1600 Json::Value jstimers(Json::arrayValue);
1601 int numTimers = Timers.Count();
1603 for (int i = 0; i < numTimers; i++)
1605 timer = Timers.Get(i);
1607 if (timer->Recording())
1609 Json::Value oneTimer;
1610 oneTimer["Recording"] = timer->Recording();
1611 oneTimer["StartTime"] = (int)timer->StartTime();
1612 oneTimer["StopTime"] = (int)timer->StopTime();
1613 oneTimer["File"] = timer->File();
1615 cRecordControl* crc = cRecordControls::GetRecordControl(timer);
1618 cDevice* crcd = crc->Device();
1619 oneTimer["DeviceNumber"] = crcd->DeviceNumber();
1623 oneTimer["DeviceNumber"] = Json::Value::null;
1626 const cChannel* channel = timer->Channel();
1629 oneTimer["ChannelName"] = channel->Name();
1633 oneTimer["ChannelName"] = Json::Value::null;
1636 jstimers.append(oneTimer);
1640 js["CurrentRecordings"] = jstimers;
1643 js["Result"] = true;
1648 bool jsonserver_epgsearchsame(Json::Value& js, const char* postData)
1650 Log* log = Log::getInstance();
1651 log->log("JSONServer", Log::DEBUG, "epgsearchsame");
1653 char sAtTime[15]; int mgv1 = mg_get_var(postData, strlen(postData), "time", sAtTime, 15);
1654 char sTitle[1024]; int mgv2 = mg_get_var(postData, strlen(postData), "title", sTitle, 1024);
1656 if ( (mgv1 == -1) || (mgv2 == -1) )
1658 log->log("JSONServer", Log::ERR, "request mgvs: %i %i", mgv1, mgv2);
1659 js["Result"] = false;
1660 js["Error"] = "Bad request parameters";
1664 int atTime = atoi(sAtTime);
1665 log->log("JSONServer", Log::DEBUG, "request time: %i, title: %s", atTime, sTitle);
1669 cSchedulesLock SchedulesLock;
1670 const cSchedules *schedules = cSchedules::Schedules(SchedulesLock);
1673 js["Result"] = false;
1677 Json::Value jsevents(Json::arrayValue);
1679 const cEvent *event;
1680 for (cSchedule *schedule = schedules->First(); (schedule != NULL); schedule = schedules->Next(schedule))
1682 event = schedule->GetEventAround(atTime);
1683 if (!event) continue; // nothing found on this schedule(channel)
1685 if (!strcmp(event->Title(), sTitle))
1687 Json::Value oneEvent;
1688 oneEvent["ChannelID"] = (const char*)event->ChannelID().ToString();
1689 oneEvent["ID"] = event->EventID();
1690 oneEvent["Time"] = (Json::UInt)event->StartTime();
1691 oneEvent["Duration"] = event->Duration();
1692 oneEvent["Title"] = event->Title() ? event->Title() : "";
1693 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
1694 oneEvent["HasTimer"] = event->HasTimer();
1695 //oneEvent["Description"] = event->Description() ? event->Description() : "";
1696 jsevents.append(oneEvent);
1700 js["Events"] = jsevents;
1701 js["Result"] = true;
1705 bool jsonserver_epgdownload(Json::Value& js, const char* postData)
1707 Log* log = Log::getInstance();
1708 log->log("JSONServer", Log::DEBUG, "channelschedule '%s'", postData);
1710 cSchedulesLock MutexLock;
1711 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
1715 log->log("JSONServer", Log::ERR, "Could not get Schedules object");
1716 js["Result"] = false;
1717 js["Error"] = "Internal schedules error (1)";
1721 Json::Value jsevents(Json::arrayValue);
1723 for (cChannel* channel = Channels.First(); channel; channel = Channels.Next(channel))
1725 if (channel->GroupSep()) continue;
1727 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
1728 if (!Schedule) continue;
1731 for (const cEvent* event = Schedule->Events()->First(); event; event = Schedule->Events()->Next(event))
1733 Json::Value oneEvent;
1734 oneEvent["ChannelNumber"] = channel->Number();
1735 oneEvent["ChannelID"] = (const char*)event->ChannelID().ToString();
1736 oneEvent["ID"] = event->EventID();
1737 oneEvent["Time"] = (Json::UInt)event->StartTime();
1738 oneEvent["Duration"] = event->Duration();
1739 oneEvent["Title"] = event->Title() ? event->Title() : "";
1740 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
1741 oneEvent["HasTimer"] = event->HasTimer();
1742 oneEvent["Description"] = event->Description() ? event->Description() : "";
1743 jsevents.append(oneEvent);
1747 js["Result"] = true;
1748 js["Events"] = jsevents;
1752 bool jsonserver_epgsearch(Json::Value& js, const char* postData)
1754 Log* log = Log::getInstance();
1755 log->log("JSONServer", Log::DEBUG, "epgsearch '%s'", postData);
1757 char searchfor[1024]; int mgv1 = mg_get_var(postData, strlen(postData), "searchfor", searchfor, 1024);
1761 log->log("JSONServer", Log::ERR, "request mgvs: %i", mgv1);
1762 js["Result"] = false;
1763 js["Error"] = "Bad request parameters";
1767 log->log("JSONServer", Log::DEBUG, "search for: %s", searchfor);
1769 cSchedulesLock MutexLock;
1770 const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
1774 log->log("JSONServer", Log::ERR, "Could not get Schedules object");
1775 js["Result"] = false;
1776 js["Error"] = "Internal schedules error (1)";
1780 Json::Value jsevents(Json::arrayValue);
1782 for (cChannel* channel = Channels.First(); channel; channel = Channels.Next(channel))
1784 if (channel->GroupSep()) continue;
1786 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
1787 if (!Schedule) continue;
1790 bool founddescription;
1791 for (const cEvent* event = Schedule->Events()->First(); event; event = Schedule->Events()->Next(event))
1794 founddescription = false;
1796 if (event->Title() && strcasestr(event->Title(), searchfor)) foundtitle = true;
1798 if (!foundtitle && event->Description())
1799 if (strcasestr(event->Description(), searchfor)) founddescription = true;
1801 if (foundtitle || founddescription)
1803 Json::Value oneEvent;
1804 oneEvent["ChannelNumber"] = channel->Number();
1805 oneEvent["ChannelID"] = (const char*)event->ChannelID().ToString();
1806 oneEvent["ID"] = event->EventID();
1807 oneEvent["Time"] = (Json::UInt)event->StartTime();
1808 oneEvent["Duration"] = event->Duration();
1809 oneEvent["Title"] = event->Title() ? event->Title() : "";
1810 oneEvent["ShortText"] = event->ShortText() ? event->ShortText() : "";
1811 oneEvent["HasTimer"] = event->HasTimer();
1812 oneEvent["Description"] = event->Description() ? event->Description() : "";
1813 if (founddescription)
1814 oneEvent["FoundInDesc"] = true;
1816 oneEvent["FoundInDesc"] = false;
1817 jsevents.append(oneEvent);
1822 js["Result"] = true;
1823 js["Events"] = jsevents;