MythTV  0.26-pre
main.cpp
Go to the documentation of this file.
00001 /*
00002     main.cpp
00003 
00004     MythArchive - mythtv plugin
00005     
00006     Starting point for the MythArchive module
00007 */
00008 #include <iostream>
00009 #include <cstdlib>
00010 #include <signal.h>
00011 
00012 using namespace std;
00013 
00014 // Qt
00015 #include <QApplication>
00016 #include <QDir>
00017 #include <QTimer>
00018 
00019 // mythtv
00020 #include <mythpluginapi.h>
00021 #include <mythcontext.h>
00022 #include <mythversion.h>
00023 #include <mythplugin.h>
00024 #include <mythcoreutil.h>
00025 #include <mythmiscutil.h>
00026 #include <myththemedmenu.h>
00027 #include <mythuihelper.h>
00028 #include <mythdialogbox.h>
00029 
00030 // mytharchive
00031 #include "archivesettings.h"
00032 #include "logviewer.h"
00033 #include "fileselector.h"
00034 #include "recordingselector.h"
00035 #include "videoselector.h"
00036 #include "dbcheck.h"
00037 #include "archiveutil.h"
00038 #include "selectdestination.h"
00039 #include "exportnative.h"
00040 #include "importnative.h"
00041 #include "mythburn.h"
00042 
00043 // return true if the process belonging to the lock file is still running
00044 static bool checkProcess(const QString &lockFile)
00045 {
00046     // read the PID from the lock file
00047     QFile file(lockFile);
00048 
00049     bool bOK = file.open(QIODevice::ReadOnly);
00050 
00051     if (!bOK)
00052     {
00053         LOG(VB_GENERAL, LOG_ERR,
00054             QString("Unable to open file %1").arg(lockFile));
00055 
00056         return true;
00057     }
00058 
00059     QString line(file.readLine(100));
00060 
00061     pid_t pid = line.toInt(&bOK);
00062 
00063     if (!bOK)
00064     {
00065         LOG(VB_GENERAL, LOG_ERR,
00066             QString("Got bad PID '%1' from lock file").arg(pid));
00067         return true;
00068     }
00069 
00070     LOG(VB_GENERAL, LOG_NOTICE,
00071         QString("Checking if PID %1 is still running").arg(pid));
00072 
00073     if (kill(pid, 0) == -1)
00074     {
00075         if (errno == ESRCH)
00076             return false;
00077     }
00078 
00079     return true;
00080 }
00081 
00082 // return true if a lock file is found and the owning process is still running
00083 static bool checkLockFile(const QString &lockFile)
00084 {
00085     QFile file(lockFile);
00086 
00087     //is a job already running?
00088     if (file.exists())
00089     {
00090         // Is the process that created the lock still alive?
00091         if (!checkProcess(lockFile))
00092         {
00093             showWarningDialog(QObject::tr("Found a lock file but the owning process isn't running!\n"
00094                                           "Removing stale lock file."));
00095             if (!file.remove())
00096                 LOG(VB_GENERAL, LOG_ERR,
00097                     QString("Failed to remove stale lock file - %1")
00098                         .arg(lockFile));
00099         }
00100         else
00101         {
00102             return true;
00103         }
00104     }
00105 
00106     return false;
00107 }
00108 
00109 static void runCreateDVD(void)
00110 {
00111     QString commandline;
00112     QString tempDir = getTempDirectory(true);
00113     MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00114 
00115     if (tempDir == "")
00116         return;
00117 
00118     QString logDir = tempDir + "logs";
00119     QString configDir = tempDir + "config";
00120     QString workDir = tempDir + "work";
00121 
00122     checkTempDirectory();
00123 
00124     if (checkLockFile(logDir + "/mythburn.lck"))
00125     {
00126         // a job is already running so just show the log viewer
00127         showLogViewer();
00128         return;
00129     }
00130 
00131     // show the select destination dialog
00132     SelectDestination *dest = new SelectDestination(mainStack, false, "SelectDestination");
00133 
00134     if (dest->Create())
00135         mainStack->AddScreen(dest);
00136 }
00137 
00138 static void runCreateArchive(void)
00139 {
00140     QString commandline;
00141     QString tempDir = getTempDirectory(true);
00142     MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00143 
00144     if (tempDir == "")
00145         return;
00146 
00147     QString logDir = tempDir + "logs";
00148     QString configDir = tempDir + "config";
00149     QString workDir = tempDir + "work";
00150 
00151     checkTempDirectory();
00152 
00153     if (checkLockFile(logDir + "/mythburn.lck"))
00154     {
00155         // a job is already running so just show the log viewer
00156         showLogViewer();
00157         return;
00158     }
00159 
00160     // show the select destination dialog
00161     SelectDestination *dest = new SelectDestination(mainStack, true, "SelectDestination");
00162 
00163     if (dest->Create())
00164         mainStack->AddScreen(dest);
00165 }
00166 
00167 static void runEncodeVideo(void)
00168 {
00169 
00170 }
00171 
00172 static void runImportVideo(void)
00173 {
00174     QString tempDir = getTempDirectory(true);
00175 
00176     if (tempDir == "")
00177         return;
00178 
00179     QString logDir = tempDir + "logs";
00180     QString configDir = tempDir + "config";
00181     QString workDir = tempDir + "work";
00182 
00183     checkTempDirectory();
00184 
00185     if (checkLockFile(logDir + "/mythburn.lck"))
00186     {
00187         // a job is already running so just show the log viewer
00188         showLogViewer();
00189         return;
00190     }
00191 
00192     QString filter = "*.xml";
00193 
00194     // show the find archive screen
00195     MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00196     ArchiveFileSelector *selector = new ArchiveFileSelector(mainStack);
00197 
00198     if (selector->Create())
00199         mainStack->AddScreen(selector);
00200 }
00201 
00202 static void runShowLog(void)
00203 {
00204     showLogViewer();
00205 }
00206 
00207 static void runTestDVD(void)
00208 {
00209     if (!gCoreContext->GetSetting("MythArchiveLastRunType").startsWith("DVD"))
00210     {
00211         showWarningDialog(QObject::tr("Last run did not create a playable DVD."));
00212         return;
00213     }
00214 
00215     if (!gCoreContext->GetSetting("MythArchiveLastRunStatus").startsWith("Success"))
00216     {
00217         showWarningDialog(QObject::tr("Last run failed to create a DVD."));
00218         return;
00219     }
00220 
00221     QString tempDir = getTempDirectory(true);
00222 
00223     if (tempDir == "")
00224         return;
00225 
00226     QString filename = tempDir + "work/dvd";
00227     QString command = gCoreContext->GetSetting("MythArchiveDVDPlayerCmd", "");
00228 
00229     if ((command.indexOf("internal", 0, Qt::CaseInsensitive) > -1) ||
00230          (command.length() < 1))
00231     {
00232         filename = QString("dvd:/") + filename;
00233         command = "Internal";
00234         GetMythMainWindow()->HandleMedia(command, filename);
00235         return;
00236     }
00237     else
00238     {
00239         if (command.contains("%f"))
00240             command = command.replace(QRegExp("%f"), filename);
00241         myth_system(command);
00242     }
00243 }
00244 
00245 static void runBurnDVD(void)
00246 {
00247     BurnMenu *menu = new BurnMenu();
00248     menu->start();
00249 }
00250 
00251 static void ArchiveCallback(void *data, QString &selection)
00252 {
00253     (void) data;
00254 
00255     QString sel = selection.toLower();
00256 
00257     if (sel == "archive_create_dvd")
00258         runCreateDVD();
00259     else if (sel == "archive_create_archive")
00260         runCreateArchive();
00261     else if (sel == "archive_encode_video")
00262         runEncodeVideo();
00263     else if (sel == "archive_import_video")
00264         runImportVideo();
00265     else if (sel == "archive_last_log")
00266         runShowLog();
00267     else if (sel == "archive_test_dvd")
00268         runTestDVD();
00269     else if (sel == "archive_burn_dvd")
00270         runBurnDVD();
00271 }
00272 
00273 static int runMenu(QString which_menu)
00274 {
00275     QString themedir = GetMythUI()->GetThemeDir();
00276     MythThemedMenu *diag = new MythThemedMenu(
00277         themedir, which_menu, GetMythMainWindow()->GetMainStack(),
00278         "archive menu");
00279 
00280     diag->setCallback(ArchiveCallback, NULL);
00281     diag->setKillable();
00282 
00283     if (diag->foundTheme())
00284     {
00285         GetMythMainWindow()->GetMainStack()->AddScreen(diag);
00286         return 0;
00287     }
00288     else
00289     {
00290         LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find menu %1 or theme %2")
00291                 .arg(which_menu).arg(themedir));
00292         delete diag;
00293         return -1;
00294     }
00295 }
00296 
00297 static void initKeys(void)
00298 {
00299     REG_KEY("Archive", "TOGGLECUT", QT_TRANSLATE_NOOP("MythControls",
00300         "Toggle use cut list state for selected program"), "C");
00301 
00302     REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Create DVD"),
00303         "", "", runCreateDVD);
00304     REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Create Archive"),
00305         "", "", runCreateArchive);
00306     REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Import Archive"),
00307         "", "", runImportVideo);
00308     REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "View Archive Log"),
00309         "", "", runShowLog);
00310     REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Play Created DVD"),
00311         "", "", runTestDVD);
00312     REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Burn DVD"),
00313         "", "", runBurnDVD);
00314 }
00315 
00316 int mythplugin_init(const char *libversion)
00317 {
00318     if (!gContext->TestPopupVersion("mytharchive", libversion,
00319                                     MYTH_BINARY_VERSION))
00320     {
00321         LOG(VB_GENERAL, LOG_ERR, "Test Popup Version Failed");
00322         return -1;
00323     }
00324 
00325     gCoreContext->ActivateSettingsCache(false);
00326     if (!UpgradeArchiveDatabaseSchema())
00327     {
00328         LOG(VB_GENERAL, LOG_ERR,
00329             "Couldn't upgrade database to new schema, exiting.");
00330         return -1;
00331     }
00332     gCoreContext->ActivateSettingsCache(true);
00333 
00334     ArchiveSettings settings;
00335     settings.Load();
00336     settings.Save();
00337 
00338     initKeys();
00339 
00340     return 0;
00341 }
00342 
00343 int mythplugin_run(void)
00344 {
00345     return runMenu("archivemenu.xml");
00346 }
00347 
00348 int mythplugin_config(void)
00349 {
00350     ArchiveSettings settings;
00351     settings.exec();
00352 
00353     return 0;
00354 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends