21#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
22#include <QStringConverter>
35#include "libmythbase/mythversion.h"
59 m_bIsMaster(bIsMaster)
84 return QStringList(
"/Status" );
120 LOG(VB_GENERAL, LOG_ERR,
121 "HttpStatus::ProcessRequest() - Unexpected Exception");
133 QDomDocument doc(
"Status" );
136 QDomProcessingInstruction encoding =
137 doc.createProcessingInstruction(
"xml",
138 R
"(version="1.0" encoding="UTF-8")");
139 doc.appendChild(encoding);
144 pRequest->m_mapRespHeaders[ "Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
147#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
148 stream.setCodec(
"UTF-8");
150 stream.setEncoding(QStringConverter::Utf8);
152 stream << doc.toString();
162 pRequest->
m_mapRespHeaders[
"Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
164 QDomDocument doc(
"Status" );
185 QDomElement root = pDoc->createElement(
"Status");
186 pDoc->appendChild(root);
190 root.setAttribute(
"time" ,
192 root.setAttribute(
"ISODate" , qdtNow.toString(
Qt::ISODate) );
193 root.setAttribute(
"version" , MYTH_BINARY_VERSION );
194 root.setAttribute(
"protoVer", MYTH_PROTO_VERSION );
198 QDomElement encoders = pDoc->createElement(
"Encoders");
199 root.appendChild(encoders);
208 if (elink !=
nullptr)
210 TVState state = elink->GetState();
211 isLocal = elink->IsLocal();
213 QDomElement encoder = pDoc->createElement(
"Encoder");
214 encoders.appendChild(encoder);
216 encoder.setAttribute(
"id" , elink->GetInputID() );
217 encoder.setAttribute(
"local" ,
static_cast<int>(isLocal));
218 encoder.setAttribute(
"connected" ,
static_cast<int>(elink->IsConnected()));
219 encoder.setAttribute(
"state" , state );
220 encoder.setAttribute(
"sleepstatus" , elink->GetSleepStatus() );
226 encoder.setAttribute(
"hostname", elink->GetHostName());
228 encoder.setAttribute(
"devlabel",
231 if (elink->IsConnected())
259 encoders.setAttribute(
"count", numencoders);
263 QDomElement scheduled = pDoc->createElement(
"Scheduled");
264 root.appendChild(scheduled);
271 unsigned int iNum = 10;
272 unsigned int iNumRecordings = 0;
274 auto itProg = recordingList.begin();
275 for (; (itProg != recordingList.end()) && iNumRecordings < iNum; ++itProg)
278 ((*itProg)->GetRecordingStartTime() >=
286 while (!recordingList.empty())
290 recordingList.pop_back();
293 scheduled.setAttribute(
"count", iNumRecordings);
297 QDomElement frontends = pDoc->createElement(
"Frontends");
298 root.appendChild(frontends);
301 "urn:schemas-mythtv-org:service:MythFrontend:1");
309 frontends.setAttribute(
"count", map.size() );
310 for (
const auto & entry : std::as_const(map))
312 QDomElement fe = pDoc->createElement(
"Frontend");
313 frontends.appendChild(fe);
314 QUrl url(entry->m_sLocation);
315 fe.setAttribute(
"name", url.host());
316 fe.setAttribute(
"url", url.toString(QUrl::RemovePath));
323 QDomElement backends = pDoc->createElement(
"Backends");
324 root.appendChild(backends);
334 QDomElement mbe = pDoc->createElement(
"Backend");
335 backends.appendChild(mbe);
336 mbe.setAttribute(
"type",
"Master");
337 mbe.setAttribute(
"name", masterhost);
338 mbe.setAttribute(
"url" , masterip +
":" + QString::number(masterport));
342 "urn:schemas-mythtv-org:device:SlaveMediaServer:1");
346 QString ipaddress = QString();
355 for (
const auto & entry : std::as_const(map))
357 QUrl url(entry->m_sLocation);
358 if (url.host() != ipaddress)
361 QDomElement mbe = pDoc->createElement(
"Backend");
362 backends.appendChild(mbe);
363 mbe.setAttribute(
"type",
"Slave");
364 mbe.setAttribute(
"name", url.host());
365 mbe.setAttribute(
"url" , url.toString(QUrl::RemovePath));
371 backends.setAttribute(
"count", numbes);
375 QDomElement
jobqueue = pDoc->createElement(
"JobQueue");
378 QMap<int, JobQueueEntry> jobs;
379 QMap<int, JobQueueEntry>::Iterator it;
385 for (it = jobs.begin(); it != jobs.end(); ++it)
387 ProgramInfo pginfo((*it).chanid, (*it).recstartts);
391 QDomElement job = pDoc->createElement(
"Job");
394 job.setAttribute(
"id" , (*it).id );
395 job.setAttribute(
"chanId" , (*it).chanid );
396 job.setAttribute(
"startTime" ,
398 job.setAttribute(
"startTs" , (*it).startts );
399 job.setAttribute(
"insertTime",
401 job.setAttribute(
"type" , (*it).type );
402 job.setAttribute(
"cmds" , (*it).cmds );
403 job.setAttribute(
"flags" , (*it).flags );
404 job.setAttribute(
"status" , (*it).status );
405 job.setAttribute(
"statusTime",
407 job.setAttribute(
"schedTime" ,
409 job.setAttribute(
"args" , (*it).args );
411 if ((*it).hostname.isEmpty())
412 job.setAttribute(
"hostname", QObject::tr(
"master"));
414 job.setAttribute(
"hostname",(*it).hostname);
416 QDomText textNode = pDoc->createTextNode((*it).comment);
417 job.appendChild(textNode);
422 jobqueue.setAttribute(
"count", jobs.size() );
426 QDomElement mInfo = pDoc->createElement(
"MachineInfo");
427 QDomElement storage = pDoc->createElement(
"Storage" );
428 QDomElement load = pDoc->createElement(
"Load" );
429 QDomElement guide = pDoc->createElement(
"Guide" );
431 root.appendChild (mInfo );
432 mInfo.appendChild(storage);
433 mInfo.appendChild(load );
434 mInfo.appendChild(guide );
451 QList<QDomElement> fsXML;
452 QStringList::const_iterator sit = strlist.cbegin();
453 while (sit != strlist.cend())
456 directory = *(sit++);
457 isLocalstr = *(sit++);
461 long long iTotal = (*(sit++)).toLongLong();
462 long long iUsed = (*(sit++)).toLongLong();;
463 long long iAvail = iTotal - iUsed;
468 QDomElement group = pDoc->createElement(
"Group");
470 group.setAttribute(
"id" , fsID );
471 group.setAttribute(
"total", (
int)(iTotal>>10) );
472 group.setAttribute(
"used" , (
int)(iUsed>>10) );
473 group.setAttribute(
"free" , (
int)(iAvail>>10) );
474 group.setAttribute(
"dir" , directory );
478 long long iLiveTV = -1;
479 long long iDeleted = -1;
480 long long iExpirable = -1;
482 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
483 " WHERE recgroup = :RECGROUP;");
488 iLiveTV = query.
value(0).toLongLong();
493 iDeleted = query.
value(0).toLongLong();
495 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
496 " WHERE autoexpire = 1 "
497 " AND recgroup NOT IN ('LiveTV', 'Deleted');");
500 iExpirable = query.
value(0).toLongLong();
502 group.setAttribute(
"livetv", (
int)(iLiveTV>>20) );
503 group.setAttribute(
"deleted", (
int)(iDeleted>>20) );
504 group.setAttribute(
"expirable", (
int)(iExpirable>>20) );
513 storage.appendChild(total);
514 int num_elements = fsXML.size();
515 for (
int fs_index = 0; fs_index < num_elements; fs_index++)
517 storage.appendChild(fsXML[fs_index]);
523 load.setAttribute(
"avg1", 0);
524 load.setAttribute(
"avg2", 1);
525 load.setAttribute(
"avg3", 2);
528 if (rgdAverages[0] != -1)
530 load.setAttribute(
"avg1", rgdAverages[0]);
531 load.setAttribute(
"avg2", rgdAverages[1]);
532 load.setAttribute(
"avg3", rgdAverages[2]);
538 QDateTime GuideDataThrough;
541 query.
prepare(
"SELECT MAX(endtime) FROM program WHERE manualid = 0;");
548 guide.setAttribute(
"start",
550 guide.setAttribute(
"end",
552 guide.setAttribute(
"status",
556 guide.setAttribute(
"next",
560 if (!GuideDataThrough.isNull())
562 guide.setAttribute(
"guideThru",
564 guide.setAttribute(
"guideDays", qdtNow.daysTo(GuideDataThrough));
570 if ((!info_script.isEmpty()) && (info_script !=
"none"))
572 QDomElement misc = pDoc->createElement(
"Miscellaneous");
573 root.appendChild(misc);
580 LOG(VB_GENERAL, LOG_ERR,
581 QString(
"Error running miscellaneous "
582 "status information script: %1").arg(info_script));
586 QByteArray input = ms.
ReadAll();
588 QStringList
output = QString(input).split(
'\n',
590 for (
const auto & line : std::as_const(
output))
592 QDomElement
info = pDoc->createElement(
"Information");
594 QStringList list = line.split(
"[]:[]");
595 unsigned int size = list.size();
596 unsigned int hasAttributes = 0;
598 if ((size > 0) && (!list[0].isEmpty()))
600 info.setAttribute(
"display", list[0]);
603 if ((size > 1) && (!list[1].isEmpty()))
605 info.setAttribute(
"name", list[1]);
608 if ((size > 2) && (!list[2].isEmpty()))
610 info.setAttribute(
"value", list[2]);
614 if (hasAttributes > 0)
615 misc.appendChild(
info);
626#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
627 os.setCodec(
"UTF-8");
629 os.setEncoding(QStringConverter::Utf8);
634 QDomElement docElem = pDoc->documentElement();
636 os <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
637 <<
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n"
638 <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\""
639 <<
" xml:lang=\"en\" lang=\"en\">\r\n"
641 <<
" <meta http-equiv=\"Content-Type\""
642 <<
"content=\"text/html; charset=UTF-8\" />\r\n"
643 <<
" <link rel=\"stylesheet\" href=\"/css/Status.css\" type=\"text/css\">\r\n"
644 <<
" <title>MythTV Status - "
648 << docElem.attribute(
"version", MYTH_BINARY_VERSION ) <<
"</title>\r\n"
650 <<
"<body bgcolor=\"#fff\">\r\n"
651 <<
"<div class=\"status\">\r\n"
652 <<
" <h1 class=\"status\">MythTV Status</h1>\r\n";
656 QDomNode node = docElem.namedItem(
"Encoders" );
663 node = docElem.namedItem(
"Scheduled" );
670 node = docElem.namedItem(
"Frontends" );
677 node = docElem.namedItem(
"Backends" );
684 node = docElem.namedItem(
"JobQueue" );
691 node = docElem.namedItem(
"MachineInfo" );
698 node = docElem.namedItem(
"Miscellaneous" );
703 os <<
"\r\n</div>\r\n</body>\r\n</html>\r\n";
713 int nNumEncoders = 0;
715 if (encoders.isNull())
718 os <<
" <div class=\"content\">\r\n"
719 <<
" <h2 class=\"status\">Encoder Status</h2>\r\n";
721 QDomNode node = encoders.firstChild();
723 while (!node.isNull())
725 QDomElement e = node.toElement();
729 if (e.tagName() ==
"Encoder")
731 QString sIsLocal = (e.attribute(
"local" ,
"remote" )==
"1")
732 ?
"local" :
"remote";
733 QString sCardId = e.attribute(
"id" ,
"0" );
734 QString sHostName = e.attribute(
"hostname" ,
"Unknown");
735 bool bConnected=
static_cast<bool>(e.attribute(
"connected",
"0" ).toInt());
737 bool bIsLowOnFreeSpace=
static_cast<bool>(e.attribute(
"lowOnFreeSpace",
"0").toInt());
739 QString sDevlabel = e.attribute(
"devlabel",
"[ UNKNOWN ]");
741 os <<
" Encoder " << sCardId <<
" " << sDevlabel
742 <<
" is " << sIsLocal <<
" on " << sHostName;
744 if ((sIsLocal ==
"remote") && !bConnected)
751 os <<
" (currently asleep).<br />";
753 os <<
" (currently not connected).<br />";
755 node = node.nextSibling();
766 os <<
" and is watching Live TV";
771 os <<
" and is recording";
775 os <<
" and is not recording.";
781 QDomNode tmpNode = e.namedItem(
"Program" );
783 if (!tmpNode.isNull())
785 QDomElement program = tmpNode.toElement();
787 if (!program.isNull())
789 os <<
" '" << program.attribute(
"title",
"Unknown" ) <<
"'";
793 tmpNode = program.namedItem(
"Channel" );
795 if (!tmpNode.isNull())
797 QDomElement channel = tmpNode.toElement();
799 if (!channel.isNull())
801 << channel.attribute(
"callSign",
"unknown" );
806 tmpNode = program.namedItem(
"Recording" );
808 if (!tmpNode.isNull())
810 QDomElement recording = tmpNode.toElement();
812 if (!recording.isNull())
815 recording.attribute(
"recEndTs",
"" ));
817 os <<
". This recording ";
823 os <<
"scheduled to end at "
833 if (bIsLowOnFreeSpace)
835 os <<
" <strong>WARNING</strong>:"
836 <<
" This backend is low on free disk space!";
843 node = node.nextSibling();
846 os <<
" </div>\r\n\r\n";
859 if (scheduled.isNull())
862 int nNumRecordings= scheduled.attribute(
"count",
"0" ).toInt();
864 os <<
" <div class=\"content\">\r\n"
865 <<
" <h2 class=\"status\">Schedule</h2>\r\n";
867 if (nNumRecordings == 0)
869 os <<
" There are no shows scheduled for recording.\r\n"
874 os <<
" The next " << nNumRecordings <<
" show" << (nNumRecordings == 1 ?
"" :
"s" )
875 <<
" that " << (nNumRecordings == 1 ?
"is" :
"are")
876 <<
" scheduled for recording:\r\n";
878 os <<
" <div class=\"schedule\">\r\n";
882 QDomNode node = scheduled.firstChild();
884 while (!node.isNull())
886 QDomElement e = node.toElement();
890 QDomNode recNode = e.namedItem(
"Recording" );
891 QDomNode chanNode = e.namedItem(
"Channel" );
893 if ((e.tagName() ==
"Program") && !recNode.isNull() &&
896 QDomElement r = recNode.toElement();
897 QDomElement c = chanNode.toElement();
899 QString sTitle = e.attribute(
"title" ,
"" );
900 QString sSubTitle = e.attribute(
"subTitle",
"" );
906 int nPreRollSecs = r.attribute(
"preRollSeconds",
"0" ).toInt();
907 int nEncoderId = r.attribute(
"encoderId" ,
"0" ).toInt();
908 QString sProfile = r.attribute(
"recProfile" ,
"" );
909 QString sChanName = c.attribute(
"channelName" ,
"" );
912 QDomText text = e.firstChild().toText();
914 sDesc = text.nodeValue();
918 int nTotalSecs = qdtNow.secsTo( recStartTs ) - nPreRollSecs;
924 int nTotalDays = nTotalSecs / 86400;
925 int nTotalHours = (nTotalSecs / 3600)
927 int nTotalMins = (nTotalSecs / 60) % 60;
929 QString sTimeToStart =
"in";
931 sTimeToStart += QObject::tr(
" %n day(s),",
"", nTotalDays );
932 sTimeToStart += QObject::tr(
" %n hour(s) and",
"", nTotalHours);
933 sTimeToStart += QObject::tr(
" %n minute(s)",
"", nTotalMins);
935 if ( nTotalHours == 0 && nTotalMins == 0)
936 sTimeToStart = QObject::tr(
"within one minute",
"Recording starting");
939 sTimeToStart = QObject::tr(
"soon",
"Recording starting");
943 os <<
" <a href=\"#\">";
951 os <<
"Encoder " << nEncoderId <<
" - ";
953 os << sChanName <<
" - " << sTitle <<
"<br />"
954 <<
"<span><strong>" << sTitle <<
"</strong> ("
958 if ( !sSubTitle.isEmpty())
959 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
961 if ( airDate.isValid())
963 os <<
"Orig. Airdate: "
969 os << sDesc <<
"<br /><br />"
970 <<
"This recording will start " << sTimeToStart
971 <<
" using encoder " << nEncoderId <<
" with the '"
972 << sProfile <<
"' profile.</span></a><hr />\r\n";
976 node = node.nextSibling();
979 os <<
" </div>\r\n\r\n";
981 return nNumRecordings;
990 if (frontends.isNull())
993 int nNumFES= frontends.attribute(
"count",
"0" ).toInt();
999 os <<
" <div class=\"content\">\r\n"
1000 <<
" <h2 class=\"status\">Frontends</h2>\r\n";
1002 QDomNode node = frontends.firstChild();
1003 while (!node.isNull())
1005 QDomElement e = node.toElement();
1009 QString name = e.attribute(
"name" ,
"" );
1010 QString url = e.attribute(
"url" ,
"" );
1011 os << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1014 node = node.nextSibling();
1017 os <<
" </div>\r\n\r\n";
1028 if (backends.isNull())
1031 int nNumBES= backends.attribute(
"count",
"0" ).toInt();
1037 os <<
" <div class=\"content\">\r\n"
1038 <<
" <h2 class=\"status\">Other Backends</h2>\r\n";
1040 QDomNode node = backends.firstChild();
1041 while (!node.isNull())
1043 QDomElement e = node.toElement();
1047 QString
type = e.attribute(
"type",
"" );
1048 QString name = e.attribute(
"name" ,
"" );
1049 QString url = e.attribute(
"url" ,
"" );
1050 os <<
type <<
": " << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1053 node = node.nextSibling();
1056 os <<
" </div>\r\n\r\n";
1070 int nNumJobs= jobs.attribute(
"count",
"0" ).toInt();
1072 os <<
" <div class=\"content\">\r\n"
1073 <<
" <h2 class=\"status\">Job Queue</h2>\r\n";
1077 QString statusColor;
1080 os <<
" Jobs currently in Queue or recently ended:\r\n<br />"
1081 <<
" <div class=\"schedule\">\r\n";
1084 QDomNode node = jobs.firstChild();
1086 while (!node.isNull())
1088 QDomElement e = node.toElement();
1092 QDomNode progNode = e.namedItem(
"Program" );
1094 if ((e.tagName() ==
"Job") && !progNode.isNull() )
1096 QDomElement
p = progNode.toElement();
1098 QDomNode recNode =
p.namedItem(
"Recording" );
1099 QDomNode chanNode =
p.namedItem(
"Channel" );
1101 QDomElement r = recNode.toElement();
1102 QDomElement c = chanNode.toElement();
1104 int nType = e.attribute(
"type" ,
"0" ).toInt();
1105 int nStatus = e.attribute(
"status",
"0" ).toInt();
1110 statusColor =
" class=\"jobaborted\"";
1115 statusColor =
" class=\"joberrored\"";
1116 jobColor =
" class=\"joberrored\"";
1120 statusColor =
" class=\"jobfinished\"";
1121 jobColor =
" class=\"jobfinished\"";
1125 statusColor =
" class=\"jobrunning\"";
1126 jobColor =
" class=\"jobrunning\"";
1130 statusColor =
" class=\"jobqueued\"";
1131 jobColor =
" class=\"jobqueued\"";
1135 QString sTitle =
p.attribute(
"title" ,
"" );
1136 QString sSubTitle =
p.attribute(
"subTitle",
"" );
1142 QString sHostname = e.attribute(
"hostname",
"master" );
1143 QString sComment =
"";
1145 QDomText text = e.firstChild().toText();
1147 sComment = text.nodeValue();
1149 os <<
"<a href=\"javascript:void(0)\">"
1153 << sTitle <<
" - <font" << jobColor <<
">"
1155 <<
"<span><strong>" << sTitle <<
"</strong> ("
1159 if (!sSubTitle.isEmpty())
1160 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
1166 os <<
"Scheduled Run Time: "
1173 os <<
"Status: <font" << statusColor <<
">"
1181 if ( nStatus != JOB_QUEUED)
1182 os <<
"Host: " << sHostname <<
"<br />";
1184 if (!sComment.isEmpty())
1185 os <<
"<br />Comments:<br />" << sComment <<
"<br />";
1187 os <<
"</span></a><hr />\r\n";
1191 node = node.nextSibling();
1193 os <<
" </div>\r\n";
1197 os <<
" Job Queue is currently empty.\r\n\r\n";
1200 os <<
" </div>\r\n\r\n ";
1217 os <<
"<div class=\"content\">\r\n"
1218 <<
" <h2 class=\"status\">Machine Information</h2>\r\n";
1222 QDomNode node =
info.namedItem(
"Load" );
1226 QDomElement e = node.toElement();
1230 double dAvg1 = e.attribute(
"avg1" ,
"0" ).toDouble();
1231 double dAvg2 = e.attribute(
"avg2" ,
"0" ).toDouble();
1232 double dAvg3 = e.attribute(
"avg3" ,
"0" ).toDouble();
1234 os <<
" <div class=\"loadstatus\">\r\n"
1235 <<
" This machine's load average:"
1236 <<
"\r\n <ul>\r\n <li>"
1237 <<
"1 Minute: " << dAvg1 <<
"</li>\r\n"
1238 <<
" <li>5 Minutes: " << dAvg2 <<
"</li>\r\n"
1239 <<
" <li>15 Minutes: " << dAvg3
1240 <<
"</li>\r\n </ul>\r\n"
1246 node =
info.namedItem(
"Storage" );
1247 QDomElement storage = node.toElement();
1248 node = storage.firstChild();
1253 while (!node.isNull())
1255 QDomElement g = node.toElement();
1257 if (!g.isNull() && g.tagName() ==
"Group")
1259 QString
id = g.attribute(
"id",
"" );
1263 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1264 int nTotal = g.attribute(
"total",
"0" ).toInt();
1265 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1266 int nLiveTV = g.attribute(
"livetv" ,
"0" ).toInt();
1267 int nDeleted = g.attribute(
"deleted",
"0" ).toInt();
1268 int nExpirable = g.attribute(
"expirable" ,
"0" ).toInt();
1269 QString nDir = g.attribute(
"dir" ,
"" );
1271 nDir.replace(
",",
", ");
1273 os <<
" Disk Usage Summary:<br />\r\n";
1276 os <<
" <li>Total Disk Space:\r\n"
1279 os <<
" <li>Total Space: ";
1280 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1281 os << sRep <<
"</li>\r\n";
1283 os <<
" <li>Space Used: ";
1284 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1285 os << sRep <<
"</li>\r\n";
1287 os <<
" <li>Space Free: ";
1288 sRep = QString(
"%L1").arg(nFree) +
" MB";
1289 os << sRep <<
"</li>\r\n";
1291 if ((nLiveTV + nDeleted + nExpirable) > 0)
1293 os <<
" <li>Space Available "
1294 "After Auto-expire: ";
1295 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1296 sRep = QString(
"%L1").arg(nFree + nLiveTV +
1297 nDeleted + nExpirable) +
" MB";
1298 os << sRep <<
"\r\n";
1300 os <<
" <li>Space Used by LiveTV: ";
1301 sRep = QString(
"%L1").arg(nLiveTV) +
" MB";
1302 os << sRep <<
"</li>\r\n";
1303 os <<
" <li>Space Used by "
1304 "Deleted Recordings: ";
1305 sRep = QString(
"%L1").arg(nDeleted) +
" MB";
1306 os << sRep <<
"</li>\r\n";
1307 os <<
" <li>Space Used by "
1308 "Auto-expirable Recordings: ";
1309 sRep = QString(
"%L1").arg(nExpirable) +
" MB";
1310 os << sRep <<
"</li>\r\n";
1323 node = node.nextSibling();
1327 node = storage.firstChild();
1329 os <<
" Disk Usage Details:<br />\r\n";
1333 while (!node.isNull())
1335 QDomElement g = node.toElement();
1337 if (!g.isNull() && g.tagName() ==
"Group")
1339 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1340 int nTotal = g.attribute(
"total",
"0" ).toInt();
1341 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1342 QString nDir = g.attribute(
"dir" ,
"" );
1343 QString
id = g.attribute(
"id" ,
"" );
1345 nDir.replace(
",",
", ");
1351 os <<
" <li>MythTV Drive #" <<
id <<
":"
1355 if (nDir.contains(
','))
1356 os <<
" <li>Directories: ";
1358 os <<
" <li>Directory: ";
1360 os << nDir <<
"</li>\r\n";
1362 os <<
" <li>Total Space: ";
1363 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1364 os << sRep <<
"</li>\r\n";
1366 os <<
" <li>Space Used: ";
1367 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1368 os << sRep <<
"</li>\r\n";
1370 os <<
" <li>Space Free: ";
1371 sRep = QString(
"%L1").arg(nFree) +
" MB";
1372 os << sRep <<
"</li>\r\n";
1380 node = node.nextSibling();
1387 node =
info.namedItem(
"Guide" );
1391 QDomElement e = node.toElement();
1395 int nDays = e.attribute(
"guideDays",
"0" ).toInt();
1396 QString sStart = e.attribute(
"start" ,
"" );
1397 QString sEnd = e.attribute(
"end" ,
"" );
1398 QString sStatus = e.attribute(
"status" ,
"" );
1400 QString sNext = next.isNull() ?
"" :
1406 QDomText text = e.firstChild().toText();
1413 sMsg = text.nodeValue();
1415 os <<
" Last mythfilldatabase run started on " << sStart
1421 os <<
"ended on " << sEnd <<
". ";
1423 os << sStatus <<
"<br />\r\n";
1425 if (!next.isNull() && next >= lastrunstart)
1427 os <<
" Suggested next mythfilldatabase run: "
1428 << sNext <<
".<br />\r\n";
1433 os <<
" There's guide data until "
1437 os <<
" " << QObject::tr(
"(%n day(s))",
"", nDays);
1442 os <<
" <strong>WARNING</strong>: is mythfilldatabase running?";
1446 os <<
" There's <strong>no guide data</strong> available! "
1447 <<
"Have you run mythfilldatabase?";
1451 os <<
"\r\n </div>\r\n";
1463 QDomNodeList nodes =
info.elementsByTagName(
"Information");
1464 uint count = nodes.count();
1470 os <<
"<div class=\"content\">\r\n"
1471 <<
" <h2 class=\"status\">Miscellaneous</h2>\r\n";
1472 for (
unsigned int i = 0; i < count; i++)
1474 QDomNode node = nodes.item(i);
1478 QDomElement e = node.toElement();
1482 display = e.attribute(
"display",
"");
1486 if (display.isEmpty())
1491 if (display.contains(
"<p>", Qt::CaseInsensitive) ||
1492 display.contains(
"<br", Qt::CaseInsensitive))
1499 linebreak =
"<br />\r\n";
1502 os <<
" " << display << linebreak;
1516 if ((pDoc ==
nullptr) || (pInfo ==
nullptr))
1521 QDomElement program = pDoc->createElement(
"Program" );
1522 node.appendChild( program );
1524 program.setAttribute(
"startTime" ,
1527 program.setAttribute(
"title" , pInfo->
GetTitle() );
1528 program.setAttribute(
"subTitle" , pInfo->
GetSubtitle());
1529 program.setAttribute(
"category" , pInfo->
GetCategory());
1531 program.setAttribute(
"repeat" ,
static_cast<int>(pInfo->
IsRepeat()));
1536 program.setAttribute(
"seriesId" , pInfo->
GetSeriesID() );
1537 program.setAttribute(
"programId" , pInfo->
GetProgramID() );
1538 program.setAttribute(
"stars" , pInfo->
GetStars() );
1539 program.setAttribute(
"fileSize" ,
1541 program.setAttribute(
"lastModified",
1544 program.setAttribute(
"hostname" , pInfo->
GetHostname() );
1547 program.setAttribute(
1550 QDomText textNode = pDoc->createTextNode( pInfo->
GetDescription() );
1551 program.appendChild( textNode );
1559 QDomElement channel = pDoc->createElement(
"Channel" );
1560 program.appendChild( channel );
1569 QDomElement recording = pDoc->createElement(
"Recording" );
1570 program.appendChild( recording );
1572 recording.setAttribute(
"recStatus" ,
1574 recording.setAttribute(
"recPriority" ,
1576 recording.setAttribute(
"recStartTs" ,
1578 recording.setAttribute(
"recEndTs" ,
1583 recording.setAttribute(
"recordId" ,
1585 recording.setAttribute(
"recGroup" ,
1587 recording.setAttribute(
"playGroup" ,
1589 recording.setAttribute(
"recType" ,
1591 recording.setAttribute(
"dupInType" ,
1593 recording.setAttribute(
"dupMethod" ,
1595 recording.setAttribute(
"encoderId" ,
1598 recording.setAttribute(
"recProfile" ,
1625 channel.setAttribute(
"chanId" , pInfo->
GetChanID() );
1626 channel.setAttribute(
"chanNum" , pInfo->
GetChanNum());
1633 channel.setAttribute(
"chanFilters",
1635 channel.setAttribute(
"sourceId" , pInfo->
GetSourceID() );
1636 channel.setAttribute(
"inputId" , pInfo->
GetInputID() );
1637 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,...