Ticket #4049: mythtv-miscellaneous_status_info-20071005.patch

File mythtv-miscellaneous_status_info-20071005.patch, 19.0 KB (added by sphery <mtdean@…>, 12 years ago)

Updates XML format to put display text in element body

  • programs/mythbackend/httpstatus.h

     
    6363        int     PrintScheduled    ( QTextStream &os, QDomElement scheduled );
    6464        int     PrintJobQueue     ( QTextStream &os, QDomElement jobs );
    6565        int     PrintMachineInfo  ( QTextStream &os, QDomElement info );
     66        int     PrintMiscellaneousInfo ( QTextStream &os, QDomElement info );
    6667
    6768    public:
    6869                 HttpStatus( QMap<int, EncoderLink *> *tvList, Scheduler *sched, AutoExpire *expirer, bool bIsMaster );
  • programs/mythbackend/httpstatus.cpp

     
    2121#include <qfile.h>
    2222#include <qregexp.h>
    2323#include <qbuffer.h>
     24#include <qprocess.h>
    2425#include <math.h>
    2526
    2627#include "../../config.h"
    27 #ifdef CONFIG_LMSENSORS
    28     #define LMSENSOR_DEFAULT_CONFIG_FILE "/etc/sensors.conf"
    29     #include <sensors/sensors.h>
    30     #include <sensors/chips.h>
    31 #endif
    3228
    3329/////////////////////////////////////////////////////////////////////////////
    3430//
     
    309305    QDomElement mInfo   = pDoc->createElement("MachineInfo");
    310306    QDomElement storage = pDoc->createElement("Storage"    );
    311307    QDomElement load    = pDoc->createElement("Load"       );
    312     QDomElement thermal = pDoc->createElement("Thermal"    );
    313308    QDomElement guide   = pDoc->createElement("Guide"      );
    314309
    315310    root.appendChild (mInfo  );
     
    368363        load.setAttribute("avg3", rgdAverages[2]);
    369364    }
    370365
    371  
    372     //temperature -----------------
    373     // Try ACPI first, then lmsensor 2nd
    374     QDir dir("/proc/acpi/thermal_zone");
    375     bool found_acpi = false;
    376     QString acpiTempDir;
    377     if (dir.exists())
    378     {
    379         QStringList lst = dir.entryList();
    380         QRegExp rxp = QRegExp ("TH?M?", TRUE, FALSE);
    381         QString line, temp;
    382         for (QStringList::Iterator it = lst.begin(); it != lst.end(); ++it)
    383         {
    384             if ( (*it).contains(rxp))
    385             {
    386                 acpiTempDir = dir.absFilePath(*it);
    387             }
    388         }
    389        
    390         QFile acpiTempFile(acpiTempDir.append("/temperature"));
    391         if (acpiTempFile.open(IO_ReadOnly))
    392         {
    393             QTextStream stream (&acpiTempFile);
    394             line = stream.readLine();
    395             rxp = QRegExp ("(\\d+)", TRUE, FALSE);
    396             if (rxp.search(line) != -1 )
    397             {
    398                 temp = rxp.cap(1);
    399                 temp += " &#8451;"; // print degress Celsius 
    400                 mInfo.appendChild(thermal);
    401                 thermal.setAttribute("temperature", temp);
    402                 found_acpi = true;
    403             }
    404         } 
    405         acpiTempFile.close();
    406     }                                                 
    407 
    408 #ifdef CONFIG_LMSENSORS
    409     m_settingLock.lock();
    410 
    411     if (!found_acpi)
    412     {
    413         int chip_nr, a, b;
    414         char *label = NULL;
    415         double value;
    416         const sensors_chip_name *chip;
    417         const sensors_feature_data *data;
    418         char* lmsensorConfigName = LMSENSOR_DEFAULT_CONFIG_FILE;
    419         a = b = 0;
    420         FILE *lmsensorConfigFile = fopen(lmsensorConfigName, "r");
    421         sensors_init(lmsensorConfigFile);
    422         fclose(lmsensorConfigFile);
    423         for (chip_nr = 0 ; (chip = sensors_get_detected_chips(&chip_nr)) ; )
    424         {
    425             while ((data = sensors_get_all_features(*chip, &a, &b)))
    426             {
    427                 if ((!sensors_get_label(*chip, data->number, &label)) && 
    428                     (!sensors_get_feature(*chip, data->number, &value)))
    429                 {
    430                     // Find label matching "CPU Temp" or "Temp/CPU"
    431                     QRegExp rxp = QRegExp ("(CPU.+Temp)|(Temp.+CPU)", FALSE, FALSE);
    432                     if (rxp.search(QString(label)) != -1  && value > 0)
    433                     {
    434                         QString temp = QString("%1").arg(value);
    435                         temp += " &#8451;";
    436                         mInfo.appendChild(thermal);
    437                         thermal.setAttribute("temperature", temp);
    438                     }
    439                 }
    440             }
    441         } 
    442         sensors_cleanup();
    443     }
    444     m_settingLock.unlock();
    445 #endif
    446 
    447366    // Guide Data ---------------------
    448367
    449368    QDateTime GuideDataThrough;
     
    477396
    478397    QDomText dataDirectMessage = pDoc->createTextNode(gContext->GetSetting("DataDirectMessage"));
    479398    guide.appendChild(dataDirectMessage);
     399
     400    // Add Miscellaneous information
     401
     402    QString info_script = gContext->GetSetting("MiscStatusScript");
     403    if ((!info_script.isEmpty()) && (info_script != "none"))
     404    {
     405        QDomElement misc = pDoc->createElement("Miscellaneous");
     406        root.appendChild(misc);
     407
     408        QProcess miscellaneous_status_info_proc(info_script);
     409        miscellaneous_status_info_proc.setCommunication(
     410                                          QProcess::Stdout|QProcess::Stderr);
     411
     412        if (miscellaneous_status_info_proc.start())
     413        {
     414            int i = 0;
     415            // Since the miscellaneous status information is not critical
     416            // but creating the status document must wait for it, timeout
     417            // if the script takes more than 10 seconds to execute.
     418            while (miscellaneous_status_info_proc.isRunning() && i < 100)
     419            {
     420                usleep(100000);
     421                ++i;
     422            }
     423
     424            if (miscellaneous_status_info_proc.normalExit())
     425            {
     426                QString input = "";
     427                while (miscellaneous_status_info_proc.canReadLineStdout())
     428                {
     429                    input = miscellaneous_status_info_proc.readLineStdout();
     430                    if (input.isEmpty())
     431                        continue;
     432
     433                    QDomElement info = pDoc->createElement("Information");
     434
     435                    QStringList list = QStringList::split("[]:[]", input, true);
     436                    unsigned int size = list.size();
     437                    unsigned int hasData = 0;
     438
     439                    if ((size > 0) && (!list[0].isEmpty()))
     440                    {
     441                        QDomText textNode = pDoc->createTextNode(list[0]);
     442                        info.appendChild(textNode);
     443                        hasData++;
     444                    }
     445                    if ((size > 2) && (!list[2].isEmpty()))
     446                    {
     447                        info.setAttribute("value", list[2]);
     448                        hasData++;
     449                    }
     450                    if ((size > 1) && (!list[1].isEmpty()))
     451                    {
     452                        info.setAttribute("name", list[1]);
     453                        hasData++;
     454                    }
     455
     456                    if (hasData > 0)
     457                        misc.appendChild(info);
     458                }
     459            }
     460            else
     461            {
     462                VERBOSE(VB_IMPORTANT, QString("Error running miscellaneous "
     463                        "status information script or execution timed out: %1")
     464                        .arg(info_script));
     465            }
     466        }
     467        else
     468        {
     469            VERBOSE(VB_IMPORTANT, QString("Failed to run miscellaneous status "
     470                    "information script: %1").arg(info_script));
     471        }
     472    }
     473
    480474}
    481475
    482476/////////////////////////////////////////////////////////////////////////////
     
    621615    if (!node.isNull())
    622616        PrintMachineInfo( os, node.toElement());
    623617
     618    // Miscellaneous information ---------------
     619
     620    node = docElem.namedItem( "Miscellaneous" );
     621
     622    if (!node.isNull())
     623        PrintMiscellaneousInfo( os, node.toElement());
     624
    624625    os << "\r\n</body>\r\n</html>\r\n";
    625626
    626627}
     
    11511152        }
    11521153    }
    11531154
    1154    // ACPI temperature ------------------
    1155 
    1156     node = info.namedItem( "Thermal" );
    1157 
    1158     if (!node.isNull())
    1159     {
    1160         QDomElement e = node.toElement();
    1161 
    1162         if (!e.isNull())
    1163         {
    1164             QString temperature = e.attribute( "temperature" , "0" );
    1165 
    1166             os << "      Current CPU temperature: "
    1167                << temperature
    1168                << ".<br />\r\n";
    1169         }
    1170     }
    1171        
    11721155    // Guide Info ---------------------
    11731156
    11741157    node = info.namedItem( "Guide" );
     
    12291212                   << "Have you run mythfilldatabase?";
    12301213
    12311214            if (!sMsg.isNull() && !sMsg.isEmpty())
    1232                 os << "<br />\r\nDataDirect Status: " << sMsg;
     1215                os << "<br />\r\n    DataDirect Status: " << sMsg;
    12331216        }
    12341217    }
    12351218    os << "\r\n  </div>\r\n";
     
    12371220    return( 1 );
    12381221}
    12391222
     1223int HttpStatus::PrintMiscellaneousInfo( QTextStream &os, QDomElement info )
     1224{
     1225    if (info.isNull())
     1226        return( 0 );
     1227
     1228    // Miscellaneous information
     1229
     1230    QDomNodeList nodes = info.elementsByTagName("Information");
     1231    uint count = nodes.count();
     1232    if (count > 0)
     1233    {
     1234        QString display, linebreak;
     1235        //QString name, value;
     1236        os << "  <div class=\"content\">\r\n"
     1237           << "    <h2>Miscellaneous</h2>\r\n";
     1238        for (unsigned int i = 0; i < count; i++)
     1239        {
     1240            QDomNode node = nodes.item(i);
     1241            if (node.isNull())
     1242                continue;
     1243
     1244            QDomElement e = node.toElement();
     1245            if (e.isNull())
     1246                continue;
     1247
     1248            QDomText text = e.firstChild().toText();
     1249            if (!text.isNull())
     1250                display = text.nodeValue();
     1251
     1252            //name = e.attribute("name", "");
     1253            //value = e.attribute("value", "");
     1254
     1255            if (display.isEmpty())
     1256                continue;
     1257
     1258            // Only include HTML line break if display value doesn't already
     1259            // contain breaks.
     1260            if ((display.contains("<p>", false) > 0) ||
     1261                (display.contains("<br", false) > 0))
     1262                linebreak = "\r\n";
     1263            else
     1264                linebreak = "<br />\r\n";
     1265
     1266            os << "    " << display << linebreak;
     1267        }
     1268        os << "  </div>\r\n";
     1269    }
     1270
     1271    return( 1 );
     1272}
     1273
    12401274// vim:set shiftwidth=4 tabstop=4 expandtab:
  • programs/mythbackend/mythxml.cpp

     
    2323#include <math.h>
    2424
    2525#include "../../config.h"
    26 #ifdef CONFIG_LMSENSORS
    27     #define LMSENSOR_DEFAULT_CONFIG_FILE "/etc/sensors.conf"
    28     #include <sensors/sensors.h>
    29     #include <sensors/chips.h>
    30 #endif
    3126
    3227/////////////////////////////////////////////////////////////////////////////
    3328//
  • programs/mythbackend/mainserver.cpp

     
    4545#include "jobqueue.h"
    4646#include "autoexpire.h"
    4747#include "previewgenerator.h"
    48 #ifdef CONFIG_LMSENSORS
    49     #define LMSENSOR_DEFAULT_CONFIG_FILE "/etc/sensors.conf"
    50     #include <sensors/sensors.h>
    51     #include <sensors/chips.h>
    52 #endif
    5348
    5449
    5550/** Milliseconds to wait for an existing thread from
  • configure

     
    145145  #echo "  --disable-backend        disable backend  [breaks dependency checking]"
    146146  echo "  --disable-lirc           disable lirc support (Infrared Remotes)"
    147147  echo "  --disable-joystick-menu  disable joystick menu"
    148   echo "  --disable-lmsensors      disable linux hw monitor support"
    149148  echo "  --disable-firewire       disable support for FireWire cable boxes"
    150149  echo "  --disable-iptv           disable support for recording RTSP/UDP/RTP streams"
    151150  echo "  --disable-dbox2          disable support for Nokia DBOX2 DVB boxes (or compatibles)"
     
    788787    ivtv
    789788    joystick_menu
    790789    lirc
    791     lmsensors
    792790    opengl_vsync
    793791    opengl_video
    794792    v4l
     
    10411039joystick_menu="default"
    10421040lamemp3="yes"
    10431041lirc="yes"
    1044 lmsensors="default"
    10451042mac_bundle="no"
    10461043mac_corevideo="no"
    10471044opengl="no"
     
    15631560    CCONFIG="$CCONFIG linux"
    15641561    backend="yes"
    15651562    ! disabled joystick_menu && enable joystick_menu
    1566     ! disabled lmsensors && enable lmsensors
    15671563    LDLATEFLAGS="-Wl,--as-needed $LDLATEFLAGS"
    15681564    ;;
    15691565  irix*)
     
    27922788    fi
    27932789fi
    27942790
    2795 enabled lmsensors && has_header sensors/sensors.h && has_library libsensors || disable lmsensors
    2796 
    27972791if test $targetos = darwin; then
    27982792    # So far, only OS X 10.4 has this as a non-private framework
    27992793    if test -d /System/Library/Frameworks/DiskArbitration.framework/Headers ; then
  • programs/mythbackend/mythbackend.pro

     
    3333using_dvb:DEFINES += USING_DVB
    3434
    3535using_valgrind:DEFINES += USING_VALGRIND
    36 
    37 using_lmsensors:LIBS += -lsensors
  • programs/mythtv-setup/backendsettings.cpp

     
    156156    return gc;
    157157};
    158158
     159static HostLineEdit *MiscStatusScript()
     160{
     161    HostLineEdit *he = new HostLineEdit("MiscStatusScript");
     162    he->setLabel(QObject::tr("Miscellaneous Status Application"));
     163    he->setValue("");
     164    he->setHelpText(QObject::tr("External application or script that outputs "
     165                                "extra information for inclusion in the "
     166                                "backend status page.  See "
     167                                "contrib/misc_status_info/README"));
     168    return he;
     169}
     170
    159171static void init_time_offsets(GlobalComboBox *gc)
    160172{
    161173    gc->addSelection("None");
     
    713725    addChild(locale);
    714726   
    715727    VerticalConfigurationGroup* group2 = new VerticalConfigurationGroup(false);
    716     group2->setLabel(QObject::tr("File Management Settings"));
    717     group2->addChild(MasterBackendOverride());
    718     group2->addChild(DeletesFollowLinks());
    719     group2->addChild(TruncateDeletes());
     728    group2->setLabel(QObject::tr("Miscellaneous Settings"));
     729    VerticalConfigurationGroup* fm = new VerticalConfigurationGroup();
     730    fm->setLabel(QObject::tr("File Management Settings"));
     731    fm->addChild(MasterBackendOverride());
     732    fm->addChild(DeletesFollowLinks());
     733    fm->addChild(TruncateDeletes());
     734    group2->addChild(fm);
     735    VerticalConfigurationGroup* misc = new VerticalConfigurationGroup(false);
     736    misc->addChild(MiscStatusScript());
     737    group2->addChild(misc);
    720738    addChild(group2);
    721739
    722740    VerticalConfigurationGroup* group2a1 = new VerticalConfigurationGroup(false);
  • contrib/misc_status_info/README

     
     1Overview
     2--------
     3MythTV now supports "Miscellaneous" status information on the backend status
     4page allowing the user to include any additional status information through a
     5user-specified program or script.  The script can be specified on a per-backend
     6basis using the mythtv-setup program, in the General settings section on the
     7page, "Miscellaneous Settings."
     8
     9Backend Status Format
     10---------------------
     11The miscellaneous status information is output in the <Miscellaneous> element
     12of the backend status document.  Each piece of information is output using a
     13single XML tag, <Information>, with an optional body (for display when rendered
     14to HTML) and the optional attributes "name", and "value":
     15
     16<Miscellaneous>
     17  <Information name="data name" value="data value" >display text</Information>
     18</Miscellaneous>
     19
     20The body of the <Information> tag, if it exists, is inserted directly into the
     21HTML backend status page.  The display value may contain HTML markup, though
     22doing so may "break" the backend status page, causing it to render incorrectly,
     23so including HTML markup should be done with care.  If the display value does
     24not contain any "<p>" or "<br" HTML breaks, a line break tag (<br />) will be
     25written after the display value.  If the display value provides any HTML
     26breaks, no line breaks will be appended to the value (so the display value must
     27provide all the breaks).  The name and value attributes are only accessible
     28through the XML backend status page.
     29
     30Script Output Format
     31--------------------
     32The script should output the three values on a single line delimited with
     33[]:[], i.e.:
     34
     35display[]:[]name[]:[]value
     36
     37Values may be omitted, as long as the order (and placement) remains constant:
     38
     39display
     40[]:[]name[]:[]value
     41
     42If four (or more) fields are output on a line, the extra fields will be
     43ignored.
     44
     45The script must provide output within 10 seconds or the Miscellaneous status
     46information will not be included on the status page.  This timeout forces the
     47status page to be returned in a reasonably short period of time regardless of
     48the script specified.  If you would like to provide information that requires
     49more than 10 seconds to compute (or that comes from a remote system whose
     50response time is unknown), you may want to set up another script, i.e. in a
     51cron job, and poll the data at appropriate intervals and write the output to a
     52file, which could then be read (or simply cat'ed, if in the proper format) by
     53the miscellaneous status script.
     54
     55Thermal Information
     56-------------------
     57Note that previously, MythTV provided CPU temperature information in the
     58"Machine information" section of the status page.  The values were retrieved
     59directly using libsensors.  The libsensors dependency has since been removed
     60and those wanting this type of information should make it available through the
     61miscellaneous status application.
     62
     63Previously, CPU temperature was output in XML format as:
     64
     65  <Thermal temperature="53.5 &amp;#8451;" />
     66
     67and rendered to HTML as:
     68
     69  Current CPU temperature: 53.5 &#8451;.<br />
     70
     71To get equivalent output using the miscellaneous status info, create a script
     72or program that outputs information such as:
     73
     74  Current CPU temperature: 53.5 &#8451;.[]:[]temperature[]:[]53.5 &#8451;
     75
     76Given the above script output, the status XML document will contain:
     77
     78  <Information name="temperature" value="53.5 &#8451;" >Current CPU Temperature: 53.5 &amp;#8451;.</Information>
     79
     80which will be rendered to HTML as:
     81
     82  Current CPU temperature: 53.5 &#8451;.<br />
     83
     84However, now that the display and value are separate, it may make more sense to
     85remove the HTML entity from the value, such as:
     86
     87  Current CPU temperature: 53.5 &#8451;.[]:[]temperature[]:[]53.5
     88
     89to make machine parsing the XML easier, especially for display in a non-HTML
     90output format.
     91
     92For additional examples, see the example scripts included in the
     93contrib/misc_status_info directory of the MythTV distribution.