Ticket #4049: mythtv-miscellaneous_status_info.patch

File mythtv-miscellaneous_status_info.patch, 18.9 KB (added by sphery <mtdean@…>, 12 years ago)
  • 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    // TODO: Add GUI control/setting for info_script
     403    QString info_script = gContext->GetSetting("MiscStatusScript");
     404    if ((!info_script.isEmpty()) && (info_script != "none"))
     405    {
     406        QDomElement misc = pDoc->createElement("Miscellaneous");
     407        root.appendChild(misc);
     408
     409        QProcess miscellaneous_status_info_proc(info_script);
     410        miscellaneous_status_info_proc.setCommunication(
     411                                          QProcess::Stdout|QProcess::Stderr);
     412
     413        if (miscellaneous_status_info_proc.start())
     414        {
     415            int i = 0;
     416            // Since the miscellaneous status information is not critical
     417            // but creating the status document must wait for it, timeout
     418            // if the script takes more than 10 seconds to execute.
     419            while (miscellaneous_status_info_proc.isRunning() && i < 100)
     420            {
     421                usleep(100000);
     422                ++i;
     423            }
     424
     425            if (miscellaneous_status_info_proc.normalExit())
     426            {
     427                QString input = "";
     428                while (miscellaneous_status_info_proc.canReadLineStdout())
     429                {
     430                    input = miscellaneous_status_info_proc.readLineStdout();
     431                    if (input.isEmpty())
     432                        continue;
     433
     434                    QDomElement info = pDoc->createElement("Information");
     435
     436                    QStringList list = QStringList::split("[]:[]", input, true);
     437                    unsigned int size = list.size();
     438                    unsigned int hasAttributes = 0;
     439
     440                    // TODO: escape XML
     441                    if ((size > 0) && (!list[0].isEmpty()))
     442                    {
     443                        info.setAttribute("display", list[0]);
     444                        hasAttributes++;
     445                    }
     446                    if ((size > 1) && (!list[1].isEmpty()))
     447                    {
     448                        info.setAttribute("name", list[1]);
     449                        hasAttributes++;
     450                    }
     451                    if ((size > 2) && (!list[2].isEmpty()))
     452                    {
     453                        info.setAttribute("value", list[2]);
     454                        hasAttributes++;
     455                    }
     456
     457                    if (hasAttributes > 0)
     458                        misc.appendChild(info);
     459                }
     460            }
     461            else
     462            {
     463                VERBOSE(VB_IMPORTANT, QString("Error running miscellaneous "
     464                        "status information script or execution timed out: %1")
     465                        .arg(info_script));
     466            }
     467        }
     468        else
     469        {
     470            VERBOSE(VB_IMPORTANT, QString("Failed to run miscellaneous status "
     471                    "information script: %1").arg(info_script));
     472        }
     473    }
     474
    480475}
    481476
    482477/////////////////////////////////////////////////////////////////////////////
     
    621616    if (!node.isNull())
    622617        PrintMachineInfo( os, node.toElement());
    623618
     619    // Miscellaneous information ---------------
     620
     621    node = docElem.namedItem( "Miscellaneous" );
     622
     623    if (!node.isNull())
     624        PrintMiscellaneousInfo( os, node.toElement());
     625
    624626    os << "\r\n</body>\r\n</html>\r\n";
    625627
    626628}
     
    11511153        }
    11521154    }
    11531155
    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        
    11721156    // Guide Info ---------------------
    11731157
    11741158    node = info.namedItem( "Guide" );
     
    12291213                   << "Have you run mythfilldatabase?";
    12301214
    12311215            if (!sMsg.isNull() && !sMsg.isEmpty())
    1232                 os << "<br />\r\nDataDirect Status: " << sMsg;
     1216                os << "<br />\r\n    DataDirect Status: " << sMsg;
    12331217        }
    12341218    }
    12351219    os << "\r\n  </div>\r\n";
     
    12371221    return( 1 );
    12381222}
    12391223
     1224int HttpStatus::PrintMiscellaneousInfo( QTextStream &os, QDomElement info )
     1225{
     1226    if (info.isNull())
     1227        return( 0 );
     1228
     1229    // Miscellaneous information
     1230
     1231    QDomNodeList nodes = info.elementsByTagName("Information");
     1232    uint count = nodes.count();
     1233    if (count > 0)
     1234    {
     1235        QString display, linebreak;
     1236        //QString name, value;
     1237        os << "<div class=\"content\">\r\n"
     1238           << "    <h2>Miscellaneous</h2>\r\n";
     1239        for (unsigned int i = 0; i < count; i++)
     1240        {
     1241            QDomNode node = nodes.item(i);
     1242            if (node.isNull())
     1243                continue;
     1244
     1245            QDomElement e = node.toElement();
     1246            if (e.isNull())
     1247                continue;
     1248
     1249            display = e.attribute("display", "");
     1250            //name = e.attribute("name", "");
     1251            //value = e.attribute("value", "");
     1252
     1253            if (display.isEmpty())
     1254                continue;
     1255
     1256            // Only include HTML line break if display value doesn't already
     1257            // contain breaks.
     1258            if ((display.contains("<p>", false) > 0) ||
     1259                (display.contains("<br", false) > 0))
     1260                linebreak = "\r\n";
     1261            else
     1262                linebreak = "<br />\r\n";
     1263
     1264            os << "    " << display << linebreak;
     1265        }
     1266        os << "</div>\r\n";
     1267    }
     1268
     1269    return( 1 );
     1270}
     1271
    12401272// 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 any of 3 attributes, "display", "name", and
     14"value":
     15
     16<Miscellaneous>
     17  <Information display="display value" name="data name" value="data value" />
     18</Miscellaneous>
     19
     20The value of the display attribute is inserted directly into the HTML backend
     21status page.  If the display value does not contain any "<p>" or "<br" HTML
     22breaks, a line break tag (<br />) will be written after the display value.  If
     23the display value provides any HTML breaks, no line breaks will be appended to
     24the value (so the display value must provide all the breaks).  The name and
     25value attributes are only accessible through the XML backend status page.  The
     26display value may contain HTML markup, though doing so may "break" the backend
     27status page, causing it to render incorrectly, so including HTML markup should
     28be done with care.
     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 display="Current CPU temperature: 53.5 &amp;#8451;." name="temperature" value="53.5 &amp;#8451;" />
     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.