[mythtv] [PATCH] Database logging/MythContextPrivate

Matt White whitem at arts.usask.ca
Fri Mar 5 17:18:22 EST 2004


Crud.  Would help if I actually attached the file....

It must be Friday - my brain's already shut down for the weekend.

-- 
Matt White                          whitem at arts.usask.ca
Arts and Science Computer Labs      University of Saskatchewan

I used to think they were after me...
But they're just after my recipe.
	- Joe Diffie..."Good Brown Gravy"
-------------- next part --------------
Index: contrib/mythmaillog.pl
===================================================================
RCS file: contrib/mythmaillog.pl
diff -N contrib/mythmaillog.pl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ contrib/mythmaillog.pl	5 Mar 2004 21:37:49 -0000
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+##
+## Script to email database log entries.
+##
+## 21 Feb 04	1.0	Initial version
+##
+## written by Matt White (whitem at arts.usask.ca)
+## 
+## Remember to edit the settings below to your taste
+##
+
+use DBI;
+
+## 
+## User Configurable Settings
+##
+
+# The email address to send the logs to
+# ** REMEMBER TO ESCAPE THE @ SYMBOL!! **
+$mailto = "someone\@somewhere.changeme";
+
+# The "from" address used in the sent mail
+# ** REMEMBER TO ESCAPE THE @ SYMBOL!! **
+$mailfrom = "someoneelse\@somewhere.changeme";
+
+# Location of your sendmail binary
+$sendmail = "/usr/sbin/sendmail";
+
+# What do you want to get?
+# 1 = Mail out all unacknowledged log entries
+# 2 = Mail out all entries since last email was sent
+$mailwhat = 1;
+
+# Do you want to automatically acknowledge entries that
+# were sent out?  Yes=1, No=0
+$autoack = 1;
+
+# Database connection details for Myth DB
+$dbhost = "localhost";
+$dbname = "mythconverg";
+$dbuser = "mythtv";
+$dbpass = "mythtv";
+
+##
+## End of User-configurable settings
+##
+
+my @priorities = ("Emergency","Alert","Critical","Error","Warning","Notice",
+                  "Info","Debug");
+my $dbh = 
+DBI->connect("dbi:mysql:database=$dbname:host=$dbhost","$dbuser","$dbpass") or
+		 die "Cannot connect to database ($!)\n";
+if ($mailwhat == 2) {
+    $q = "select data from settings where value = 'LogLastEmail'";
+    $sth = $dbh->prepare($q);
+    $numrows = $sth->execute or die "Could not execute ($q)\n";
+    if ($numrows!=0) {
+        @row=$sth->fetchrow_array;
+        $lastemail = 0 + $row[0];
+    } else {
+        $lastemail = 0;
+    }
+    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
+        localtime($lastemail);
+    $lastdate = sprintf("%4d-%02d-%02dT%02d:%02d:%02d",$year+1900,$mon+1,
+        $mday,$hour,$min,$sec);
+
+    $where = "(logdate > '$lastdate')";
+} else {
+    $where = "(acknowledged = 0)";
+}
+
+$now = time();
+$email = "";
+$q = "select logid,module,priority,acknowledged,logdate,host," .
+     "message,details from mythlog where $where order by logdate";
+$sth = $dbh->prepare($q);
+$numrows = $sth->execute or die "Could not execute ($q)\n";
+while (@row = $sth->fetchrow_array) {
+    $logid = $row[0];
+    $module = $row[1];
+    $priority = $row[2];
+    $ack = $row[3];
+    $logdate = $row[4];
+    $host = $row[5];
+    $message = $row[6];
+    $details = $row[7];
+    if ($mailwhat == 2) {
+        if ($ack == 1) {
+            $printack = "Acknowledged: Yes";
+        } else {
+            $printack = "Acknowledged: No";
+        }
+    } else {
+        $printack = "";
+    }
+
+    $email .= sprintf("%-20s %-15s %s\n",$logdate,$host,$message);
+    $email .= sprintf("    Module: %-20s Priority: %-12s %s\n\n",$module,$priority,
+                      $printack);
+}
+
+if ($numrows == 0) {
+    exit(0);
+}
+
+if ($autoack == 1) {
+    $q = "update mythlog set acknowledged = 1 where $where";
+    $sth = $dbh->prepare($q);
+    $sth->execute or die "Could not execute ($q)\n";
+}
+
+if ($mailwhat == 2) {
+    if ($lastemail == 0) {
+        $q = "insert into settings (value,data) values ('LogLastEmail','$now')";
+    } else {
+        $q = "update settings set data='$now' where value='LogLastEmail'";
+    }
+    $sth = $dbh->prepare($q);
+    $sth->execute or die "Could not execute ($q)\n";
+}
+
+($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
+        localtime($now);
+$subject = sprintf("Myth Event Report for %4d-%02d-%02d",$year+1900,$mon+1,$mday);
+open MAIL,"| $sendmail -t";
+print MAIL "From: $mailfrom\n";
+print MAIL "To: $mailto\n";
+print MAIL "Subject: $subject\n\n";
+print MAIL $email;
+close MAIL;
+
+exit(0);
Index: libs/libmyth/mythcontext.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/mythcontext.cpp,v
retrieving revision 1.114
diff -u -w -r1.114 mythcontext.cpp
--- libs/libmyth/mythcontext.cpp	1 Mar 2004 18:05:36 -0000	1.114
+++ libs/libmyth/mythcontext.cpp	5 Mar 2004 21:37:49 -0000
@@ -74,6 +74,7 @@
 
     float m_wmult, m_hmult;
     int m_screenwidth, m_screenheight;
+    int m_logenable, m_logmaxcount, m_logprintlevel;
 
     QString themecachedir;
 
@@ -159,6 +160,10 @@
     serverSock = NULL;
     eventSock = new QSocket(0);
 
+    m_logenable = -1;
+    m_logmaxcount = -1;
+    m_logprintlevel = -1;
+
     mainWindow = NULL;
 
     if (lcd)
@@ -391,6 +396,13 @@
     InitializeScreenSettings();
 }
 
+void MythContext::RefreshBackendConfig(void)
+{
+    d->m_logenable = GetNumSetting("LogEnabled",0);
+    d->m_logmaxcount = GetNumSetting("LogMaxCount",0);
+    d->m_logprintlevel = GetNumSetting("LogPrintLevel",LP_ERROR);
+}
+
 void MythContext::UpdateImageCache(void)
 {
     d->imageCache.clear();
@@ -859,6 +871,81 @@
     return retval.toInt();
 }
 
+void MythContext::LogEntry(const QString &module, int priority,
+                     const QString &message, const QString &details)
+{
+    static QMap<QString,int> lastLogCounts;
+    static QMap<QString,QString> lastLogStrings;
+    unsigned int logid;
+    int howmany;
+
+    if (d->m_logenable == -1) // Haven't grabbed the settings yet
+        RefreshBackendConfig();
+    if (d->m_logenable == 1)
+    {
+        if (message.left(21) != "Last message repeated")
+	{
+            if (message == lastLogStrings[module])
+            {
+                lastLogCounts[module] += 1;
+    	    return;
+            }
+            else
+            {
+                if (0 < lastLogCounts[module])
+                {
+                    LogEntry(module, priority, QString("Last message repeated %1 times")
+                             .arg(lastLogCounts[module]),lastLogStrings[module]);
+                }
+
+                lastLogCounts[module] = 0;
+                lastLogStrings[module] = message;
+            }
+        }
+
+        d->dbLock.lock();
+    
+        if (d->m_db->isOpen())
+        {
+            KickDatabase(d->m_db);
+    
+            QString querystr = QString("INSERT INTO mythlog ( module, priority, "
+                                       "logdate, host, message, details) "
+                                       "values ( '%1', %2, now(), '%3', "
+                                       "'%4','%5' );") . arg(module) .
+                                       arg(priority) . arg(d->m_localhostname) .
+                                       arg(message) . arg(details);
+    
+            QSqlQuery result = d->m_db->exec(querystr);
+            if (!result.isActive())
+                MythContext::DBError("LogEntry", querystr);
+
+	    if (d->m_logmaxcount > 0)
+	    {
+	        querystr = QString("SELECT logid FROM mythlog WHERE "
+	                           "module='%1' ORDER BY logdate ASC") .arg(module);
+	        result = d->m_db->exec(querystr);
+		howmany = result.size();
+                if (howmany > d->m_logmaxcount)
+                    while (howmany > d->m_logmaxcount)
+                    {
+		        result.next();
+		        logid = result.value(0).toUInt();
+                        querystr = QString("DELETE FROM mythlog WHERE "
+		                           "logid=%1") .arg(logid);
+                        d->m_db->exec(querystr);
+		        howmany--;
+                    }
+	    }
+        }
+    
+        d->dbLock.unlock();
+	if (priority <= d->m_logprintlevel)
+            cout << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") \
+	             << " " << module << ":" << message << endl;
+    }
+}
+
 QString MythContext::GetSettingOnHost(const QString &key, const QString &host,
                                       const QString &defaultval)
 {
Index: libs/libmyth/mythcontext.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/mythcontext.h,v
retrieving revision 1.133
diff -u -w -r1.133 mythcontext.h
--- libs/libmyth/mythcontext.h	4 Mar 2004 02:50:59 -0000	1.133
+++ libs/libmyth/mythcontext.h	5 Mar 2004 21:37:49 -0000
@@ -42,6 +42,17 @@
     VB_ALL       = 0xffff
 };
 
+enum LogPriorities {
+    LP_EMERG     = 0,
+    LP_ALERT     = 1,
+    LP_CRITICAL  = 2,
+    LP_ERROR     = 3,
+    LP_WARNING   = 4,
+    LP_NOTICE    = 5,
+    LP_INFO      = 6,
+    LP_DEBUG     = 7
+};
+
 #define VERBOSE(mask,args...) \
 do { \
 if ((print_verbose_messages & mask) != 0) \
@@ -105,6 +116,7 @@
 
     bool LoadSettingsFiles(const QString &filename);
     void LoadQtConfig(void);
+    void RefreshBackendConfig(void);
     void UpdateImageCache(void);
 
     void GetScreenSettings(float &wmult, float &hmult);
@@ -129,6 +141,9 @@
     QString GetSetting(const QString &key, const QString &defaultval = "");
     int GetNumSetting(const QString &key, int defaultval = 0);
 
+    void LogEntry(const QString &module, int priority,
+                  const QString &message, const QString &details);
+
     QString GetSettingOnHost(const QString &key, const QString &host,
                              const QString &defaultval = "");
     int GetNumSettingOnHost(const QString &key, const QString &host,
Index: libs/libmythtv/dbcheck.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dbcheck.cpp,v
retrieving revision 1.36
diff -u -w -r1.36 dbcheck.cpp
--- libs/libmythtv/dbcheck.cpp	2 Mar 2004 06:31:52 -0000	1.36
+++ libs/libmythtv/dbcheck.cpp	5 Mar 2004 21:37:49 -0000
@@ -8,7 +8,7 @@
 
 #include "mythcontext.h"
 
-const QString currentDatabaseVersion = "1034";
+const QString currentDatabaseVersion = "1035";
 
 void UpdateDBVersionNumber(const QString &newnumber)
 {
@@ -648,6 +648,27 @@
 };
         performActualUpdate(updates, "1034", dbver);
     }
+    if (dbver == "1034")
+    {
+        const QString updates[] = {
+"CREATE TABLE mythlog ("
+"  logid int(10) unsigned PRIMARY KEY NOT NULL auto_increment,"
+"  module char(32) NOT NULL,"
+"  priority int(11) NOT NULL,"
+"  acknowledged bool default 0,"
+"  logdate datetime,"
+"  host varchar(128),"
+"  message varchar(255) NOT NULL,"
+"  details text"
+");",
+"CREATE TABLE housekeeping ("
+"  tag varchar(64) PRIMARY KEY NOT NULL,"
+"  lastrun datetime"
+");",
+""
+};
+        performActualUpdate(updates, "1035", dbver);
+    }
 };
 
 void InitializeDatabase(void)
Index: programs/mythbackend/housekeeper.cpp
===================================================================
RCS file: programs/mythbackend/housekeeper.cpp
diff -N programs/mythbackend/housekeeper.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ programs/mythbackend/housekeeper.cpp	5 Mar 2004 21:37:49 -0000
@@ -0,0 +1,210 @@
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <qsqldatabase.h>
+#include <qsqlquery.h>
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qstringlist.h>
+
+#include <iostream>
+using namespace std;
+
+#include "housekeeper.h"
+
+#include "libmyth/mythcontext.h"
+
+bool HouseKeeper_filldb_running = false;
+
+void reapChild(int sig)
+{
+    (void) wait(0);
+    HouseKeeper_filldb_running = false;
+}
+
+HouseKeeper::HouseKeeper(bool runthread, bool master, QSqlDatabase *ldb)
+{
+    db = ldb;
+    isMaster = master;
+
+    threadrunning = runthread;
+    filldbRunning = false;
+
+    if (runthread)
+    {
+        pthread_t hkthread;
+        pthread_create(&hkthread, NULL, doHouseKeepingThread, this);
+        gContext->addListener(this);
+    }
+}
+
+HouseKeeper::~HouseKeeper()
+{
+    if (threadrunning)
+        gContext->removeListener(this);
+}
+
+bool HouseKeeper::wantToRun(QString dbTag, int period, int minhour,
+                            int maxhour)
+{
+    bool runOK = false;
+    unsigned int oneday = 60 * 60 * 24;
+
+    QDateTime now = QDateTime::currentDateTime();
+    QDateTime lastrun;
+    lastrun.setTime_t(0);
+    if (db->isOpen())
+    {
+        gContext->KickDatabase(db);
+        QString query = QString("SELECT lastrun FROM housekeeping WHERE "
+                                "tag = \"%1\";") .arg(dbTag);
+        QSqlQuery result = db->exec(query);
+        if (result.isActive() && result.numRowsAffected() > 0)
+        {
+            result.next();
+            lastrun = result.value(0).toDateTime();
+        }
+    }
+
+    if ((now.toTime_t() - lastrun.toTime_t()) > period * oneday)
+    {
+        int hour = now.toString(QString("h")).toInt();
+        if ((hour>=minhour) && (hour<=maxhour))
+            runOK = true;       
+    }
+    return(runOK);
+}
+
+void HouseKeeper::updateLastrun(QString dbTag)
+{
+    if (db->isOpen())
+    {
+        gContext->KickDatabase(db);
+        QString query = QString("DELETE FROM housekeeping WHERE "
+                                "tag = \"%1\";") .arg(dbTag);
+        QSqlQuery result = db->exec(query);
+        query = QString("INSERT INTO housekeeping (tag,lastrun) "
+                        "values (\"%1\",now())") .arg(dbTag);
+        result = db->exec(query);
+    }
+}
+
+void HouseKeeper::RunHouseKeeping(void)
+{
+    int period,maxhr,minhr;
+    // wait a little for main server to come up and things to settle down
+    sleep(10);
+
+    while (1)
+    {
+        gContext->LogEntry(QString("mythbackend"),LP_DEBUG,
+	         QString("Running housekeeping thread"),QString(""));
+        // These tasks are only done from the master backend
+        if (isMaster)
+        {
+            // Clean out old database entries
+            if ((bool) gContext->GetNumSetting("LogEnabled", 0) &&
+               (bool) gContext->GetNumSetting("LogCleanEnabled", 0))
+            {
+                period = gContext->GetNumSetting("LogCleanPeriod",1);
+                if (wantToRun(QString("LogClean"),period,0,24))
+                {
+                    QString msg = QString("Running LogClean");
+                    VERBOSE(VB_GENERAL, msg);
+                    flushLogs();
+                    updateLastrun(QString("LogClean"));
+                }
+            }
+
+            // Run mythfilldatabase to grab the TV listings
+            if ((bool) gContext->GetNumSetting("MythFillEnabled", 0))
+            {
+                if (HouseKeeper_filldb_running)
+                {
+                    QString msg = QString("mythfilldatabase still running, skipping checks");
+                    VERBOSE(VB_GENERAL, msg);
+                } else {
+                    period = gContext->GetNumSetting("MythFillPeriod",1);
+                    minhr = gContext->GetNumSetting("MythFillMinHour",-1);
+                    if (minhr == -1)
+                    {
+                        minhr = 0;
+                        maxhr = 24;
+                    } else {
+                        maxhr = gContext->GetNumSetting("MythFillMaxHour",24);
+                    }
+                    if (wantToRun(QString("MythFillDB"),period,minhr,maxhr))
+                    {
+                        QString msg = QString("Running mythfilldatabase");
+                        gContext->LogEntry(QString("mythbackend"),LP_DEBUG,
+                                           msg,QString(""));
+                        VERBOSE(VB_GENERAL, msg);
+                        runFillDatabase();
+                        updateLastrun(QString("MythFillDB"));
+                    }
+                }
+            }
+        }
+    
+        sleep(300);
+    }
+} 
+
+void HouseKeeper::flushLogs()
+{
+    int numdays = gContext->GetNumSetting("LogCleanDays",14);
+    int maxdays = gContext->GetNumSetting("LogCleanMax",30);
+
+    QDateTime days = QDateTime::currentDateTime();
+    days.addDays(0-numdays);
+    QDateTime max = QDateTime::currentDateTime();
+    max.addDays(0-maxdays);
+
+    if (db->isOpen())
+    {
+        gContext->KickDatabase(db);
+        QString dstring = days.toString(QString("yyyy-MM-dd hh:mm:ss"));
+        QString query = QString("DELETE FROM mythlog WHERE "
+                                "acknowledged=1 and logdate<\"%1\";")
+                                .arg(dstring);
+        QSqlQuery result = db->exec(query);
+
+        dstring = max.toString(QString("yyyy-MM-dd hh:mm:ss"));
+        query = QString("DELETE FROM mythlog WHERE logdate<\"%1\";")
+                                .arg(dstring);
+        result = db->exec(query);
+    }
+}
+
+void HouseKeeper::runFillDatabase()
+{
+    QString command;
+
+    QString mfpath = gContext->GetSetting("MythFillDatabasePath","/usr/local/bin/mythfilldatabase");
+    QString mfarg = gContext->GetSetting("MythFillDatabaseArgs","");
+    QString mflog = gContext->GetSetting("MythFillDatabaseLog","/var/log/mythfilldatabase.log");
+
+    if (mflog == "")
+        command = QString("%1 %2") .arg(mfpath) .arg(mfarg);
+    else
+        command = QString("%1 %2 >>%3 2>&1") .arg(mfpath) 
+                                  .arg(mfarg) .arg(mflog);
+    
+    signal(SIGCHLD,&reapChild);
+    HouseKeeper_filldb_running = true;
+    if (fork() == 0)
+    {
+        system(command.ascii());
+        exit(0);
+    }
+}
+
+void *HouseKeeper::doHouseKeepingThread(void *param)
+{
+    HouseKeeper *hkeeper = (HouseKeeper *)param;
+    hkeeper->RunHouseKeeping();
+ 
+    return NULL;
+}
Index: programs/mythbackend/housekeeper.h
===================================================================
RCS file: programs/mythbackend/housekeeper.h
diff -N programs/mythbackend/housekeeper.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ programs/mythbackend/housekeeper.h	5 Mar 2004 21:37:49 -0000
@@ -0,0 +1,38 @@
+#ifndef HOUSEKEEPER_H_
+#define HOUSEKEEPER_H_
+
+class QSqlDatabase;
+
+#include <qmutex.h>
+#include <qobject.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qprocess.h>
+
+using namespace std;
+
+class HouseKeeper : public QObject
+{
+    Q_OBJECT
+  public:
+    HouseKeeper(bool runthread, bool master, QSqlDatabase *ldb);
+   ~HouseKeeper();
+
+  protected:
+    void RunHouseKeeping(void);
+    static void *doHouseKeepingThread(void *param);
+
+
+  private:
+    QSqlDatabase *db;
+
+    bool wantToRun(QString dbTag, int period, int minhour, int maxhour);
+    void updateLastrun(QString dbTag);
+    void flushLogs();
+    void runFillDatabase();
+    bool threadrunning;
+    bool filldbRunning;
+    bool isMaster;
+};
+
+#endif
Index: programs/mythbackend/main.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/main.cpp,v
retrieving revision 1.61
diff -u -w -r1.61 main.cpp
--- programs/mythbackend/main.cpp	4 Mar 2004 21:18:07 -0000	1.61
+++ programs/mythbackend/main.cpp	5 Mar 2004 21:37:49 -0000
@@ -14,6 +14,7 @@
 
 #include "tv.h"
 #include "autoexpire.h"
+#include "housekeeper.h"
 #include "scheduler.h"
 #include "transcoder.h"
 #include "mainserver.h"
@@ -26,6 +27,7 @@
 
 QMap<int, EncoderLink *> tvList;
 AutoExpire *expirer = NULL;
+HouseKeeper *housekeeping = NULL;
 Scheduler *sched = NULL;
 Transcoder *trans = NULL;
 QString pidfile;
@@ -51,6 +53,11 @@
                 cerr << "One of your capturecard entries does not have a "
                      << "hostname.\n  Please run setup and confirm all of the "
                      << "capture cards.\n";
+                gContext->LogEntry("mythbackend",LP_CRITICAL,
+                      "Problem with capture cards",
+                      "One of your capturecard entries does not have a "
+                      "hostname.\n  Please run setup and confirm all of the "
+                      "capture cards.\n");
                 exit(-1);
             }
 
@@ -85,6 +92,8 @@
     {
         cerr << "ERROR: no capture cards are defined in the database.\n";
         cerr << "Perhaps you should read the installation instructions?\n";
+        gContext->LogEntry("mythbackend",LP_CRITICAL,
+                "No capture cards are defined","Please run the setup program.");
         return false;
     }
 
@@ -360,6 +369,13 @@
         return -1;
     }
 
+    QSqlDatabase *hkthread = QSqlDatabase::addDatabase("QMYSQL3", "HKDB");
+    if (!hkthread)
+    {
+        cerr << "Couldn't connect to database\n";
+        return -1;
+    }
+
     QSqlDatabase *transthread = QSqlDatabase::addDatabase("QMYSQL3", "TRANSDB");
     if (!transthread)
     {
@@ -376,6 +392,7 @@
 
     if (!gContext->OpenDatabase(db) || !gContext->OpenDatabase(subthread) ||
         !gContext->OpenDatabase(expthread) ||
+        !gContext->OpenDatabase(hkthread) ||
         !gContext->OpenDatabase(transthread) ||
         !gContext->OpenDatabase(msdb))
     {
@@ -437,6 +454,9 @@
     if (masterip == myip)
     {
         cerr << "Starting up as the master server.\n";
+        gContext->LogEntry("mythbackend",LP_INFO,
+                           "MythBackend started as master server","");
+
         ismaster = true;
 
         if (nosched)
@@ -446,6 +466,8 @@
     else
     {
         cerr << "Running as a slave backend.\n";
+        gContext->LogEntry("mythbackend",LP_INFO,
+                           "MythBackend started as a slave backend","");
     }
  
     bool runsched = setupTVs(ismaster);
@@ -459,6 +481,9 @@
     QSqlDatabase *expdb = QSqlDatabase::database("EXPDB");
     expirer = new AutoExpire(true, ismaster, expdb);
 
+    QSqlDatabase *hkdb = QSqlDatabase::database("HKDB");
+    housekeeping = new HouseKeeper(true, ismaster, hkdb);
+
     QSqlDatabase *trandb = QSqlDatabase::database("TRANSDB");
     trans = new Transcoder(&tvList, trandb);
 
@@ -504,6 +529,8 @@
     a.exec();
 
     // delete trans;
+    gContext->LogEntry("mythbackend",LP_INFO,
+                       "MythBackend exiting","");
 
     cleanup();
 
Index: programs/mythbackend/mainserver.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/mainserver.cpp,v
retrieving revision 1.128
diff -u -w -r1.128 mainserver.cpp
--- programs/mythbackend/mainserver.cpp	27 Feb 2004 20:38:03 -0000	1.128
+++ programs/mythbackend/mainserver.cpp	5 Mar 2004 21:37:49 -0000
@@ -369,6 +369,11 @@
         MythEvent me(message, extra);
         gContext->dispatch(me);
     }
+    else if (command == "REFRESH_BACKEND")
+    {
+        VERBOSE(VB_ALL,"Reloading backend settings");
+        HandleBackendRefresh(sock);
+    }
     else
         VERBOSE(VB_ALL, "Unknown command: " + command);
 }
@@ -2289,6 +2294,14 @@
     delete pginfo;
 }
 
+void MainServer::HandleBackendRefresh(QSocket *socket)
+{
+    gContext->RefreshBackendConfig();
+
+    QStringList retlist = "OK";
+    SendResponse(socket, retlist);    
+}
+
 void MainServer::endConnection(QSocket *socket)
 {
     vector<PlaybackSock *>::iterator it = playbackList.begin();
Index: programs/mythbackend/mainserver.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/mainserver.h,v
retrieving revision 1.42
diff -u -w -r1.42 mainserver.h
--- programs/mythbackend/mainserver.h	27 Feb 2004 20:38:03 -0000	1.42
+++ programs/mythbackend/mainserver.h	5 Mar 2004 21:37:49 -0000
@@ -85,6 +85,7 @@
     void HandleLockTuner(PlaybackSock *pbs);
     void HandleFreeTuner(int cardid, PlaybackSock *pbs);
     void HandleVersion(QSocket *socket, QString version);
+    void HandleBackendRefresh(QSocket *socket);
 
     void SendResponse(QSocket *pbs, QStringList &commands);
 
Index: programs/mythbackend/mythbackend.pro
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/mythbackend.pro,v
retrieving revision 1.12
diff -u -w -r1.12 mythbackend.pro
--- programs/mythbackend/mythbackend.pro	1 Jan 2004 03:38:45 -0000	1.12
+++ programs/mythbackend/mythbackend.pro	5 Mar 2004 21:37:49 -0000
@@ -19,8 +19,8 @@
 
 # Input
 HEADERS += autoexpire.h encoderlink.h filetransfer.h httpstatus.h mainserver.h
-HEADERS += playbacksock.h scheduler.h server.h transcoder.h
+HEADERS += playbacksock.h scheduler.h server.h transcoder.h housekeeper.h
 
 SOURCES += autoexpire.cpp encoderlink.cpp filetransfer.cpp httpstatus.cpp
 SOURCES += main.cpp mainserver.cpp playbacksock.cpp scheduler.cpp server.cpp
-SOURCES += transcoder.cpp
+SOURCES += transcoder.cpp housekeeper.cpp
Index: programs/mythfilldatabase/filldata.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfilldatabase/filldata.cpp,v
retrieving revision 1.94
diff -u -w -r1.94 filldata.cpp
--- programs/mythfilldatabase/filldata.cpp	2 Mar 2004 06:43:30 -0000	1.94
+++ programs/mythfilldatabase/filldata.cpp	5 Mar 2004 21:37:50 -0000
@@ -2156,6 +2156,7 @@
         return -1;
     }
 
+    gContext->LogEntry("mythfilldatabase",LP_INFO,"Listings Download Started","");
     if (from_xawfile)
     {
         readXawtvChannels(fromxawfile_id, fromxawfile_name);
@@ -2194,6 +2195,7 @@
              {
                   cerr << "There are no channel sources defined, did you run the "
                        << "setup program?\n";
+                  gContext->LogEntry("mythfilldatabase",LP_CRITICAL,"No channel sources defined","Could not find any defined channel sources - did you run the setup program?");
                   exit(-1);
              }
         }
@@ -2208,6 +2210,7 @@
         if (!ret)
         {
              cerr << "Failed to fetch some program info\n";
+             gContext->LogEntry("mythfilldatabase",LP_WARNING,"Failed to fetch some program info","");
              exit(1);
         }
     }
@@ -2222,6 +2225,7 @@
 
     ScheduledRecording::signalChange(db);
 
+    gContext->LogEntry("mythfilldatabase",LP_INFO,"Listings Download Finished","");
     delete gContext;
 
     return 0;
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfrontend/globalsettings.cpp,v
retrieving revision 1.146
diff -u -w -r1.146 globalsettings.cpp
--- programs/mythfrontend/globalsettings.cpp	5 Mar 2004 04:14:01 -0000	1.146
+++ programs/mythfrontend/globalsettings.cpp	5 Mar 2004 21:37:50 -0000
@@ -982,6 +982,238 @@
     };
 };
 
+class LogEnabled: public CheckBoxSetting, public GlobalSetting {
+public:
+    LogEnabled():
+        GlobalSetting("LogEnabled") {
+        setLabel(QObject::tr("DB Logging Enabled"));
+        setValue(false);
+        setHelpText(QObject::tr("If checked, the Myth modules will send event details "
+                    "to the database, where they can be viewed with MythLog or emailed "
+                    "out periodically."));
+    };
+};
+
+class LogMaxCount: public SpinBoxSetting, public GlobalSetting {
+public:
+    LogMaxCount():
+        SpinBoxSetting(0,500,10),
+        GlobalSetting("LogMaxCount") {
+        setLabel(QObject::tr("Max. Number of Entries per Module"));
+        setValue(0);
+        setHelpText(QObject::tr("If there are more than this number of entries for "
+	                        "a module, the oldest log entries will be deleted to "
+				"reduce the count to this number.  Set to 0 to disable."));
+    };
+};
+
+class LogCleanEnabled: public CheckBoxSetting, public GlobalSetting {
+public:
+    LogCleanEnabled():
+        GlobalSetting("LogCleanEnabled") {
+        setLabel(QObject::tr("Automatic Log Cleaning Enabled"));
+        setValue(false);
+        setHelpText(QObject::tr("This enables the periodic cleanup of the events stored "
+                    "in the Myth database (see 'DB Logging Enabled' on the previous "
+                    "page)."));
+    };
+};
+
+class LogCleanPeriod: public SpinBoxSetting, public GlobalSetting {
+public:
+    LogCleanPeriod():
+        SpinBoxSetting(0,60,1),
+        GlobalSetting("LogCleanPeriod") {
+        setLabel(QObject::tr("Log Cleanup Frequency (Days)"));
+        setValue(14);
+        setHelpText(QObject::tr("The number of days between log cleanup runs"));
+    };
+};
+
+class LogCleanDays: public SpinBoxSetting, public GlobalSetting {
+public:
+    LogCleanDays():
+        SpinBoxSetting(0,60,1),
+        GlobalSetting("LogCleanDays") {
+        setLabel(QObject::tr("Number of days to keep acknowledged log entries"));
+        setValue(14);
+        setHelpText(QObject::tr("The number of days before a log entry that has been "
+	                        "acknowledged will be deleted by the log cleanup "
+				"process."));
+    };
+};
+
+class LogCleanMax: public SpinBoxSetting, public GlobalSetting {
+public:
+    LogCleanMax():
+        SpinBoxSetting(0,60,1),
+        GlobalSetting("LogCleanMax") {
+        setLabel(QObject::tr("Number of days to keep unacknowledged log entries"));
+        setValue(30);
+        setHelpText(QObject::tr("The number of days before a log entry that has NOT "
+	                        "been acknowledged will be deleted by the log cleanup "
+				"process."));
+    };
+};
+
+class LogPrintLevel: public ComboBoxSetting, public GlobalSetting {
+public:
+    LogPrintLevel() :
+      GlobalSetting("LogPrintLevel") {
+        setLabel(QObject::tr("Log Print Threshold"));
+        addSelection(QObject::tr("All Messages"), "8");
+        addSelection(QObject::tr("Debug and Higher"), "7");
+        addSelection(QObject::tr("Info and Higher"), "6");
+        addSelection(QObject::tr("Notice and Higher"), "5");
+        addSelection(QObject::tr("Warning and Higher"), "4");
+        addSelection(QObject::tr("Error and Higher"), "3");
+        addSelection(QObject::tr("Critical and Higher"), "2");
+        addSelection(QObject::tr("Alert and Higher"), "1");
+        addSelection(QObject::tr("Emergency Only"), "0");
+        addSelection(QObject::tr("Disable Printed Output"), "-1");
+        setHelpText(QObject::tr("This controls what messages will be printed out as "
+                                "well as being logged to the database."));
+    }
+};
+
+class MythFillEnabled: public CheckBoxSetting, public GlobalSetting {
+public:
+    MythFillEnabled():
+        GlobalSetting("MythFillEnabled") {
+        setLabel(QObject::tr("Automatically run mythfilldatabase"));
+        setValue(false);
+        setHelpText(QObject::tr("This enables the automatic execution of "
+                                "mythfilldatabase."));
+    };
+};
+
+class MythFillPeriod: public SpinBoxSetting, public GlobalSetting {
+public:
+    MythFillPeriod():
+        SpinBoxSetting(0,30,1),
+        GlobalSetting("MythFillPeriod") {
+        setLabel(QObject::tr("mythfilldatabase Run Frequency (Days)"));
+        setValue(1);
+        setHelpText(QObject::tr("The number of days between mythfilldatabase runs"));
+    };
+};
+
+class MythFillMinHour: public SpinBoxSetting, public GlobalSetting {
+public:
+    MythFillMinHour():
+        SpinBoxSetting(0,24,1),
+        GlobalSetting("MythFillMinHour") {
+        setLabel(QObject::tr("mythfilldatabase Execution Start"));
+        setValue(2);
+        setHelpText(QObject::tr("This setting and the following one define a "
+                    "time period when the mythfilldatabase process is allowed to "
+                    "run.  Ex. setting Min to 11 and Max to 13 would mean that "
+                    "the process would only run between 11 AM and 1 PM."));
+    };
+};
+
+class MythFillMaxHour: public SpinBoxSetting, public GlobalSetting {
+public:
+    MythFillMaxHour():
+        SpinBoxSetting(0,24,1),
+        GlobalSetting("MythFillMaxHour") {
+        setLabel(QObject::tr("mythfilldatabase Execution End"));
+        setValue(5);
+        setHelpText(QObject::tr("This setting and the preceding one define a "
+                    "time period when the mythfilldatabase process is allowed to "
+                    "run.  Ex. setting Min to 11 and Max to 13 would mean that "
+                    "the process would only run between 11 AM and 1 PM."));
+    };
+};
+
+class MythFillDatabasePath: public LineEditSetting, public GlobalSetting {
+public:
+    MythFillDatabasePath():
+        GlobalSetting("MythFillDatabasePath") {
+        setLabel(QObject::tr("mythfilldatabase Path"));
+        setValue("/usr/local/bin/mythfilldatabase");
+        setHelpText(QObject::tr("Path (including executable) of the "
+                                "mythfilldatabase program."));
+    };
+};
+
+class MythFillDatabaseArgs: public LineEditSetting, public GlobalSetting {
+public:
+    MythFillDatabaseArgs():
+        GlobalSetting("MythFillDatabaseArgs") {
+        setLabel(QObject::tr("mythfilldatabase Arguments"));
+        setValue("");
+        setHelpText(QObject::tr("Any arguments you want passed to the "
+                                "mythfilldatabase program."));
+    };
+};
+
+class MythFillDatabaseLog: public LineEditSetting, public GlobalSetting {
+public:
+    MythFillDatabaseLog():
+        GlobalSetting("MythFillDatabaseLog") {
+        setLabel(QObject::tr("mythfilldatabase Log Path"));
+        setValue("/var/log/mythfilldatabase.log");
+        setHelpText(QObject::tr("Path to use for logging output from "
+                                "mythfilldatabase program.  Leave blank "
+				"to disable logging."));
+    };
+};
+
+class MythLogSettings: public VerticalConfigurationGroup,
+                      public TriggeredConfigurationGroup {
+public:
+     MythLogSettings():
+         VerticalConfigurationGroup(false),
+         TriggeredConfigurationGroup(false) {
+         setLabel(QObject::tr("Myth Database Logging"));
+//         setUseLabel(false);
+
+         Setting* logEnabled = new LogEnabled();
+         addChild(logEnabled);
+         setTrigger(logEnabled);
+	 addChild(new LogMaxCount());
+
+         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
+         settings->addChild(new LogPrintLevel());
+         settings->addChild(new LogCleanEnabled());
+         settings->addChild(new LogCleanPeriod());
+         settings->addChild(new LogCleanDays());
+         settings->addChild(new LogCleanMax());
+         addTarget("1", settings);
+         
+         // show nothing if logEnabled is off
+         addTarget("0", new VerticalConfigurationGroup(true));
+     };
+};
+
+class MythFillSettings: public VerticalConfigurationGroup,
+                      public TriggeredConfigurationGroup {
+public:
+     MythFillSettings():
+         VerticalConfigurationGroup(false),
+         TriggeredConfigurationGroup(false) {
+         setLabel(QObject::tr("Mythfilldatabase"));
+         setUseLabel(false);
+
+         Setting* fillEnabled = new MythFillEnabled();
+         addChild(fillEnabled);
+         setTrigger(fillEnabled);
+
+         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
+         settings->addChild(new MythFillDatabasePath());
+         settings->addChild(new MythFillDatabaseArgs());
+         settings->addChild(new MythFillDatabaseLog());
+         settings->addChild(new MythFillPeriod());
+         settings->addChild(new MythFillMinHour());
+         settings->addChild(new MythFillMaxHour());
+         addTarget("1", settings);
+         
+         // show nothing if fillEnabled is off
+         addTarget("0", new VerticalConfigurationGroup(true));
+     };
+};
+
 class XineramaScreen: public SpinBoxSetting, public GlobalSetting {
 public:
     XineramaScreen():
@@ -1704,6 +1936,12 @@
     general->addChild(new EnableMediaMon());
     general->addChild(new EnableXbox());
     addChild(general);
+
+    MythLogSettings *mythlog = new MythLogSettings();
+    addChild(mythlog);
+
+    MythFillSettings *mythfill = new MythFillSettings();
+    addChild(mythfill);
 }
 
 PlaybackSettings::PlaybackSettings()
Index: programs/mythfrontend/main.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfrontend/main.cpp,v
retrieving revision 1.138
diff -u -w -r1.138 main.cpp
--- programs/mythfrontend/main.cpp	2 Mar 2004 06:34:57 -0000	1.138
+++ programs/mythfrontend/main.cpp	5 Mar 2004 21:37:50 -0000
@@ -427,6 +427,8 @@
         MainGeneralSettings mainsettings;
         mainsettings.exec(QSqlDatabase::database());
         menu->ReloadExitKey();
+        QStringList strlist = QString("REFRESH_BACKEND");
+	gContext->SendReceiveStringList(strlist);
     } 
     else if (sel == "settings playback") 
     {


More information about the mythtv-dev mailing list