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"
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";
848 return( nNumEncoders );
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" ,