21#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
22#include <QStringConverter>
29#include "libmythbase/mythconfig.h"
36#include "libmythbase/mythversion.h"
61 m_bIsMaster(bIsMaster)
86 return QStringList(
"/Status" );
122 LOG(VB_GENERAL, LOG_ERR,
123 "HttpStatus::ProcessRequest() - Unexpected Exception");
135 QDomDocument doc(
"Status" );
138 QDomProcessingInstruction encoding =
139 doc.createProcessingInstruction(
"xml",
140 R
"(version="1.0" encoding="UTF-8")");
141 doc.appendChild(encoding);
146 pRequest->m_mapRespHeaders[ "Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
149#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
150 stream.setCodec(
"UTF-8");
152 stream.setEncoding(QStringConverter::Utf8);
154 stream << doc.toString();
164 pRequest->
m_mapRespHeaders[
"Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
166 QDomDocument doc(
"Status" );
187 QDomElement root = pDoc->createElement(
"Status");
188 pDoc->appendChild(root);
192 root.setAttribute(
"time" ,
194 root.setAttribute(
"ISODate" , qdtNow.toString(
Qt::ISODate) );
195 root.setAttribute(
"version" , MYTH_BINARY_VERSION );
196 root.setAttribute(
"protoVer", MYTH_PROTO_VERSION );
200 QDomElement encoders = pDoc->createElement(
"Encoders");
201 root.appendChild(encoders);
210 if (elink !=
nullptr)
212 TVState state = elink->GetState();
213 isLocal = elink->IsLocal();
215 QDomElement encoder = pDoc->createElement(
"Encoder");
216 encoders.appendChild(encoder);
218 encoder.setAttribute(
"id" , elink->GetInputID() );
219 encoder.setAttribute(
"local" ,
static_cast<int>(isLocal));
220 encoder.setAttribute(
"connected" ,
static_cast<int>(elink->IsConnected()));
221 encoder.setAttribute(
"state" , state );
222 encoder.setAttribute(
"sleepstatus" , elink->GetSleepStatus() );
228 encoder.setAttribute(
"hostname", elink->GetHostName());
230 encoder.setAttribute(
"devlabel",
233 if (elink->IsConnected())
261 encoders.setAttribute(
"count", numencoders);
265 QDomElement scheduled = pDoc->createElement(
"Scheduled");
266 root.appendChild(scheduled);
273 unsigned int iNum = 10;
274 unsigned int iNumRecordings = 0;
276 auto itProg = recordingList.begin();
277 for (; (itProg != recordingList.end()) && iNumRecordings < iNum; ++itProg)
280 ((*itProg)->GetRecordingStartTime() >=
288 while (!recordingList.empty())
292 recordingList.pop_back();
295 scheduled.setAttribute(
"count", iNumRecordings);
299 QDomElement frontends = pDoc->createElement(
"Frontends");
300 root.appendChild(frontends);
303 "urn:schemas-mythtv-org:service:MythFrontend:1");
311 frontends.setAttribute(
"count", map.size() );
312 for (
const auto & entry : std::as_const(map))
314 QDomElement fe = pDoc->createElement(
"Frontend");
315 frontends.appendChild(fe);
316 QUrl url(entry->m_sLocation);
317 fe.setAttribute(
"name", url.host());
318 fe.setAttribute(
"url", url.toString(QUrl::RemovePath));
325 QDomElement backends = pDoc->createElement(
"Backends");
326 root.appendChild(backends);
336 QDomElement mbe = pDoc->createElement(
"Backend");
337 backends.appendChild(mbe);
338 mbe.setAttribute(
"type",
"Master");
339 mbe.setAttribute(
"name", masterhost);
340 mbe.setAttribute(
"url" , masterip +
":" + QString::number(masterport));
344 "urn:schemas-mythtv-org:device:SlaveMediaServer:1");
348 QString ipaddress = QString();
357 for (
const auto & entry : std::as_const(map))
359 QUrl url(entry->m_sLocation);
360 if (url.host() != ipaddress)
363 QDomElement mbe = pDoc->createElement(
"Backend");
364 backends.appendChild(mbe);
365 mbe.setAttribute(
"type",
"Slave");
366 mbe.setAttribute(
"name", url.host());
367 mbe.setAttribute(
"url" , url.toString(QUrl::RemovePath));
373 backends.setAttribute(
"count", numbes);
377 QDomElement
jobqueue = pDoc->createElement(
"JobQueue");
380 QMap<int, JobQueueEntry> jobs;
381 QMap<int, JobQueueEntry>::Iterator it;
387 for (it = jobs.begin(); it != jobs.end(); ++it)
389 ProgramInfo pginfo((*it).chanid, (*it).recstartts);
393 QDomElement job = pDoc->createElement(
"Job");
396 job.setAttribute(
"id" , (*it).id );
397 job.setAttribute(
"chanId" , (*it).chanid );
398 job.setAttribute(
"startTime" ,
400 job.setAttribute(
"startTs" , (*it).startts );
401 job.setAttribute(
"insertTime",
403 job.setAttribute(
"type" , (*it).type );
404 job.setAttribute(
"cmds" , (*it).cmds );
405 job.setAttribute(
"flags" , (*it).flags );
406 job.setAttribute(
"status" , (*it).status );
407 job.setAttribute(
"statusTime",
409 job.setAttribute(
"schedTime" ,
411 job.setAttribute(
"args" , (*it).args );
413 if ((*it).hostname.isEmpty())
414 job.setAttribute(
"hostname", QObject::tr(
"master"));
416 job.setAttribute(
"hostname",(*it).hostname);
418 QDomText textNode = pDoc->createTextNode((*it).comment);
419 job.appendChild(textNode);
424 jobqueue.setAttribute(
"count", jobs.size() );
428 QDomElement mInfo = pDoc->createElement(
"MachineInfo");
429 QDomElement storage = pDoc->createElement(
"Storage" );
430 QDomElement load = pDoc->createElement(
"Load" );
431 QDomElement guide = pDoc->createElement(
"Guide" );
433 root.appendChild (mInfo );
434 mInfo.appendChild(storage);
435 mInfo.appendChild(load );
436 mInfo.appendChild(guide );
453 QList<QDomElement> fsXML;
454 QStringList::const_iterator sit = strlist.cbegin();
455 while (sit != strlist.cend())
458 directory = *(sit++);
459 isLocalstr = *(sit++);
463 long long iTotal = (*(sit++)).toLongLong();
464 long long iUsed = (*(sit++)).toLongLong();;
465 long long iAvail = iTotal - iUsed;
470 QDomElement group = pDoc->createElement(
"Group");
472 group.setAttribute(
"id" , fsID );
473 group.setAttribute(
"total", (
int)(iTotal>>10) );
474 group.setAttribute(
"used" , (
int)(iUsed>>10) );
475 group.setAttribute(
"free" , (
int)(iAvail>>10) );
476 group.setAttribute(
"dir" , directory );
480 long long iLiveTV = -1;
481 long long iDeleted = -1;
482 long long iExpirable = -1;
484 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
485 " WHERE recgroup = :RECGROUP;");
490 iLiveTV = query.
value(0).toLongLong();
495 iDeleted = query.
value(0).toLongLong();
497 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
498 " WHERE autoexpire = 1 "
499 " AND recgroup NOT IN ('LiveTV', 'Deleted');");
502 iExpirable = query.
value(0).toLongLong();
504 group.setAttribute(
"livetv", (
int)(iLiveTV>>20) );
505 group.setAttribute(
"deleted", (
int)(iDeleted>>20) );
506 group.setAttribute(
"expirable", (
int)(iExpirable>>20) );
515 storage.appendChild(total);
516 int num_elements = fsXML.size();
517 for (
int fs_index = 0; fs_index < num_elements; fs_index++)
519 storage.appendChild(fsXML[fs_index]);
525 load.setAttribute(
"avg1", 0);
526 load.setAttribute(
"avg2", 1);
527 load.setAttribute(
"avg3", 2);
530 if (rgdAverages[0] != -1)
532 load.setAttribute(
"avg1", rgdAverages[0]);
533 load.setAttribute(
"avg2", rgdAverages[1]);
534 load.setAttribute(
"avg3", rgdAverages[2]);
540 QDateTime GuideDataThrough;
543 query.
prepare(
"SELECT MAX(endtime) FROM program WHERE manualid = 0;");
550 guide.setAttribute(
"start",
552 guide.setAttribute(
"end",
554 guide.setAttribute(
"status",
558 guide.setAttribute(
"next",
562 if (!GuideDataThrough.isNull())
564 guide.setAttribute(
"guideThru",
566 guide.setAttribute(
"guideDays", qdtNow.daysTo(GuideDataThrough));
572 if ((!info_script.isEmpty()) && (info_script !=
"none"))
574 QDomElement misc = pDoc->createElement(
"Miscellaneous");
575 root.appendChild(misc);
582 LOG(VB_GENERAL, LOG_ERR,
583 QString(
"Error running miscellaneous "
584 "status information script: %1").arg(info_script));
588 QByteArray input = ms.
ReadAll();
590 QStringList
output = QString(input).split(
'\n',
592 for (
const auto & line : std::as_const(
output))
594 QDomElement
info = pDoc->createElement(
"Information");
596 QStringList list = line.split(
"[]:[]");
597 unsigned int size = list.size();
598 unsigned int hasAttributes = 0;
600 if ((size > 0) && (!list[0].isEmpty()))
602 info.setAttribute(
"display", list[0]);
605 if ((size > 1) && (!list[1].isEmpty()))
607 info.setAttribute(
"name", list[1]);
610 if ((size > 2) && (!list[2].isEmpty()))
612 info.setAttribute(
"value", list[2]);
616 if (hasAttributes > 0)
617 misc.appendChild(
info);
628#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
629 os.setCodec(
"UTF-8");
631 os.setEncoding(QStringConverter::Utf8);
636 QDomElement docElem = pDoc->documentElement();
638 os <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
639 <<
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n"
640 <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\""
641 <<
" xml:lang=\"en\" lang=\"en\">\r\n"
643 <<
" <meta http-equiv=\"Content-Type\""
644 <<
"content=\"text/html; charset=UTF-8\" />\r\n"
645 <<
" <link rel=\"stylesheet\" href=\"/css/Status.css\" type=\"text/css\">\r\n"
646 <<
" <title>MythTV Status - "
650 << docElem.attribute(
"version", MYTH_BINARY_VERSION ) <<
"</title>\r\n"
652 <<
"<body bgcolor=\"#fff\">\r\n"
653 <<
"<div class=\"status\">\r\n"
654 <<
" <h1 class=\"status\">MythTV Status</h1>\r\n";
658 QDomNode node = docElem.namedItem(
"Encoders" );
665 node = docElem.namedItem(
"Scheduled" );
672 node = docElem.namedItem(
"Frontends" );
679 node = docElem.namedItem(
"Backends" );
686 node = docElem.namedItem(
"JobQueue" );
693 node = docElem.namedItem(
"MachineInfo" );
700 node = docElem.namedItem(
"Miscellaneous" );
705 os <<
"\r\n</div>\r\n</body>\r\n</html>\r\n";
715 int nNumEncoders = 0;
717 if (encoders.isNull())
720 os <<
" <div class=\"content\">\r\n"
721 <<
" <h2 class=\"status\">Encoder Status</h2>\r\n";
723 QDomNode node = encoders.firstChild();
725 while (!node.isNull())
727 QDomElement e = node.toElement();
731 if (e.tagName() ==
"Encoder")
733 QString sIsLocal = (e.attribute(
"local" ,
"remote" )==
"1")
734 ?
"local" :
"remote";
735 QString sCardId = e.attribute(
"id" ,
"0" );
736 QString sHostName = e.attribute(
"hostname" ,
"Unknown");
737 bool bConnected=
static_cast<bool>(e.attribute(
"connected",
"0" ).toInt());
739 bool bIsLowOnFreeSpace=
static_cast<bool>(e.attribute(
"lowOnFreeSpace",
"0").toInt());
741 QString sDevlabel = e.attribute(
"devlabel",
"[ UNKNOWN ]");
743 os <<
" Encoder " << sCardId <<
" " << sDevlabel
744 <<
" is " << sIsLocal <<
" on " << sHostName;
746 if ((sIsLocal ==
"remote") && !bConnected)
753 os <<
" (currently asleep).<br />";
755 os <<
" (currently not connected).<br />";
757 node = node.nextSibling();
768 os <<
" and is watching Live TV";
773 os <<
" and is recording";
777 os <<
" and is not recording.";
783 QDomNode tmpNode = e.namedItem(
"Program" );
785 if (!tmpNode.isNull())
787 QDomElement program = tmpNode.toElement();
789 if (!program.isNull())
791 os <<
" '" << program.attribute(
"title",
"Unknown" ) <<
"'";
795 tmpNode = program.namedItem(
"Channel" );
797 if (!tmpNode.isNull())
799 QDomElement channel = tmpNode.toElement();
801 if (!channel.isNull())
803 << channel.attribute(
"callSign",
"unknown" );
808 tmpNode = program.namedItem(
"Recording" );
810 if (!tmpNode.isNull())
812 QDomElement recording = tmpNode.toElement();
814 if (!recording.isNull())
817 recording.attribute(
"recEndTs",
"" ));
819 os <<
". This recording ";
825 os <<
"scheduled to end at "
835 if (bIsLowOnFreeSpace)
837 os <<
" <strong>WARNING</strong>:"
838 <<
" This backend is low on free disk space!";
845 node = node.nextSibling();
848 os <<
" </div>\r\n\r\n";
850 return( nNumEncoders );
861 if (scheduled.isNull())
864 int nNumRecordings= scheduled.attribute(
"count",
"0" ).toInt();
866 os <<
" <div class=\"content\">\r\n"
867 <<
" <h2 class=\"status\">Schedule</h2>\r\n";
869 if (nNumRecordings == 0)
871 os <<
" There are no shows scheduled for recording.\r\n"
876 os <<
" The next " << nNumRecordings <<
" show" << (nNumRecordings == 1 ?
"" :
"s" )
877 <<
" that " << (nNumRecordings == 1 ?
"is" :
"are")
878 <<
" scheduled for recording:\r\n";
880 os <<
" <div class=\"schedule\">\r\n";
884 QDomNode node = scheduled.firstChild();
886 while (!node.isNull())
888 QDomElement e = node.toElement();
892 QDomNode recNode = e.namedItem(
"Recording" );
893 QDomNode chanNode = e.namedItem(
"Channel" );
895 if ((e.tagName() ==
"Program") && !recNode.isNull() &&
898 QDomElement r = recNode.toElement();
899 QDomElement c = chanNode.toElement();
901 QString sTitle = e.attribute(
"title" ,
"" );
902 QString sSubTitle = e.attribute(
"subTitle",
"" );
908 int nPreRollSecs = r.attribute(
"preRollSeconds",
"0" ).toInt();
909 int nEncoderId = r.attribute(
"encoderId" ,
"0" ).toInt();
910 QString sProfile = r.attribute(
"recProfile" ,
"" );
911 QString sChanName = c.attribute(
"channelName" ,
"" );
914 QDomText text = e.firstChild().toText();
916 sDesc = text.nodeValue();
920 int nTotalSecs = qdtNow.secsTo( recStartTs ) - nPreRollSecs;
926 int nTotalDays = nTotalSecs / 86400;
927 int nTotalHours = (nTotalSecs / 3600)
929 int nTotalMins = (nTotalSecs / 60) % 60;
931 QString sTimeToStart =
"in";
933 sTimeToStart += QObject::tr(
" %n day(s),",
"", nTotalDays );
934 sTimeToStart += QObject::tr(
" %n hour(s) and",
"", nTotalHours);
935 sTimeToStart += QObject::tr(
" %n minute(s)",
"", nTotalMins);
937 if ( nTotalHours == 0 && nTotalMins == 0)
938 sTimeToStart = QObject::tr(
"within one minute",
"Recording starting");
941 sTimeToStart = QObject::tr(
"soon",
"Recording starting");
945 os <<
" <a href=\"#\">";
953 os <<
"Encoder " << nEncoderId <<
" - ";
955 os << sChanName <<
" - " << sTitle <<
"<br />"
956 <<
"<span><strong>" << sTitle <<
"</strong> ("
960 if ( !sSubTitle.isEmpty())
961 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
963 if ( airDate.isValid())
965 os <<
"Orig. Airdate: "
971 os << sDesc <<
"<br /><br />"
972 <<
"This recording will start " << sTimeToStart
973 <<
" using encoder " << nEncoderId <<
" with the '"
974 << sProfile <<
"' profile.</span></a><hr />\r\n";
978 node = node.nextSibling();
981 os <<
" </div>\r\n\r\n";
983 return( nNumRecordings );
992 if (frontends.isNull())
995 int nNumFES= frontends.attribute(
"count",
"0" ).toInt();
1001 os <<
" <div class=\"content\">\r\n"
1002 <<
" <h2 class=\"status\">Frontends</h2>\r\n";
1004 QDomNode node = frontends.firstChild();
1005 while (!node.isNull())
1007 QDomElement e = node.toElement();
1011 QString name = e.attribute(
"name" ,
"" );
1012 QString url = e.attribute(
"url" ,
"" );
1013 os << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1016 node = node.nextSibling();
1019 os <<
" </div>\r\n\r\n";
1030 if (backends.isNull())
1033 int nNumBES= backends.attribute(
"count",
"0" ).toInt();
1039 os <<
" <div class=\"content\">\r\n"
1040 <<
" <h2 class=\"status\">Other Backends</h2>\r\n";
1042 QDomNode node = backends.firstChild();
1043 while (!node.isNull())
1045 QDomElement e = node.toElement();
1049 QString
type = e.attribute(
"type",
"" );
1050 QString name = e.attribute(
"name" ,
"" );
1051 QString url = e.attribute(
"url" ,
"" );
1052 os <<
type <<
": " << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1055 node = node.nextSibling();
1058 os <<
" </div>\r\n\r\n";
1072 int nNumJobs= jobs.attribute(
"count",
"0" ).toInt();
1074 os <<
" <div class=\"content\">\r\n"
1075 <<
" <h2 class=\"status\">Job Queue</h2>\r\n";
1079 QString statusColor;
1082 os <<
" Jobs currently in Queue or recently ended:\r\n<br />"
1083 <<
" <div class=\"schedule\">\r\n";
1086 QDomNode node = jobs.firstChild();
1088 while (!node.isNull())
1090 QDomElement e = node.toElement();
1094 QDomNode progNode = e.namedItem(
"Program" );
1096 if ((e.tagName() ==
"Job") && !progNode.isNull() )
1098 QDomElement
p = progNode.toElement();
1100 QDomNode recNode =
p.namedItem(
"Recording" );
1101 QDomNode chanNode =
p.namedItem(
"Channel" );
1103 QDomElement r = recNode.toElement();
1104 QDomElement c = chanNode.toElement();
1106 int nType = e.attribute(
"type" ,
"0" ).toInt();
1107 int nStatus = e.attribute(
"status",
"0" ).toInt();
1112 statusColor =
" class=\"jobaborted\"";
1117 statusColor =
" class=\"joberrored\"";
1118 jobColor =
" class=\"joberrored\"";
1122 statusColor =
" class=\"jobfinished\"";
1123 jobColor =
" class=\"jobfinished\"";
1127 statusColor =
" class=\"jobrunning\"";
1128 jobColor =
" class=\"jobrunning\"";
1132 statusColor =
" class=\"jobqueued\"";
1133 jobColor =
" class=\"jobqueued\"";
1137 QString sTitle =
p.attribute(
"title" ,
"" );
1138 QString sSubTitle =
p.attribute(
"subTitle",
"" );
1144 QString sHostname = e.attribute(
"hostname",
"master" );
1145 QString sComment =
"";
1147 QDomText text = e.firstChild().toText();
1149 sComment = text.nodeValue();
1151 os <<
"<a href=\"javascript:void(0)\">"
1155 << sTitle <<
" - <font" << jobColor <<
">"
1157 <<
"<span><strong>" << sTitle <<
"</strong> ("
1161 if (!sSubTitle.isEmpty())
1162 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
1168 os <<
"Scheduled Run Time: "
1175 os <<
"Status: <font" << statusColor <<
">"
1183 if ( nStatus != JOB_QUEUED)
1184 os <<
"Host: " << sHostname <<
"<br />";
1186 if (!sComment.isEmpty())
1187 os <<
"<br />Comments:<br />" << sComment <<
"<br />";
1189 os <<
"</span></a><hr />\r\n";
1193 node = node.nextSibling();
1195 os <<
" </div>\r\n";
1199 os <<
" Job Queue is currently empty.\r\n\r\n";
1202 os <<
" </div>\r\n\r\n ";
1219 os <<
"<div class=\"content\">\r\n"
1220 <<
" <h2 class=\"status\">Machine Information</h2>\r\n";
1224 QDomNode node =
info.namedItem(
"Load" );
1228 QDomElement e = node.toElement();
1232 double dAvg1 = e.attribute(
"avg1" ,
"0" ).toDouble();
1233 double dAvg2 = e.attribute(
"avg2" ,
"0" ).toDouble();
1234 double dAvg3 = e.attribute(
"avg3" ,
"0" ).toDouble();
1236 os <<
" <div class=\"loadstatus\">\r\n"
1237 <<
" This machine's load average:"
1238 <<
"\r\n <ul>\r\n <li>"
1239 <<
"1 Minute: " << dAvg1 <<
"</li>\r\n"
1240 <<
" <li>5 Minutes: " << dAvg2 <<
"</li>\r\n"
1241 <<
" <li>15 Minutes: " << dAvg3
1242 <<
"</li>\r\n </ul>\r\n"
1248 node =
info.namedItem(
"Storage" );
1249 QDomElement storage = node.toElement();
1250 node = storage.firstChild();
1255 while (!node.isNull())
1257 QDomElement g = node.toElement();
1259 if (!g.isNull() && g.tagName() ==
"Group")
1261 QString
id = g.attribute(
"id",
"" );
1265 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1266 int nTotal = g.attribute(
"total",
"0" ).toInt();
1267 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1268 int nLiveTV = g.attribute(
"livetv" ,
"0" ).toInt();
1269 int nDeleted = g.attribute(
"deleted",
"0" ).toInt();
1270 int nExpirable = g.attribute(
"expirable" ,
"0" ).toInt();
1271 QString nDir = g.attribute(
"dir" ,
"" );
1273 nDir.replace(
",",
", ");
1275 os <<
" Disk Usage Summary:<br />\r\n";
1278 os <<
" <li>Total Disk Space:\r\n"
1281 os <<
" <li>Total Space: ";
1282 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1283 os << sRep <<
"</li>\r\n";
1285 os <<
" <li>Space Used: ";
1286 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1287 os << sRep <<
"</li>\r\n";
1289 os <<
" <li>Space Free: ";
1290 sRep = QString(
"%L1").arg(nFree) +
" MB";
1291 os << sRep <<
"</li>\r\n";
1293 if ((nLiveTV + nDeleted + nExpirable) > 0)
1295 os <<
" <li>Space Available "
1296 "After Auto-expire: ";
1297 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1298 sRep = QString(
"%L1").arg(nFree + nLiveTV +
1299 nDeleted + nExpirable) +
" MB";
1300 os << sRep <<
"\r\n";
1302 os <<
" <li>Space Used by LiveTV: ";
1303 sRep = QString(
"%L1").arg(nLiveTV) +
" MB";
1304 os << sRep <<
"</li>\r\n";
1305 os <<
" <li>Space Used by "
1306 "Deleted Recordings: ";
1307 sRep = QString(
"%L1").arg(nDeleted) +
" MB";
1308 os << sRep <<
"</li>\r\n";
1309 os <<
" <li>Space Used by "
1310 "Auto-expirable Recordings: ";
1311 sRep = QString(
"%L1").arg(nExpirable) +
" MB";
1312 os << sRep <<
"</li>\r\n";
1325 node = node.nextSibling();
1329 node = storage.firstChild();
1331 os <<
" Disk Usage Details:<br />\r\n";
1335 while (!node.isNull())
1337 QDomElement g = node.toElement();
1339 if (!g.isNull() && g.tagName() ==
"Group")
1341 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1342 int nTotal = g.attribute(
"total",
"0" ).toInt();
1343 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1344 QString nDir = g.attribute(
"dir" ,
"" );
1345 QString
id = g.attribute(
"id" ,
"" );
1347 nDir.replace(
",",
", ");
1353 os <<
" <li>MythTV Drive #" <<
id <<
":"
1357 if (nDir.contains(
','))
1358 os <<
" <li>Directories: ";
1360 os <<
" <li>Directory: ";
1362 os << nDir <<
"</li>\r\n";
1364 os <<
" <li>Total Space: ";
1365 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1366 os << sRep <<
"</li>\r\n";
1368 os <<
" <li>Space Used: ";
1369 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1370 os << sRep <<
"</li>\r\n";
1372 os <<
" <li>Space Free: ";
1373 sRep = QString(
"%L1").arg(nFree) +
" MB";
1374 os << sRep <<
"</li>\r\n";
1382 node = node.nextSibling();
1389 node =
info.namedItem(
"Guide" );
1393 QDomElement e = node.toElement();
1397 int nDays = e.attribute(
"guideDays",
"0" ).toInt();
1398 QString sStart = e.attribute(
"start" ,
"" );
1399 QString sEnd = e.attribute(
"end" ,
"" );
1400 QString sStatus = e.attribute(
"status" ,
"" );
1402 QString sNext = next.isNull() ?
"" :
1408 QDomText text = e.firstChild().toText();
1415 sMsg = text.nodeValue();
1417 os <<
" Last mythfilldatabase run started on " << sStart
1423 os <<
"ended on " << sEnd <<
". ";
1425 os << sStatus <<
"<br />\r\n";
1427 if (!next.isNull() && next >= lastrunstart)
1429 os <<
" Suggested next mythfilldatabase run: "
1430 << sNext <<
".<br />\r\n";
1435 os <<
" There's guide data until "
1439 os <<
" " << QObject::tr(
"(%n day(s))",
"", nDays);
1444 os <<
" <strong>WARNING</strong>: is mythfilldatabase running?";
1448 os <<
" There's <strong>no guide data</strong> available! "
1449 <<
"Have you run mythfilldatabase?";
1453 os <<
"\r\n </div>\r\n";
1465 QDomNodeList nodes =
info.elementsByTagName(
"Information");
1466 uint count = nodes.count();
1472 os <<
"<div class=\"content\">\r\n"
1473 <<
" <h2 class=\"status\">Miscellaneous</h2>\r\n";
1474 for (
unsigned int i = 0; i < count; i++)
1476 QDomNode node = nodes.item(i);
1480 QDomElement e = node.toElement();
1484 display = e.attribute(
"display",
"");
1488 if (display.isEmpty())
1493 if (display.contains(
"<p>", Qt::CaseInsensitive) ||
1494 display.contains(
"<br", Qt::CaseInsensitive))
1501 linebreak =
"<br />\r\n";
1504 os <<
" " << display << linebreak;
1518 if ((pDoc ==
nullptr) || (pInfo ==
nullptr))
1523 QDomElement program = pDoc->createElement(
"Program" );
1524 node.appendChild( program );
1526 program.setAttribute(
"startTime" ,
1529 program.setAttribute(
"title" , pInfo->
GetTitle() );
1530 program.setAttribute(
"subTitle" , pInfo->
GetSubtitle());
1531 program.setAttribute(
"category" , pInfo->
GetCategory());
1533 program.setAttribute(
"repeat" ,
static_cast<int>(pInfo->
IsRepeat()));
1538 program.setAttribute(
"seriesId" , pInfo->
GetSeriesID() );
1539 program.setAttribute(
"programId" , pInfo->
GetProgramID() );
1540 program.setAttribute(
"stars" , pInfo->
GetStars() );
1541 program.setAttribute(
"fileSize" ,
1543 program.setAttribute(
"lastModified",
1546 program.setAttribute(
"hostname" , pInfo->
GetHostname() );
1549 program.setAttribute(
1552 QDomText textNode = pDoc->createTextNode( pInfo->
GetDescription() );
1553 program.appendChild( textNode );
1561 QDomElement channel = pDoc->createElement(
"Channel" );
1562 program.appendChild( channel );
1571 QDomElement recording = pDoc->createElement(
"Recording" );
1572 program.appendChild( recording );
1574 recording.setAttribute(
"recStatus" ,
1576 recording.setAttribute(
"recPriority" ,
1578 recording.setAttribute(
"recStartTs" ,
1580 recording.setAttribute(
"recEndTs" ,
1585 recording.setAttribute(
"recordId" ,
1587 recording.setAttribute(
"recGroup" ,
1589 recording.setAttribute(
"playGroup" ,
1591 recording.setAttribute(
"recType" ,
1593 recording.setAttribute(
"dupInType" ,
1595 recording.setAttribute(
"dupMethod" ,
1597 recording.setAttribute(
"encoderId" ,
1600 recording.setAttribute(
"recProfile" ,
1627 channel.setAttribute(
"chanId" , pInfo->
GetChanID() );
1628 channel.setAttribute(
"chanNum" , pInfo->
GetChanNum());
1635 channel.setAttribute(
"chanFilters",
1637 channel.setAttribute(
"sourceId" , pInfo->
GetSourceID() );
1638 channel.setAttribute(
"inputId" , pInfo->
GetInputID() );
1639 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 SSDPCacheEntries * Find(const QString &sURI)
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,...