21 #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
22 #include <QStringConverter>
24 #include <QTextStream>
29 #include "libmythbase/mythconfig.h"
35 #include "libmythbase/mythversion.h"
87 return QStringList(
"/Status" );
123 LOG(VB_GENERAL, LOG_ERR,
124 "HttpStatus::ProcessRequest() - Unexpected Exception");
136 QDomDocument doc(
"Status" );
139 QDomProcessingInstruction encoding =
140 doc.createProcessingInstruction(
"xml",
141 R
"(version="1.0" encoding="UTF-8")");
142 doc.appendChild(encoding);
147 pRequest->m_mapRespHeaders[ "Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
150 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
151 stream.setCodec(
"UTF-8");
153 stream.setEncoding(QStringConverter::Utf8);
155 stream << doc.toString();
165 pRequest->
m_mapRespHeaders[
"Cache-Control" ] =
"no-cache=\"Ext\", max-age = 5000";
167 QDomDocument doc(
"Status" );
188 QDomElement root = pDoc->createElement(
"Status");
189 pDoc->appendChild(root);
193 root.setAttribute(
"time" ,
195 root.setAttribute(
"ISODate" , qdtNow.toString(
Qt::ISODate) );
196 root.setAttribute(
"version" , MYTH_BINARY_VERSION );
197 root.setAttribute(
"protoVer", MYTH_PROTO_VERSION );
201 QDomElement encoders = pDoc->createElement(
"Encoders");
202 root.appendChild(encoders);
211 if (elink !=
nullptr)
213 TVState state = elink->GetState();
214 isLocal = elink->IsLocal();
216 QDomElement encoder = pDoc->createElement(
"Encoder");
217 encoders.appendChild(encoder);
219 encoder.setAttribute(
"id" , elink->GetInputID() );
220 encoder.setAttribute(
"local" ,
static_cast<int>(isLocal));
221 encoder.setAttribute(
"connected" ,
static_cast<int>(elink->IsConnected()));
222 encoder.setAttribute(
"state" , state );
223 encoder.setAttribute(
"sleepstatus" , elink->GetSleepStatus() );
229 encoder.setAttribute(
"hostname", elink->GetHostName());
231 encoder.setAttribute(
"devlabel",
234 if (elink->IsConnected())
262 encoders.setAttribute(
"count", numencoders);
266 QDomElement scheduled = pDoc->createElement(
"Scheduled");
267 root.appendChild(scheduled);
274 unsigned int iNum = 10;
275 unsigned int iNumRecordings = 0;
277 auto itProg = recordingList.begin();
278 for (; (itProg != recordingList.end()) && iNumRecordings < iNum; ++itProg)
281 ((*itProg)->GetRecordingStartTime() >=
289 while (!recordingList.empty())
293 recordingList.pop_back();
296 scheduled.setAttribute(
"count", iNumRecordings);
300 QDomElement frontends = pDoc->createElement(
"Frontends");
301 root.appendChild(frontends);
304 "urn:schemas-mythtv-org:service:MythFrontend:1");
312 frontends.setAttribute(
"count", map.size() );
313 for (
const auto & entry : qAsConst(map))
315 QDomElement fe = pDoc->createElement(
"Frontend");
316 frontends.appendChild(fe);
317 QUrl url(entry->m_sLocation);
318 fe.setAttribute(
"name", url.host());
319 fe.setAttribute(
"url", url.toString(QUrl::RemovePath));
326 QDomElement backends = pDoc->createElement(
"Backends");
327 root.appendChild(backends);
337 QDomElement mbe = pDoc->createElement(
"Backend");
338 backends.appendChild(mbe);
339 mbe.setAttribute(
"type",
"Master");
340 mbe.setAttribute(
"name", masterhost);
341 mbe.setAttribute(
"url" , masterip +
":" + QString::number(masterport));
345 "urn:schemas-mythtv-org:device:SlaveMediaServer:1");
349 QString ipaddress = QString();
358 for (
const auto & entry : qAsConst(map))
360 QUrl url(entry->m_sLocation);
361 if (url.host() != ipaddress)
364 QDomElement mbe = pDoc->createElement(
"Backend");
365 backends.appendChild(mbe);
366 mbe.setAttribute(
"type",
"Slave");
367 mbe.setAttribute(
"name", url.host());
368 mbe.setAttribute(
"url" , url.toString(QUrl::RemovePath));
374 backends.setAttribute(
"count", numbes);
378 QDomElement
jobqueue = pDoc->createElement(
"JobQueue");
381 QMap<int, JobQueueEntry> jobs;
382 QMap<int, JobQueueEntry>::Iterator it;
388 for (it = jobs.begin(); it != jobs.end(); ++it)
390 ProgramInfo pginfo((*it).chanid, (*it).recstartts);
394 QDomElement job = pDoc->createElement(
"Job");
397 job.setAttribute(
"id" , (*it).id );
398 job.setAttribute(
"chanId" , (*it).chanid );
399 job.setAttribute(
"startTime" ,
401 job.setAttribute(
"startTs" , (*it).startts );
402 job.setAttribute(
"insertTime",
404 job.setAttribute(
"type" , (*it).type );
405 job.setAttribute(
"cmds" , (*it).cmds );
406 job.setAttribute(
"flags" , (*it).flags );
407 job.setAttribute(
"status" , (*it).status );
408 job.setAttribute(
"statusTime",
410 job.setAttribute(
"schedTime" ,
412 job.setAttribute(
"args" , (*it).args );
414 if ((*it).hostname.isEmpty())
415 job.setAttribute(
"hostname", QObject::tr(
"master"));
417 job.setAttribute(
"hostname",(*it).hostname);
419 QDomText textNode = pDoc->createTextNode((*it).comment);
420 job.appendChild(textNode);
425 jobqueue.setAttribute(
"count", jobs.size() );
429 QDomElement mInfo = pDoc->createElement(
"MachineInfo");
430 QDomElement storage = pDoc->createElement(
"Storage" );
431 QDomElement load = pDoc->createElement(
"Load" );
432 QDomElement guide = pDoc->createElement(
"Guide" );
434 root.appendChild (mInfo );
435 mInfo.appendChild(storage);
436 mInfo.appendChild(load );
437 mInfo.appendChild(guide );
454 QList<QDomElement> fsXML;
455 QStringList::const_iterator sit = strlist.cbegin();
456 while (sit != strlist.cend())
459 directory = *(sit++);
460 isLocalstr = *(sit++);
464 long long iTotal = (*(sit++)).toLongLong();
465 long long iUsed = (*(sit++)).toLongLong();;
466 long long iAvail = iTotal - iUsed;
471 QDomElement group = pDoc->createElement(
"Group");
473 group.setAttribute(
"id" , fsID );
474 group.setAttribute(
"total", (
int)(iTotal>>10) );
475 group.setAttribute(
"used" , (
int)(iUsed>>10) );
476 group.setAttribute(
"free" , (
int)(iAvail>>10) );
477 group.setAttribute(
"dir" , directory );
481 long long iLiveTV = -1;
482 long long iDeleted = -1;
483 long long iExpirable = -1;
485 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
486 " WHERE recgroup = :RECGROUP;");
491 iLiveTV = query.
value(0).toLongLong();
496 iDeleted = query.
value(0).toLongLong();
498 query.
prepare(
"SELECT SUM(filesize) FROM recorded "
499 " WHERE autoexpire = 1 "
500 " AND recgroup NOT IN ('LiveTV', 'Deleted');");
503 iExpirable = query.
value(0).toLongLong();
505 group.setAttribute(
"livetv", (
int)(iLiveTV>>20) );
506 group.setAttribute(
"deleted", (
int)(iDeleted>>20) );
507 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 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
590 QStringList
output = QString(input).split(
'\n',
591 QString::SkipEmptyParts);
593 QStringList
output = QString(input).split(
'\n',
597 for (
const auto & line : qAsConst(
output))
599 QDomElement info = pDoc->createElement(
"Information");
601 QStringList list = line.split(
"[]:[]");
602 unsigned int size = list.size();
603 unsigned int hasAttributes = 0;
605 if ((size > 0) && (!list[0].isEmpty()))
607 info.setAttribute(
"display", list[0]);
610 if ((size > 1) && (!list[1].isEmpty()))
612 info.setAttribute(
"name", list[1]);
615 if ((size > 2) && (!list[2].isEmpty()))
617 info.setAttribute(
"value", list[2]);
621 if (hasAttributes > 0)
622 misc.appendChild(info);
633 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
634 os.setCodec(
"UTF-8");
636 os.setEncoding(QStringConverter::Utf8);
641 QDomElement docElem = pDoc->documentElement();
643 os <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
644 <<
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n"
645 <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\""
646 <<
" xml:lang=\"en\" lang=\"en\">\r\n"
648 <<
" <meta http-equiv=\"Content-Type\""
649 <<
"content=\"text/html; charset=UTF-8\" />\r\n"
650 <<
" <link rel=\"stylesheet\" href=\"/css/Status.css\" type=\"text/css\">\r\n"
651 <<
" <title>MythTV Status - "
655 << docElem.attribute(
"version", MYTH_BINARY_VERSION ) <<
"</title>\r\n"
657 <<
"<body bgcolor=\"#fff\">\r\n"
658 <<
"<div class=\"status\">\r\n"
659 <<
" <h1 class=\"status\">MythTV Status</h1>\r\n";
663 QDomNode node = docElem.namedItem(
"Encoders" );
670 node = docElem.namedItem(
"Scheduled" );
677 node = docElem.namedItem(
"Frontends" );
684 node = docElem.namedItem(
"Backends" );
691 node = docElem.namedItem(
"JobQueue" );
698 node = docElem.namedItem(
"MachineInfo" );
705 node = docElem.namedItem(
"Miscellaneous" );
710 os <<
"\r\n</div>\r\n</body>\r\n</html>\r\n";
720 int nNumEncoders = 0;
722 if (encoders.isNull())
725 os <<
" <div class=\"content\">\r\n"
726 <<
" <h2 class=\"status\">Encoder Status</h2>\r\n";
728 QDomNode node = encoders.firstChild();
730 while (!node.isNull())
732 QDomElement e = node.toElement();
736 if (e.tagName() ==
"Encoder")
738 QString sIsLocal = (e.attribute(
"local" ,
"remote" )==
"1")
739 ?
"local" :
"remote";
740 QString sCardId = e.attribute(
"id" ,
"0" );
741 QString sHostName = e.attribute(
"hostname" ,
"Unknown");
742 bool bConnected=
static_cast<bool>(e.attribute(
"connected",
"0" ).toInt());
744 bool bIsLowOnFreeSpace=
static_cast<bool>(e.attribute(
"lowOnFreeSpace",
"0").toInt());
746 QString sDevlabel = e.attribute(
"devlabel",
"[ UNKNOWN ]");
748 os <<
" Encoder " << sCardId <<
" " << sDevlabel
749 <<
" is " << sIsLocal <<
" on " << sHostName;
751 if ((sIsLocal ==
"remote") && !bConnected)
758 os <<
" (currently asleep).<br />";
760 os <<
" (currently not connected).<br />";
762 node = node.nextSibling();
773 os <<
" and is watching Live TV";
778 os <<
" and is recording";
782 os <<
" and is not recording.";
788 QDomNode tmpNode = e.namedItem(
"Program" );
790 if (!tmpNode.isNull())
792 QDomElement program = tmpNode.toElement();
794 if (!program.isNull())
796 os <<
" '" << program.attribute(
"title",
"Unknown" ) <<
"'";
800 tmpNode = program.namedItem(
"Channel" );
802 if (!tmpNode.isNull())
804 QDomElement channel = tmpNode.toElement();
806 if (!channel.isNull())
808 << channel.attribute(
"callSign",
"unknown" );
813 tmpNode = program.namedItem(
"Recording" );
815 if (!tmpNode.isNull())
817 QDomElement recording = tmpNode.toElement();
819 if (!recording.isNull())
822 recording.attribute(
"recEndTs",
"" ));
824 os <<
". This recording ";
830 os <<
"scheduled to end at "
840 if (bIsLowOnFreeSpace)
842 os <<
" <strong>WARNING</strong>:"
843 <<
" This backend is low on free disk space!";
850 node = node.nextSibling();
853 os <<
" </div>\r\n\r\n";
855 return( nNumEncoders );
866 if (scheduled.isNull())
869 int nNumRecordings= scheduled.attribute(
"count",
"0" ).toInt();
871 os <<
" <div class=\"content\">\r\n"
872 <<
" <h2 class=\"status\">Schedule</h2>\r\n";
874 if (nNumRecordings == 0)
876 os <<
" There are no shows scheduled for recording.\r\n"
881 os <<
" The next " << nNumRecordings <<
" show" << (nNumRecordings == 1 ?
"" :
"s" )
882 <<
" that " << (nNumRecordings == 1 ?
"is" :
"are")
883 <<
" scheduled for recording:\r\n";
885 os <<
" <div class=\"schedule\">\r\n";
889 QDomNode node = scheduled.firstChild();
891 while (!node.isNull())
893 QDomElement e = node.toElement();
897 QDomNode recNode = e.namedItem(
"Recording" );
898 QDomNode chanNode = e.namedItem(
"Channel" );
900 if ((e.tagName() ==
"Program") && !recNode.isNull() &&
903 QDomElement r = recNode.toElement();
904 QDomElement c = chanNode.toElement();
906 QString sTitle = e.attribute(
"title" ,
"" );
907 QString sSubTitle = e.attribute(
"subTitle",
"" );
913 int nPreRollSecs = r.attribute(
"preRollSeconds",
"0" ).toInt();
914 int nEncoderId = r.attribute(
"encoderId" ,
"0" ).toInt();
915 QString sProfile = r.attribute(
"recProfile" ,
"" );
916 QString sChanName = c.attribute(
"channelName" ,
"" );
919 QDomText text = e.firstChild().toText();
921 sDesc = text.nodeValue();
925 int nTotalSecs = qdtNow.secsTo( recStartTs ) - nPreRollSecs;
931 int nTotalDays = nTotalSecs / 86400;
932 int nTotalHours = (nTotalSecs / 3600)
934 int nTotalMins = (nTotalSecs / 60) % 60;
936 QString sTimeToStart =
"in";
938 sTimeToStart += QObject::tr(
" %n day(s),",
"", nTotalDays );
939 sTimeToStart += QObject::tr(
" %n hour(s) and",
"", nTotalHours);
940 sTimeToStart += QObject::tr(
" %n minute(s)",
"", nTotalMins);
942 if ( nTotalHours == 0 && nTotalMins == 0)
943 sTimeToStart = QObject::tr(
"within one minute",
"Recording starting");
946 sTimeToStart = QObject::tr(
"soon",
"Recording starting");
950 os <<
" <a href=\"#\">";
958 os <<
"Encoder " << nEncoderId <<
" - ";
960 os << sChanName <<
" - " << sTitle <<
"<br />"
961 <<
"<span><strong>" << sTitle <<
"</strong> ("
965 if ( !sSubTitle.isEmpty())
966 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
968 if ( airDate.isValid())
970 os <<
"Orig. Airdate: "
976 os << sDesc <<
"<br /><br />"
977 <<
"This recording will start " << sTimeToStart
978 <<
" using encoder " << nEncoderId <<
" with the '"
979 << sProfile <<
"' profile.</span></a><hr />\r\n";
983 node = node.nextSibling();
986 os <<
" </div>\r\n\r\n";
988 return( nNumRecordings );
997 if (frontends.isNull())
1000 int nNumFES= frontends.attribute(
"count",
"0" ).toInt();
1006 os <<
" <div class=\"content\">\r\n"
1007 <<
" <h2 class=\"status\">Frontends</h2>\r\n";
1009 QDomNode node = frontends.firstChild();
1010 while (!node.isNull())
1012 QDomElement e = node.toElement();
1016 QString name = e.attribute(
"name" ,
"" );
1017 QString url = e.attribute(
"url" ,
"" );
1018 os << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1021 node = node.nextSibling();
1024 os <<
" </div>\r\n\r\n";
1035 if (backends.isNull())
1038 int nNumBES= backends.attribute(
"count",
"0" ).toInt();
1044 os <<
" <div class=\"content\">\r\n"
1045 <<
" <h2 class=\"status\">Other Backends</h2>\r\n";
1047 QDomNode node = backends.firstChild();
1048 while (!node.isNull())
1050 QDomElement e = node.toElement();
1054 QString
type = e.attribute(
"type",
"" );
1055 QString name = e.attribute(
"name" ,
"" );
1056 QString url = e.attribute(
"url" ,
"" );
1057 os <<
type <<
": " << name <<
" (<a href=\"" << url <<
"\">Status page</a>)<br />";
1060 node = node.nextSibling();
1063 os <<
" </div>\r\n\r\n";
1077 int nNumJobs= jobs.attribute(
"count",
"0" ).toInt();
1079 os <<
" <div class=\"content\">\r\n"
1080 <<
" <h2 class=\"status\">Job Queue</h2>\r\n";
1084 QString statusColor;
1087 os <<
" Jobs currently in Queue or recently ended:\r\n<br />"
1088 <<
" <div class=\"schedule\">\r\n";
1091 QDomNode node = jobs.firstChild();
1093 while (!node.isNull())
1095 QDomElement e = node.toElement();
1099 QDomNode progNode = e.namedItem(
"Program" );
1101 if ((e.tagName() ==
"Job") && !progNode.isNull() )
1103 QDomElement
p = progNode.toElement();
1105 QDomNode recNode =
p.namedItem(
"Recording" );
1106 QDomNode chanNode =
p.namedItem(
"Channel" );
1108 QDomElement r = recNode.toElement();
1109 QDomElement c = chanNode.toElement();
1111 int nType = e.attribute(
"type" ,
"0" ).toInt();
1112 int nStatus = e.attribute(
"status",
"0" ).toInt();
1117 statusColor =
" class=\"jobaborted\"";
1122 statusColor =
" class=\"joberrored\"";
1123 jobColor =
" class=\"joberrored\"";
1127 statusColor =
" class=\"jobfinished\"";
1128 jobColor =
" class=\"jobfinished\"";
1132 statusColor =
" class=\"jobrunning\"";
1133 jobColor =
" class=\"jobrunning\"";
1137 statusColor =
" class=\"jobqueued\"";
1138 jobColor =
" class=\"jobqueued\"";
1142 QString sTitle =
p.attribute(
"title" ,
"" );
1143 QString sSubTitle =
p.attribute(
"subTitle",
"" );
1149 QString sHostname = e.attribute(
"hostname",
"master" );
1150 QString sComment =
"";
1152 QDomText text = e.firstChild().toText();
1154 sComment = text.nodeValue();
1156 os <<
"<a href=\"javascript:void(0)\">"
1160 << sTitle <<
" - <font" << jobColor <<
">"
1162 <<
"<span><strong>" << sTitle <<
"</strong> ("
1166 if (!sSubTitle.isEmpty())
1167 os <<
"<em>" << sSubTitle <<
"</em><br /><br />";
1173 os <<
"Scheduled Run Time: "
1180 os <<
"Status: <font" << statusColor <<
">"
1188 if ( nStatus != JOB_QUEUED)
1189 os <<
"Host: " << sHostname <<
"<br />";
1191 if (!sComment.isEmpty())
1192 os <<
"<br />Comments:<br />" << sComment <<
"<br />";
1194 os <<
"</span></a><hr />\r\n";
1198 node = node.nextSibling();
1200 os <<
" </div>\r\n";
1203 os <<
" Job Queue is currently empty.\r\n\r\n";
1205 os <<
" </div>\r\n\r\n ";
1222 os <<
"<div class=\"content\">\r\n"
1223 <<
" <h2 class=\"status\">Machine Information</h2>\r\n";
1227 QDomNode node = info.namedItem(
"Load" );
1231 QDomElement e = node.toElement();
1235 double dAvg1 = e.attribute(
"avg1" ,
"0" ).toDouble();
1236 double dAvg2 = e.attribute(
"avg2" ,
"0" ).toDouble();
1237 double dAvg3 = e.attribute(
"avg3" ,
"0" ).toDouble();
1239 os <<
" <div class=\"loadstatus\">\r\n"
1240 <<
" This machine's load average:"
1241 <<
"\r\n <ul>\r\n <li>"
1242 <<
"1 Minute: " << dAvg1 <<
"</li>\r\n"
1243 <<
" <li>5 Minutes: " << dAvg2 <<
"</li>\r\n"
1244 <<
" <li>15 Minutes: " << dAvg3
1245 <<
"</li>\r\n </ul>\r\n"
1251 node = info.namedItem(
"Storage" );
1252 QDomElement storage = node.toElement();
1253 node = storage.firstChild();
1258 while (!node.isNull())
1260 QDomElement g = node.toElement();
1262 if (!g.isNull() && g.tagName() ==
"Group")
1264 QString
id = g.attribute(
"id",
"" );
1268 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1269 int nTotal = g.attribute(
"total",
"0" ).toInt();
1270 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1271 int nLiveTV = g.attribute(
"livetv" ,
"0" ).toInt();
1272 int nDeleted = g.attribute(
"deleted",
"0" ).toInt();
1273 int nExpirable = g.attribute(
"expirable" ,
"0" ).toInt();
1274 QString nDir = g.attribute(
"dir" ,
"" );
1276 nDir.replace(
",",
", ");
1278 os <<
" Disk Usage Summary:<br />\r\n";
1281 os <<
" <li>Total Disk Space:\r\n"
1284 os <<
" <li>Total Space: ";
1285 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1286 os << sRep <<
"</li>\r\n";
1288 os <<
" <li>Space Used: ";
1289 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1290 os << sRep <<
"</li>\r\n";
1292 os <<
" <li>Space Free: ";
1293 sRep = QString(
"%L1").arg(nFree) +
" MB";
1294 os << sRep <<
"</li>\r\n";
1296 if ((nLiveTV + nDeleted + nExpirable) > 0)
1298 os <<
" <li>Space Available "
1299 "After Auto-expire: ";
1300 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1301 sRep = QString(
"%L1").arg(nFree + nLiveTV +
1302 nDeleted + nExpirable) +
" MB";
1303 os << sRep <<
"\r\n";
1305 os <<
" <li>Space Used by LiveTV: ";
1306 sRep = QString(
"%L1").arg(nLiveTV) +
" MB";
1307 os << sRep <<
"</li>\r\n";
1308 os <<
" <li>Space Used by "
1309 "Deleted Recordings: ";
1310 sRep = QString(
"%L1").arg(nDeleted) +
" MB";
1311 os << sRep <<
"</li>\r\n";
1312 os <<
" <li>Space Used by "
1313 "Auto-expirable Recordings: ";
1314 sRep = QString(
"%L1").arg(nExpirable) +
" MB";
1315 os << sRep <<
"</li>\r\n";
1328 node = node.nextSibling();
1332 node = storage.firstChild();
1334 os <<
" Disk Usage Details:<br />\r\n";
1338 while (!node.isNull())
1340 QDomElement g = node.toElement();
1342 if (!g.isNull() && g.tagName() ==
"Group")
1344 int nFree = g.attribute(
"free" ,
"0" ).toInt();
1345 int nTotal = g.attribute(
"total",
"0" ).toInt();
1346 int nUsed = g.attribute(
"used" ,
"0" ).toInt();
1347 QString nDir = g.attribute(
"dir" ,
"" );
1348 QString
id = g.attribute(
"id" ,
"" );
1350 nDir.replace(
",",
", ");
1356 os <<
" <li>MythTV Drive #" <<
id <<
":"
1360 if (nDir.contains(
','))
1361 os <<
" <li>Directories: ";
1363 os <<
" <li>Directory: ";
1365 os << nDir <<
"</li>\r\n";
1367 os <<
" <li>Total Space: ";
1368 sRep = QString(
"%L1").arg(nTotal) +
" MB";
1369 os << sRep <<
"</li>\r\n";
1371 os <<
" <li>Space Used: ";
1372 sRep = QString(
"%L1").arg(nUsed) +
" MB";
1373 os << sRep <<
"</li>\r\n";
1375 os <<
" <li>Space Free: ";
1376 sRep = QString(
"%L1").arg(nFree) +
" MB";
1377 os << sRep <<
"</li>\r\n";
1385 node = node.nextSibling();
1392 node = info.namedItem(
"Guide" );
1396 QDomElement e = node.toElement();
1400 int nDays = e.attribute(
"guideDays",
"0" ).toInt();
1401 QString sStart = e.attribute(
"start" ,
"" );
1402 QString sEnd = e.attribute(
"end" ,
"" );
1403 QString sStatus = e.attribute(
"status" ,
"" );
1405 QString sNext = next.isNull() ?
"" :
1411 QDomText text = e.firstChild().toText();
1418 sMsg = text.nodeValue();
1420 os <<
" Last mythfilldatabase run started on " << sStart
1426 os <<
"ended on " << sEnd <<
". ";
1428 os << sStatus <<
"<br />\r\n";
1430 if (!next.isNull() && next >= lastrunstart)
1432 os <<
" Suggested next mythfilldatabase run: "
1433 << sNext <<
".<br />\r\n";
1438 os <<
" There's guide data until "
1442 os <<
" " << QObject::tr(
"(%n day(s))",
"", nDays);
1447 os <<
" <strong>WARNING</strong>: is mythfilldatabase running?";
1450 os <<
" There's <strong>no guide data</strong> available! "
1451 <<
"Have you run mythfilldatabase?";
1454 os <<
"\r\n </div>\r\n";
1466 QDomNodeList nodes = info.elementsByTagName(
"Information");
1467 uint count = nodes.count();
1473 os <<
"<div class=\"content\">\r\n"
1474 <<
" <h2 class=\"status\">Miscellaneous</h2>\r\n";
1475 for (
unsigned int i = 0; i < count; i++)
1477 QDomNode node = nodes.item(i);
1481 QDomElement e = node.toElement();
1485 display = e.attribute(
"display",
"");
1489 if (display.isEmpty())
1494 if (display.contains(
"<p>", Qt::CaseInsensitive) ||
1495 display.contains(
"<br", Qt::CaseInsensitive))
1501 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" ,