Ticket #3176: mythtv-mythshutdown.diff

File mythtv-mythshutdown.diff, 8.7 KB (added by devel@…, 13 years ago)

mythshutdown "Set Scheduled Wakeup Time" and "Detect Recording in Progress"

  • programs/mythshutdown/main.cpp

     
    1111#include <exitcodes.h>
    1212#include <mythcontext.h>
    1313#include <mythdbcon.h>
     14#include "libmythtv/programinfo.h"
     15#include "tv.h"
    1416
    1517void setGlobalSetting(const QString &key, const QString &value)
    1618{
     
    103105    return dtDateTime;
    104106}
    105107
     108bool isRecording()
     109{
     110    bool m_isRecording = false;
     111
     112    if (!gContext->IsConnectedToMaster())
     113    {
     114        VERBOSE(VB_IMPORTANT, "isRecording: Attempting to connect to master server...");
     115        if (!gContext->ConnectToMasterServer(false))
     116        {
     117            VERBOSE(VB_IMPORTANT, "isRecording: Could not connect to master server!");
     118            return false;
     119        }
     120    }
     121
     122    QStringList strlist;
     123
     124    // get list of current recordings
     125    QString querytext = QString("SELECT cardid FROM capturecard WHERE parentid = 0;");
     126    MSqlQuery query(MSqlQuery::InitCon());
     127    query.exec(querytext);
     128    QString Status = "";
     129
     130    if (query.isActive() && query.numRowsAffected())
     131    {
     132        VERBOSE(VB_IMPORTANT, "isRecording: Query active");
     133        while(query.next())
     134        {
     135            QString status = "";
     136            int cardid = query.value(0).toInt();
     137            int state = kState_ChangingState;
     138            QString channelName = "";
     139            QString title = "";
     140            QString subtitle = "";
     141            QDateTime dtStart = QDateTime();
     142            QDateTime dtEnd = QDateTime();
     143
     144            QString cmd = QString("QUERY_REMOTEENCODER %1").arg(cardid);
     145
     146            while (state == kState_ChangingState)
     147            {
     148                strlist = cmd;
     149                strlist << "GET_STATE";
     150                gContext->SendReceiveStringList(strlist);
     151
     152                state = strlist[0].toInt();
     153                if (state == kState_ChangingState)
     154                    usleep(500);
     155            }
     156            VERBOSE(VB_IMPORTANT, "isRecording: Successfully queried encoder.");
     157
     158            if (state == kState_RecordingOnly || state == kState_WatchingRecording)
     159            {
     160                VERBOSE(VB_IMPORTANT, "Recorder is recording. Returning true");
     161                m_isRecording = true;
     162            }
     163        }
     164    }
     165    return m_isRecording;
     166}
     167
    106168int getStatus()
    107169{
    108170    VERBOSE(VB_GENERAL, "Mythshutdown: --status");
     
    127189        res += 4;
    128190    }
    129191
     192    if (isRecording())
     193    {
     194        VERBOSE(VB_IMPORTANT, "Recording in progress...");
     195        res += 8;
     196    }
     197   
    130198    if (getGlobalSetting("MythShutdownLock", "0") == "1")
    131199    {
    132200        VERBOSE(VB_IMPORTANT, "Shutdown is locked");
     
    250318    return 0;
    251319}
    252320
     321int setScheduledWakeupTime()
     322{
     323    typedef struct
     324    {
     325        QString channel, title, subtitle;
     326        QDateTime startTime, endTime;
     327    } ProgramDetail;
     328
     329    if (!gContext->IsConnectedToMaster())
     330    {
     331        VERBOSE(VB_IMPORTANT, "setScheduledWakeupTime: Attempting to connect to master server...");
     332        if (!gContext->ConnectToMasterServer(false))
     333        {
     334            VERBOSE(VB_IMPORTANT, "setScheduledWakeupTime: Could not connect to master server!");
     335            return false;
     336        }
     337    }
     338   
     339    QDateTime m_nextRecordingStart = QDateTime();
     340
     341    ProgramList *progList = new ProgramList(true);
     342    ProgramInfo *progInfo;
     343
     344    if (progList->FromScheduler())
     345    {
     346        if (progList->count() > 0)
     347        {
     348            VERBOSE(VB_IMPORTANT, "setScheduledWakeupTime: At least one scheduled recording found.");
     349            // find the earliest scheduled recording
     350            for (progInfo = progList->first(); progInfo; progInfo = progList->next())
     351            {
     352                if (progInfo->recstatus == rsWillRecord)
     353                {
     354                    if (m_nextRecordingStart.isNull() ||
     355                            m_nextRecordingStart > progInfo->recstartts)
     356                    {
     357                        m_nextRecordingStart = progInfo->recstartts;
     358                    }
     359                }
     360            }
     361
     362            // save the details of the earliest recording(s)
     363            for (progInfo = progList->first(); progInfo; progInfo = progList->next())
     364            {
     365                if (progInfo->recstatus == rsWillRecord)
     366                {
     367                    if (progInfo->recstartts == m_nextRecordingStart)
     368                    {
     369                        ProgramDetail *prog = new ProgramDetail;
     370                        prog->channel = progInfo->channame;
     371                        prog->title = progInfo->title;
     372                        prog->subtitle = progInfo->subtitle;
     373                        prog->startTime = progInfo->recstartts;
     374                        prog->endTime = progInfo->recendts;
     375                    }
     376                }
     377            }
     378        }
     379    }
     380
     381    delete progList;
     382
     383    // set the wakeup time for the next scheduled recording
     384    if (!m_nextRecordingStart.isNull())
     385    {
     386        int m_preRollSeconds = gContext->GetNumSetting("RecordPreRoll");
     387        QDateTime restarttime = m_nextRecordingStart.addSecs((-1) * m_preRollSeconds);
     388
     389        int add = gContext->GetNumSetting("StartupSecsBeforeRecording", 240);
     390        if (add)
     391            restarttime = restarttime.addSecs((-1) * add);
     392
     393        QString wakeup_timeformat = gContext->GetSetting("WakeupTimeFormat",
     394                                                            "yyyy-MM-ddThh:mm");
     395        setWakeupTime(restarttime.toString(wakeup_timeformat));
     396   
     397        return true;
     398    }
     399    return false;
     400}
     401
    253402int shutdown()
    254403{
    255404    VERBOSE(VB_GENERAL, "Mythshutdown: --shutdown");
     
    542691void showUsage()
    543692{
    544693  cout << "Usage of mythshutdown\n";
    545   cout << "-w/--setwakeup time (sets the wakeup time. time=yyyy-MM-ddThh:mm:ss.\n";
     694  cout << "-w/--setwakeup time (sets the wakeup time. time=yyyy-MM-ddThh:mm:ss)\n";
     695  cout << "-t/--setscheduledwakeup (sets the wakeup time to the next scheduled recording)\n";
    546696  cout << "                     doesn't write it into nvram)\n";
    547697  cout << "-q/--shutdown       (set nvram-wakeup time and shutdown)\n";
     698  cout << "-x/--safeshutdown       (equal to -c -t -q.  check shutdown possible, set\n";
     699  cout <<"                                 scheduled wakeup and shutdown)\n";
    548700  cout << "-p/--startup        (check startup. check will return 0 if automatic\n";
    549701  cout << "                                                      1 for manually)\n";
    550702  cout << "-c/--check          (check shutdown possible returns 0 ok to shutdown\n";
     
    556708  cout << "         1 - Transcoding\n";
    557709  cout << "         2 - Commercial Flagging\n";
    558710  cout << "         4 - Grabbing EPG data\n";
    559   cout << "         8 - Not used\n";
     711  cout << "         8 - Recording\n";
    560712  cout << "        16 - Locked\n";
    561713  cout << "        32 - Not used\n";
    562714  cout << "        64 - In a daily wakeup/shutdown period\n";
     
    577729    if (!gContext->Init(false))
    578730    {
    579731        cout << "mythshutdown: Could not initialize myth context. "
    580                 "Exiting." << endl;;
     732                "Exiting." << endl;
    581733        return FRONTEND_EXIT_NO_MYTHCONTEXT;
    582734    }
    583735
     
    590742    bool bSetWakeupTime = false;
    591743    QString sWakeupTime = "";
    592744    bool bShowUsage = false;
     745    bool bSetScheduledWakeupTime = false;
     746    bool bCheckAndShutdown = false;
    593747
    594748    //  Check command line arguments
    595749    for (int argpos = 1; argpos < a.argc(); ++argpos)
     
    663817        {
    664818            bShowUsage = true;
    665819        }
     820        else if (!strcmp(a.argv()[argpos],"-t") ||
     821            !strcmp(a.argv()[argpos],"--setscheduledwakeup"))
     822        {
     823            bSetScheduledWakeupTime = true;
     824        }
     825        else if (!strcmp(a.argv()[argpos],"-x") ||
     826            !strcmp(a.argv()[argpos],"--safeshutdown"))
     827        {
     828            bCheckAndShutdown = true;
     829        }
     830
    666831        else
    667832        {
    668833            cout << "Invalid argument: " << a.argv()[argpos] << endl;
     
    681846        res = unlockShutdown();
    682847    else if (bCheckOKShutdown)
    683848        res = checkOKShutdown();
     849    else if (bSetScheduledWakeupTime)
     850        res = setScheduledWakeupTime();
    684851    else if (bStartup)
    685852        res = startup();
    686853    else if (bShutdown)
     
    689856        res = getStatus();
    690857    else if (bSetWakeupTime)
    691858        res = setWakeupTime(sWakeupTime);
     859    else if (bCheckAndShutdown)
     860    {
     861        cout << "into checkAndShutdown" << endl;
     862        res = checkOKShutdown();
     863        if (res == 0)     // Nothing to stop a shutdown (eg. recording in progress).
     864        {
     865             res = setScheduledWakeupTime();
     866             res = shutdown();
     867        }
     868    }
    692869    else
    693870        showUsage();
    694871