21#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
22#include <QStringConverter>
29#include "libmythbase/mythconfig.h"
36#include "libmythbase/mythversion.h"
60 m_bIsMaster(bIsMaster)
85 return QStringList(
"/Status" );
121 LOG(VB_GENERAL, LOG_ERR,
122 "HttpStatus::ProcessRequest() - Unexpected Exception");
134 QDomDocument doc(
"Status" );
137 QDomProcessingInstruction encoding =
138 doc.createProcessingInstruction(
"xml",
139 R
"(version="1.0" encoding="UTF-8")");
140 doc.appendChild(encoding);
145 pRequest->m_mapRespHeaders[ "Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
148#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
149 stream.setCodec(
"UTF-8");
151 stream.setEncoding(QStringConverter::Utf8);
153 stream << doc.toString();
163 pRequest->
m_mapRespHeaders[
"Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
165 QDomDocument doc(
"Status" );
186 QDomElement root = pDoc->createElement(
"Status");
187 pDoc->appendChild(root);
191 root.setAttribute(
"time" ,
193 root.setAttribute(
"ISODate" , qdtNow.toString(
Qt::ISODate) );
194 root.setAttribute(
"version" , MYTH_BINARY_VERSION );
195 root.setAttribute(
"protoVer", MYTH_PROTO_VERSION );
199 QDomElement encoders = pDoc->createElement(
"Encoders");
200 root.appendChild(encoders);
209 if (elink !=
nullptr)
211 TVState state = elink->GetState();
212 isLocal = elink->IsLocal();
214 QDomElement encoder = pDoc->createElement(
"Encoder");
215 encoders.appendChild(encoder);
217 encoder.setAttribute(
"id" , elink->GetInputID() );
218 encoder.setAttribute(
"local" ,
static_cast<int>(isLocal));
219 encoder.setAttribute(
"connected" ,
static_cast<int>(elink->IsConnected()));
220 encoder.setAttribute(
"state" , state );
221 encoder.setAttribute(
"sleepstatus" , elink->GetSleepStatus() );
227 encoder.setAttribute(
"hostname", elink->GetHostName());
229 encoder.setAttribute(
"devlabel",
232 if (elink->IsConnected())
260 encoders.setAttribute(
"count", numencoders);
264 QDomElement scheduled = pDoc->createElement(
"Scheduled");
265 root.appendChild(scheduled);
272 unsigned int iNum = 10;
273 unsigned int iNumRecordings = 0;
275 auto itProg = recordingList.begin();
276 for (; (itProg != recordingList.end()) && iNumRecordings < iNum; ++itProg)
279 ((*itProg)->GetRecordingStartTime() >=
287 while (!recordingList.empty())
291 recordingList.pop_back();
294 scheduled.setAttribute(
"count", iNumRecordings);
298 QDomElement frontends = pDoc->createElement(
"Frontends");
299 root.appendChild(frontends);
302 "urn:schemas-mythtv-org:service:MythFrontend:1");
310 frontends.setAttribute(
"count", map.size() );
311 for (
const auto & entry : std::as_const(map))
313 QDomElement fe = pDoc->createElement(
"Frontend");
314 frontends.appendChild(fe);
315 QUrl url(entry->m_sLocation);
316 fe.setAttribute(
"name", url.host());
317 fe.setAttribute(
"url", url.toString(QUrl::RemovePath));
324 QDomElement backends = pDoc->createElement(
"Backends");
325 root.appendChild(backends);
335 QDomElement mbe = pDoc->createElement(
"Backend");
336 backends.appendChild(mbe);
337 mbe.setAttribute(
"type",
"Master");
338 mbe.setAttribute(
"name", masterhost);
339 mbe.setAttribute(
"url" , masterip +
":" + QString::number(masterport));
343 "urn:schemas-mythtv-org:device:SlaveMediaServer:1");
347 QString ipaddress = QString();
356 for (
const auto & entry : std::as_const(map))
358 QUrl url(entry->m_sLocation);
359 if (url.host() != ipaddress)
362 QDomElement mbe = pDoc->createElement(
"Backend");
363 backends.appendChild(mbe);
364 mbe.setAttribute(
"type",
"Slave");
365 mbe.setAttribute(
"name", url.host());
366 mbe.setAttribute(
"url" , url.toString(QUrl::RemovePath));
372 backends.setAttribute(
"count", numbes);
376 QDomElement
jobqueue = pDoc->createElement(
"JobQueue");
379 QMap<int, JobQueueEntry> jobs;
380 QMap<int, JobQueueEntry>::Iterator it;
386 for (it = jobs.begin(); it != jobs.end(); ++it)
388 ProgramInfo pginfo((*it).chanid, (*it).recstartts);
392 QDomElement job = pDoc->createElement(
"Job");
395 job.setAttribute(
"id" , (*it).id );
396 job.setAttribute(
"chanId" , (*it).chanid );
397 job.setAttribute(
"startTime" ,
399 job.setAttribute(
"startTs" , (*it).startts );
400 job.setAttribute(
"insertTime",
402 job.setAttribute(
"type" , (*it).type );
403 job.setAttribute(
"cmds" , (*it).cmds );
404 job.setAttribute(
"flags" , (*it).flags );
405 job.setAttribute(
"status" , (*it).status );
406 job.setAttribute(
"statusTime",
408 job.setAttribute(
"schedTime" ,
410 job.setAttribute(
"args" , (*it).args );
412 if ((*it).hostname.isEmpty())
413 job.setAttribute(
"hostname", QObject::tr(
"master"));
415 job.setAttribute(
"hostname",(*it).hostname);
417 QDomText textNode = pDoc->createTextNode((*it).comment);
418 job.appendChild(textNode);
423 jobqueue.setAttribute(
"count", jobs.size() );
427 QDomElement mInfo = pDoc->createElement(
"MachineInfo");
428 QDomElement storage = pDoc->createElement(
"Storage" );
429 QDomElement load = pDoc->createElement(
"Load" );
430 QDomElement guide = pDoc->createElement(
"Guide" );
432 root.appendChild (mInfo );
433 mInfo.appendChild(storage);
434 mInfo.appendChild(load );
435 mInfo.appendChild(guide );
452 QList<QDomElement> fsXML;
453 QStringList::const_iterator sit = strlist.cbegin();
454 while (sit != strlist.cend())
457 directory = *(sit++);
458 isLocalstr = *(sit++);
462 long long iTotal = (*(sit++)).toLongLong();
463 long long iUsed = (*(sit++)).toLongLong();;
464 long long iAvail = iTotal - iUsed;
469 QDomElement group = pDoc->createElement(
"Group");
471 group.setAttribute(
"id" , fsID );
472 group.setAttribute(
"total", (
int)(iTotal>>10) );
473 group.setAttribute(
"used" , (
int)(iUsed>>10) );
474 group.setAttribute(
"free" , (
int)(iAvail>>10) );
475 group.setAttribute(
"dir" , directory );
479 long long iLiveTV = -1;
480 long long iDeleted = -1;
481 long long iExpirable = -1;
483 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
484 " WHERE recgroup = :RECGROUP;");
489 iLiveTV = query.
value(0).toLongLong();
494 iDeleted = query.
value(0).toLongLong();
496 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
497 " WHERE autoexpire = 1 "
498 " AND recgroup NOT IN ('LiveTV', 'Deleted');");
501 iExpirable = query.
value(0).toLongLong();
503 group.setAttribute(
"livetv", (
int)(iLiveTV>>20) );
504 group.setAttribute(
"deleted", (
int)(iDeleted>>20) );
505 group.setAttribute(
"expirable", (
int)(iExpirable>>20) );
514 storage.appendChild(total);
515 int num_elements = fsXML.size();
516 for (
int fs_index = 0; fs_index < num_elements; fs_index++)
518 storage.appendChild(fsXML[fs_index]);
524 load.setAttribute(
"avg1", 0);
525 load.setAttribute(
"avg2", 1);
526 load.setAttribute(
"avg3", 2);
529 if (rgdAverages[0] != -1)
531 load.setAttribute(
"avg1", rgdAverages[0]);
532 load.setAttribute(
"avg2", rgdAverages[1]);
533 load.setAttribute(
"avg3", rgdAverages[2]);
539 QDateTime GuideDataThrough;
542 query.
prepare(
"SELECT MAX(endtime) FROM program WHERE manualid = 0;");
549 guide.setAttribute(
"start",
551 guide.setAttribute(
"end",
553 guide.setAttribute(
"status",
557 guide.setAttribute(
"next",
561 if (!GuideDataThrough.isNull())
563 guide.setAttribute(
"guideThru",
565 guide.setAttribute(
"guideDays", qdtNow.daysTo(GuideDataThrough));
571 if ((!info_script.isEmpty()) && (info_script !=
"none"))
573 QDomElement misc = pDoc->createElement(
"Miscellaneous");
574 root.appendChild(misc);
581 LOG(VB_GENERAL, LOG_ERR,
582 QString(
"Error running miscellaneous "
583 "status information script: %1").arg(info_script));
587 QByteArray input = ms.
ReadAll();
589 QStringList
output = QString(input).split(
'\n',
591 for (
const auto & line : std::as_const(
output))
593 QDomElement
info = pDoc->createElement(
"Information");
595 QStringList list = line.split(
"[]:[]");
596 unsigned int size = list.size();
597 unsigned int hasAttributes = 0;
599 if ((size > 0) && (!list[0].isEmpty()))
601 info.setAttribute(
"display", list[0]);
604 if ((size > 1) && (!list[1].isEmpty()))
606 info.setAttribute(
"name", list[1]);
609 if ((size > 2) && (!list[2].isEmpty()))
611 info.setAttribute(
"value", list[2]);
615 if (hasAttributes > 0)
616 misc.appendChild(
info);
627#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
628 os.setCodec(
"UTF-8");
630 os.setEncoding(QStringConverter::Utf8);
635 QDomElement docElem = pDoc->documentElement();
637 os <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
638 <<
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n"
639 <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\""
640 <<
" xml:lang=\"en\" lang=\"en\">\r\n"
642 <<
" <meta http-equiv=\"Content-Type\""
643 <<
"content=\"text/html; charset=UTF-8\" />\r\n"
644 <<
" <link rel=\"stylesheet\" href=\"/css/Status.css\" type=\"text/css\">\r\n"
645 <<
" <title>MythTV Status - "
649 << docElem.attribute(
"version", MYTH_BINARY_VERSION ) <<
"</title>\r\n"
651 <<
"<body bgcolor=\"#fff\">\r\n"
652 <<
"<div class=\"status\">\r\n"
653 <<
" <h1 class=\"status\">MythTV Status</h1>\r\n";
657 QDomNode node = docElem.namedItem(
"Encoders" );
664 node = docElem.namedItem(
"Scheduled" );
671 node = docElem.namedItem(
"Frontends" );
678 node = docElem.namedItem(
"Backends" );
685 node = docElem.namedItem(
"JobQueue" );
692 node = docElem.namedItem(
"MachineInfo" );
699 node = docElem.namedItem(
"Miscellaneous" );
704 os <<
"\r\n</div>\r\n</body>\r\n</html>\r\n";
714 int nNumEncoders = 0;
716 if (encoders.isNull())
719 os <<
" <div class=\"content\">\r\n"
720 <<
" <h2 class=\"status\">Encoder Status</h2>\r\n";
722 QDomNode node = encoders.firstChild();
724 while (!node.isNull())
726 QDomElement e = node.toElement();
730 if (e.tagName() ==
"Encoder")
732 QString sIsLocal = (e.attribute(
"local" ,
"remote" )==
"1")
733 ?
"local" :
"remote";
734 QString sCardId = e.attribute(
"id" ,
"0" );
735 QString sHostName = e.attribute(
"hostname" ,
"Unknown");
736 bool bConnected=
static_cast<bool>(e.attribute(
"connected",
"0" ).toInt());
738 bool bIsLowOnFreeSpace=
static_cast<bool>(e.attribute(
"lowOnFreeSpace",
"0").toInt());
740 QString sDevlabel = e.attribute(
"devlabel",
"[ UNKNOWN ]");
742 os <<
" Encoder " << sCardId <<
" " << sDevlabel
743 <<
" is " << sIsLocal <<
" on " << sHostName;
745 if ((sIsLocal ==
"remote") && !bConnected)
752 os <<
" (currently asleep).<br />";
754 os <<
" (currently not connected).<br />";
756 node = node.nextSibling();
767 os <<
" and is watching Live TV";
772 os <<
" and is recording";
776 os <<
" and is not recording.";
782 QDomNode tmpNode = e.namedItem(
"Program" );
784 if (!tmpNode.isNull())
786 QDomElement program = tmpNode.toElement();
788 if (!program.isNull())
790 os <<
" '" << program.attribute(
"title",
"Unknown" ) <<
"'";
794 tmpNode = program.namedItem(
"Channel" );
796 if (!tmpNode.isNull())
798 QDomElement channel = tmpNode.toElement();
800 if (!channel.isNull())
802 << channel.attribute(
"callSign",
"unknown" );
807 tmpNode = program.namedItem(
"Recording" );
809 if (!tmpNode.isNull())
811 QDomElement recording = tmpNode.toElement();
813 if (!recording.isNull())
816 recording.attribute(
"recEndTs",
"" ));
818 os <<
". This recording ";
824 os <<
"scheduled to end at "
834 if (bIsLowOnFreeSpace)
836 os <<
" <strong>WARNING</strong>:"
837 <<
" This backend is low on free disk space!";
844 node = node.nextSibling();
847 os <<
" </div>\r\n\r\n";
849 return( nNumEncoders );
860 if (scheduled.isNull())
863 int nNumRecordings= scheduled.attribute(
"count",
"0" ).toInt();
865 os <<
" <div class=\"content\">\r\n"
866 <<
" <h2 class=\"status\">Schedule</h2>\r\n";
868 if (nNumRecordings == 0)
870 os <<
" There are no shows scheduled for recording.\r\n"
875 os <<
" The next " << nNumRecordings <<
" show" << (nNumRecordings == 1 ?
"" :
"s" )
876 <<
" that " << (nNumRecordings == 1 ?
"is" :
"are")
877 <<
" scheduled for recording:\r\n";
879 os <<
" <div class=\"schedule\">\r\n";
883 QDomNode node = scheduled.firstChild();
885 while (!node.isNull())
887 QDomElement e = node.toElement();
891 QDomNode recNode = e.namedItem(
"Recording" );
892 QDomNode chanNode = e.namedItem(
"Channel" );
894 if ((e.tagName() ==
"Program") && !recNode.isNull() &&
897 QDomElement r = recNode.toElement();
898 QDomElement c = chanNode.toElement();
900 QString sTitle = e.attribute(
"title" ,
"" );
901 QString sSubTitle = e.attribute(
"subTitle",
"" );
907 int nPreRollSecs = r.attribute(
"preRollSeconds",
"0" ).toInt();
908 int nEncoderId = r.attribute(
"encoderId" ,
"0" ).toInt();
909 QString sProfile = r.attribute(
"recProfile" ,
"" );
910 QString sChanName = c.attribute(
"channelName" ,
"" );
913 QDomText text = e.firstChild().toText();
915 sDesc = text.nodeValue();
919 int nTotalSecs = qdtNow.secsTo( recStartTs ) - nPreRollSecs;
925 int nTotalDays = nTotalSecs / 86400;
926 int nTotalHours = (nTotalSecs / 3600)
928 int nTotalMins = (nTotalSecs / 60) % 60;
930 QString sTimeToStart =
"in";
932 sTimeToStart += QObject::tr(
" %n day(s),",
"", nTotalDays );
933 sTimeToStart += QObject::tr(
" %n hour(s) and",
"", nTotalHours);
934 sTimeToStart += QObject::tr(
" %n minute(s)",
"", nTotalMins);
936 if ( nTotalHours == 0 && nTotalMins == 0)
937 sTimeToStart = QObject::tr(
"within one minute",
"Recording starting");
940 sTimeToStart = QObject::tr(
"soon",
"Recording starting");
944 os <<
" <a href=\"#\">";
952 os <<
"Encoder " << nEncoderId <<
" - ";
954 os << sChanName <<
" - " << sTitle <<
"<br />"
955 <<
"<span><strong>" << sTitle <<
"</strong> ("
959 if ( !sSubTitle.isEmpty())
960 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
962 if ( airDate.isValid())
964 os <<
"Orig. Airdate: "
970 os << sDesc <<
"<br /><br />"
971 <<
"This recording will start " << sTimeToStart
972 <<
" using encoder " << nEncoderId <<
" with the '"
973 << sProfile <<
"' profile.</span></a><hr />\r\n";
977 node = node.nextSibling();
980 os <<
" </div>\r\n\r\n";
982 return( nNumRecordings );
991 if (frontends.isNull())
994 int nNumFES= frontends.attribute(
"count",
"0" ).toInt();
1000 os <<
" <div class=\"content\">\r\n"
1001 <<
" <h2 class=\"status\">Frontends</h2>\r\n";
1003 QDomNode node = frontends.firstChild();
1004 while (!node.isNull())
1006 QDomElement e = node.toElement();
1010 QString name = e.attribute(
"name" ,
"" );
1011 QString url = e.attribute(
"url" ,
"" );
1012 os << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1015 node = node.nextSibling();
1018 os <<
" </div>\r\n\r\n";
1029 if (backends.isNull())
1032 int nNumBES= backends.attribute(
"count",
"0" ).toInt();
1038 os <<
" <div class=\"content\">\r\n"
1039 <<
" <h2 class=\"status\">Other Backends</h2>\r\n";
1041 QDomNode node = backends.firstChild();
1042 while (!node.isNull())
1044 QDomElement e = node.toElement();
1048 QString
type = e.attribute(
"type",
"" );
1049 QString name = e.attribute(
"name" ,
"" );
1050 QString url = e.attribute(
"url" ,
"" );
1051 os <<
type <<
": " << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1054 node = node.nextSibling();
1057 os <<
" </div>\r\n\r\n";
1071 int nNumJobs= jobs.attribute(
"count",
"0" ).toInt();
1073 os <<
" <div class=\"content\">\r\n"
1074 <<
" <h2 class=\"status\">Job Queue</h2>\r\n";
1078 QString statusColor;
1081 os <<
" Jobs currently in Queue or recently ended:\r\n<br />"
1082 <<
" <div class=\"schedule\">\r\n";
1085 QDomNode node = jobs.firstChild();
1087 while (!node.isNull())
1089 QDomElement e = node.toElement();
1093 QDomNode progNode = e.namedItem(
"Program" );
1095 if ((e.tagName() ==
"Job") && !progNode.isNull() )
1097 QDomElement
p = progNode.toElement();
1099 QDomNode recNode =
p.namedItem(
"Recording" );
1100 QDomNode chanNode =
p.namedItem(
"Channel" );
1102 QDomElement r = recNode.toElement();
1103 QDomElement c = chanNode.toElement();
1105 int nType = e.attribute(
"type" ,
"0" ).toInt();
1106 int nStatus = e.attribute(
"status",
"0" ).toInt();
1111 statusColor =
" class=\"jobaborted\"";
1116 statusColor =
" class=\"joberrored\"";
1117 jobColor =
" class=\"joberrored\"";
1121 statusColor =
" class=\"jobfinished\"";
1122 jobColor =
" class=\"jobfinished\"";
1126 statusColor =
" class=\"jobrunning\"";
1127 jobColor =
" class=\"jobrunning\"";
1131 statusColor =
" class=\"jobqueued\"";
1132 jobColor =
" class=\"jobqueued\"";
1136 QString sTitle =
p.attribute(
"title" ,
"" );
1137 QString sSubTitle =
p.attribute(
"subTitle",
"" );
1143 QString sHostname = e.attribute(
"hostname",
"master" );
1144 QString sComment =
"";
1146 QDomText text = e.firstChild().toText();
1148 sComment = text.nodeValue();
1150 os <<
"<a href=\"javascript:void(0)\">"
1154 << sTitle <<
" - <font" << jobColor <<
">"
1156 <<
"<span><strong>" << sTitle <<
"</strong> ("
1160 if (!sSubTitle.isEmpty())
1161 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
1167 os <<
"Scheduled Run Time: "
1174 os <<
"Status: <font" << statusColor <<
">"
1182 if ( nStatus != JOB_QUEUED)
1183 os <<
"Host: " << sHostname <<
"<br />";
1185 if (!sComment.isEmpty())
1186 os <<
"<br />Comments:<br />" << sComment <<
"<br />";
1188 os <<
"</span></a><hr />\r\n";
1192 node = node.nextSibling();
1194 os <<
" </div>\r\n";
1198 os <<
" Job Queue is currently empty.\r\n\r\n";
1201 os <<
" </div>\r\n\r\n ";
1218 os <<
"<div class=\"content\">\r\n"
1219 <<
" <h2 class=\"status\">Machine Information</h2>\r\n";
1223 QDomNode node =
info.namedItem(
"Load" );
1227 QDomElement e = node.toElement();
1231 double dAvg1 = e.attribute(
"avg1" ,
"0" ).toDouble();
1232 double dAvg2 = e.attribute(
"avg2" ,
"0" ).toDouble();
1233 double dAvg3 = e.attribute(
"avg3" ,
"0" ).toDouble();
1235 os <<
" <div class=\"loadstatus\">\r\n"
1236 <<
" This machine's load average:"
1237 <<
"\r\n <ul>\r\n <li>"
1238 <<
"1 Minute: " << dAvg1 <<
"</li>\r\n"
1239 <<
" <li>5 Minutes: " << dAvg2 <<
"</li>\r\n"
1240 <<
" <li>15 Minutes: " << dAvg3
1241 <<
"</li>\r\n </ul>\r\n"
1247 node =
info.namedItem(
"Storage" );
1248 QDomElement storage = node.toElement();
1249 node = storage.firstChild();
1254 while (!node.isNull())
1256 QDomElement g = node.toElement();
1258 if (!g.isNull() && g.tagName() ==
"Group")
1260 QString
id = g.attribute(
"id",
"" );
1264 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1265 int nTotal = g.attribute(
"total",
"0" ).toInt();
1266 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1267 int nLiveTV = g.attribute(
"livetv" ,
"0" ).toInt();
1268 int nDeleted = g.attribute(
"deleted",
"0" ).toInt();
1269 int nExpirable = g.attribute(
"expirable" ,
"0" ).toInt();
1270 QString nDir = g.attribute(
"dir" ,
"" );
1272 nDir.replace(
",",
", ");
1274 os <<
" Disk Usage Summary:<br />\r\n";
1277 os <<
" <li>Total Disk Space:\r\n"
1280 os <<
" <li>Total Space: ";
1281 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1282 os << sRep <<
"</li>\r\n";
1284 os <<
" <li>Space Used: ";
1285 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1286 os << sRep <<
"</li>\r\n";
1288 os <<
" <li>Space Free: ";
1289 sRep = QString(
"%L1").arg(nFree) +
" MB";
1290 os << sRep <<
"</li>\r\n";
1292 if ((nLiveTV + nDeleted + nExpirable) > 0)
1294 os <<
" <li>Space Available "
1295 "After Auto-expire: ";
1296 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1297 sRep = QString(
"%L1").arg(nFree + nLiveTV +
1298 nDeleted + nExpirable) +
" MB";
1299 os << sRep <<
"\r\n";
1301 os <<
" <li>Space Used by LiveTV: ";
1302 sRep = QString(
"%L1").arg(nLiveTV) +
" MB";
1303 os << sRep <<
"</li>\r\n";
1304 os <<
" <li>Space Used by "
1305 "Deleted Recordings: ";
1306 sRep = QString(
"%L1").arg(nDeleted) +
" MB";
1307 os << sRep <<
"</li>\r\n";
1308 os <<
" <li>Space Used by "
1309 "Auto-expirable Recordings: ";
1310 sRep = QString(
"%L1").arg(nExpirable) +
" MB";
1311 os << sRep <<
"</li>\r\n";
1324 node = node.nextSibling();
1328 node = storage.firstChild();
1330 os <<
" Disk Usage Details:<br />\r\n";
1334 while (!node.isNull())
1336 QDomElement g = node.toElement();
1338 if (!g.isNull() && g.tagName() ==
"Group")
1340 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1341 int nTotal = g.attribute(
"total",
"0" ).toInt();
1342 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1343 QString nDir = g.attribute(
"dir" ,
"" );
1344 QString
id = g.attribute(
"id" ,
"" );
1346 nDir.replace(
",",
", ");
1352 os <<
" <li>MythTV Drive #" <<
id <<
":"
1356 if (nDir.contains(
','))
1357 os <<
" <li>Directories: ";
1359 os <<
" <li>Directory: ";
1361 os << nDir <<
"</li>\r\n";
1363 os <<
" <li>Total Space: ";
1364 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1365 os << sRep <<
"</li>\r\n";
1367 os <<
" <li>Space Used: ";
1368 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1369 os << sRep <<
"</li>\r\n";
1371 os <<
" <li>Space Free: ";
1372 sRep = QString(
"%L1").arg(nFree) +
" MB";
1373 os << sRep <<
"</li>\r\n";
1381 node = node.nextSibling();
1388 node =
info.namedItem(
"Guide" );
1392 QDomElement e = node.toElement();
1396 int nDays = e.attribute(
"guideDays",
"0" ).toInt();
1397 QString sStart = e.attribute(
"start" ,
"" );
1398 QString sEnd = e.attribute(
"end" ,
"" );
1399 QString sStatus = e.attribute(
"status" ,
"" );
1401 QString sNext = next.isNull() ?
"" :
1407 QDomText text = e.firstChild().toText();
1414 sMsg = text.nodeValue();
1416 os <<
" Last mythfilldatabase run started on " << sStart
1422 os <<
"ended on " << sEnd <<
". ";
1424 os << sStatus <<
"<br />\r\n";
1426 if (!next.isNull() && next >= lastrunstart)
1428 os <<
" Suggested next mythfilldatabase run: "
1429 << sNext <<
".<br />\r\n";
1434 os <<
" There's guide data until "
1438 os <<
" " << QObject::tr(
"(%n day(s))",
"", nDays);
1443 os <<
" <strong>WARNING</strong>: is mythfilldatabase running?";
1447 os <<
" There's <strong>no guide data</strong> available! "
1448 <<
"Have you run mythfilldatabase?";
1452 os <<
"\r\n </div>\r\n";
1464 QDomNodeList nodes =
info.elementsByTagName(
"Information");
1465 uint count = nodes.count();
1471 os <<
"<div class=\"content\">\r\n"
1472 <<
" <h2 class=\"status\">Miscellaneous</h2>\r\n";
1473 for (
unsigned int i = 0; i < count; i++)
1475 QDomNode node = nodes.item(i);
1479 QDomElement e = node.toElement();
1483 display = e.attribute(
"display",
"");
1487 if (display.isEmpty())
1492 if (display.contains(
"<p>", Qt::CaseInsensitive) ||
1493 display.contains(
"<br", Qt::CaseInsensitive))
1500 linebreak =
"<br />\r\n";
1503 os <<
" " << display << linebreak;
1517 if ((pDoc ==
nullptr) || (pInfo ==
nullptr))
1522 QDomElement program = pDoc->createElement(
"Program" );
1523 node.appendChild( program );
1525 program.setAttribute(
"startTime" ,
1528 program.setAttribute(
"title" , pInfo->
GetTitle() );
1529 program.setAttribute(
"subTitle" , pInfo->
GetSubtitle());
1530 program.setAttribute(
"category" , pInfo->
GetCategory());
1532 program.setAttribute(
"repeat" ,
static_cast<int>(pInfo->
IsRepeat()));
1537 program.setAttribute(
"seriesId" , pInfo->
GetSeriesID() );
1538 program.setAttribute(
"programId" , pInfo->
GetProgramID() );
1539 program.setAttribute(
"stars" , pInfo->
GetStars() );
1540 program.setAttribute(
"fileSize" ,
1542 program.setAttribute(
"lastModified",
1545 program.setAttribute(
"hostname" , pInfo->
GetHostname() );
1548 program.setAttribute(
1551 QDomText textNode = pDoc->createTextNode( pInfo->
GetDescription() );
1552 program.appendChild( textNode );
1560 QDomElement channel = pDoc->createElement(
"Channel" );
1561 program.appendChild( channel );
1570 QDomElement recording = pDoc->createElement(
"Recording" );
1571 program.appendChild( recording );
1573 recording.setAttribute(
"recStatus" ,
1575 recording.setAttribute(
"recPriority" ,
1577 recording.setAttribute(
"recStartTs" ,
1579 recording.setAttribute(
"recEndTs" ,
1584 recording.setAttribute(
"recordId" ,
1586 recording.setAttribute(
"recGroup" ,
1588 recording.setAttribute(
"playGroup" ,
1590 recording.setAttribute(
"recType" ,
1592 recording.setAttribute(
"dupInType" ,
1594 recording.setAttribute(
"dupMethod" ,
1596 recording.setAttribute(
"encoderId" ,
1599 recording.setAttribute(
"recProfile" ,
1626 channel.setAttribute(
"chanId" , pInfo->
GetChanID() );
1627 channel.setAttribute(
"chanNum" , pInfo->
GetChanNum());
1634 channel.setAttribute(
"chanFilters",
1636 channel.setAttribute(
"sourceId" , pInfo->
GetSourceID() );
1637 channel.setAttribute(
"inputId" , pInfo->
GetInputID() );
1638 channel.setAttribute(
"commFree" ,
static QString GetDeviceLabel(const QString &inputtype, const QString &videodevice)
HttpResponseType m_eResponseType
QStringMap m_mapRespHeaders
static int PrintJobQueue(QTextStream &os, const QDomElement &jobs)
static int PrintScheduled(QTextStream &os, const QDomElement &scheduled)
static void FillChannelInfo(QDomElement &channel, ProgramInfo *pInfo, bool bDetails=true)
static void FillProgramInfo(QDomDocument *pDoc, QDomNode &node, ProgramInfo *pInfo, bool bIncChannel=true, bool bDetails=true)
static int PrintMiscellaneousInfo(QTextStream &os, const QDomElement &info)
QMap< int, EncoderLink * > * m_pEncoders
static HttpStatusMethod GetMethod(const QString &sURI)
static int PrintEncoderStatus(QTextStream &os, const QDomElement &encoders)
void FillStatusXML(QDomDocument *pDoc)
void GetStatusXML(HTTPRequest *pRequest)
bool ProcessRequest(HTTPRequest *pRequest) override
MainServer * m_pMainServer
static void PrintStatus(QTextStream &os, QDomDocument *pDoc)
QStringList GetBasePaths() override
HttpStatus(QMap< int, EncoderLink * > *tvList, Scheduler *sched, bool bIsMaster)
static int PrintBackends(QTextStream &os, const QDomElement &backends)
static int PrintMachineInfo(QTextStream &os, const QDomElement &info)
static int PrintFrontends(QTextStream &os, const QDomElement &frontends)
void GetStatusHTML(HTTPRequest *pRequest)
static int GetJobsInQueue(QMap< int, JobQueueEntry > &jobs, int findJobs=JOB_LIST_NOT_DONE)
static QString JobText(int jobType)
static QString StatusText(int status)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
void BackendQueryDiskSpace(QStringList &strlist, bool consolidated, bool allHosts)
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
QString GetHostName(void)
QString GetSetting(const QString &key, const QString &defaultval="")
int GetMasterServerStatusPort(void)
Returns the Master Backend status port If no master server status port has been defined in the databa...
int GetNumSetting(const QString &key, int defaultval=0)
QString GetMasterHostName(void)
bool IsMasterBackend(void)
is this the actual MBE process
bool GetBoolSetting(const QString &key, bool defaultval=false)
uint Wait(std::chrono::seconds timeout=0s)
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
Holds information on recordings and videos.
float GetStars(void) const
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
uint GetRecordingRuleID(void) const
RecordingDupMethodType GetDuplicateCheckMethod(void) const
What should be compared to determine if two programs are the same?
QString GetSeriesID(void) const
QString GetCategoryTypeString(void) const
Returns catType as a string.
QString GetProgramID(void) const
QString GetRecordingGroup(void) const
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
QString GetChannelPlaybackFilters(void) const
RecordingDupInType GetDuplicateCheckSource(void) const
Where should we check for duplicates?
bool IsRepeat(void) const
QString GetHostname(void) const
uint GetSourceID(void) const
QString GetPlaybackGroup(void) const
QString GetDescription(void) const
QDateTime GetLastModifiedTime(void) const
QString GetChannelName(void) const
This is the channel name in the local market, i.e.
QString GetTitle(void) const
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
bool IsCommercialFree(void) const
int GetRecordingPriority(void) const
QDate GetOriginalAirDate(void) const
uint GetInputID(void) const
virtual uint64_t GetFilesize(void) const
uint32_t GetProgramFlags(void) const
RecStatus::Type GetRecordingStatus(void) const
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
QString GetSubtitle(void) const
QString GetCategory(void) const
RecordingType GetRecordingRuleType(void) const
QString GetChannelSchedulingID(void) const
This is the unique programming identifier of a channel.
Holds information on a TV Program one might wish to record.
QString GetProgramRecordingProfile(void) const
Returns recording profile name that will be, or was used, for this program, creating "record" field i...
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
void GetEntryMap(EntryMap &map)
Returns a copy of the EntryMap.
static SSDPCache * Instance()
SSDPCacheEntries * Find(const QString &sURI)
Finds the SSDPCacheEntries in the cache, returns nullptr when absent.
bool GetAllPending(RecList &retList, int recRuleId=0) const
static QReadWriteLock s_inputsLock
static QList< QHostAddress > g_IPAddrList
@ GENERIC_EXIT_OK
Exited with no error.
static QString setting_to_localtime(const char *setting)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
loadArray getLoadAvgs(void)
Returns the system load averages.
std::array< double, 3 > loadArray
std::deque< RecordingInfo * > RecList
@ kMSStdOut
allow access to stdout
@ kMSRunShell
run process through shell
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
@ kDateTimeFull
Default local time.
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
@ kDateFull
Default local time.
@ kTime
Default local time.
@ kAddYear
Add year to string if not included.
@ kDateShort
Default local time.
@ kDatabase
Default UTC, database format.
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
QMap< QString, DeviceLocation * > EntryMap
Key == Unique Service Name (USN)
SleepStatus
SleepStatus is an enumeration of the awake/sleep status of a slave.
@ sStatus_Asleep
A slave is considered asleep when it is not awake and not undefined.
@ sStatus_Undefined
A slave's sleep status is undefined when it has never connected to the master backend or is not able ...
TVState
TVState is an enumeration of the states used by TV and TVRec.
@ kState_RecordingOnly
Recording Only is a TVRec only state for when we are recording a program, but there is no one current...
@ kState_WatchingLiveTV
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
@ kState_WatchingRecording
Watching Recording is the state for when we are watching an in progress recording,...