00001
00002
00003 #include <sys/wait.h>
00004 #include <unistd.h>
00005
00006
00007 #include <cstdlib>
00008
00009
00010 #include <iostream>
00011
00012
00013 #include <qdir.h>
00014 #include <qdom.h>
00015
00016
00017 #include <mythtv/mythcontext.h>
00018 #include <libmythtv/programinfo.h>
00019 #include <mythtv/dialogbox.h>
00020
00021
00022 #include "archiveutil.h"
00023
00024
00025 struct ArchiveDestination ArchiveDestinations[] =
00026 {
00027 {AD_DVD_SL, "Single Layer DVD", "Single Layer DVD (4482Mb)", 4482*1024},
00028 {AD_DVD_DL, "Dual Layer DVD", "Dual Layer DVD (8964Mb)", 8964*1024},
00029 {AD_DVD_RW, "DVD +/- RW", "Rewritable DVD", 4482*1024},
00030 {AD_FILE, "File", "Any file accessable from "
00031 "your filesystem.", -1},
00032 };
00033
00034 int ArchiveDestinationsCount = sizeof(ArchiveDestinations) / sizeof(ArchiveDestinations[0]);
00035
00036 QString formatSize(long long sizeKB, int prec)
00037 {
00038 if (sizeKB>1024*1024*1024)
00039 {
00040 double sizeGB = sizeKB/(1024*1024*1024.0);
00041 return QString("%1 TB").arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec);
00042 }
00043 else if (sizeKB>1024*1024)
00044 {
00045 double sizeGB = sizeKB/(1024*1024.0);
00046 return QString("%1 GB").arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec);
00047 }
00048 else if (sizeKB>1024)
00049 {
00050 double sizeMB = sizeKB/1024.0;
00051 return QString("%1 MB").arg(sizeMB, 0, 'f', (sizeMB>10)?0:prec);
00052 }
00053
00054 return QString("%1 KB").arg(sizeKB);
00055 }
00056
00057 QString getTempDirectory(bool showError)
00058 {
00059 QString tempDir = gContext->GetSetting("MythArchiveTempDir", "");
00060
00061 if (tempDir == "" && showError)
00062 MythPopupBox::showOkPopup(gContext->GetMainWindow(),
00063 QObject::tr("Myth Archive"),
00064 QObject::tr("Cannot find the MythArchive work directory.\n"
00065 "Have you set the correct path in the settings?"));
00066
00067 if (tempDir == "")
00068 return "";
00069
00070
00071 if (!tempDir.endsWith("/"))
00072 {
00073 tempDir += "/";
00074 gContext->SaveSetting("MythArchiveTempDir", tempDir);
00075 }
00076
00077 return tempDir;
00078 }
00079
00080 void checkTempDirectory()
00081 {
00082 QString tempDir = getTempDirectory();
00083 QString logDir = tempDir + "logs";
00084 QString configDir = tempDir + "config";
00085 QString workDir = tempDir + "work";
00086
00087
00088 QDir dir(tempDir);
00089 if (!dir.exists())
00090 {
00091 dir.mkdir(tempDir);
00092 system("chmod 777 " + tempDir);
00093 }
00094
00095 dir = QDir(workDir);
00096 if (!dir.exists())
00097 {
00098 dir.mkdir(workDir);
00099 system("chmod 777 " + workDir);
00100 }
00101
00102 dir = QDir(logDir);
00103 if (!dir.exists())
00104 {
00105 dir.mkdir(logDir);
00106 system("chmod 777 " + logDir);
00107 }
00108 dir = QDir(configDir);
00109 if (!dir.exists())
00110 {
00111 dir.mkdir(configDir);
00112 system("chmod 777 " + configDir);
00113 }
00114 }
00115
00116 QString getBaseName(const QString &filename)
00117 {
00118 QString baseName = filename;
00119 int pos = filename.findRev('/');
00120 if (pos > 0)
00121 baseName = filename.mid(pos + 1);
00122
00123 return baseName;
00124 }
00125
00126 bool extractDetailsFromFilename(const QString &inFile,
00127 QString &chanID, QString &startTime)
00128 {
00129 VERBOSE(VB_JOBQUEUE, "Extracting details from: " + inFile);
00130
00131 QString baseName = getBaseName(inFile);
00132
00133 MSqlQuery query(MSqlQuery::InitCon());
00134 query.prepare("SELECT chanid, starttime FROM recorded "
00135 "WHERE basename = :BASENAME");
00136 query.bindValue(":BASENAME", baseName);
00137
00138 query.exec();
00139 if (query.isActive() && query.numRowsAffected())
00140 {
00141 query.first();
00142 chanID = query.value(0).toString();
00143 startTime= query.value(1).toString();
00144 }
00145 else
00146 {
00147 VERBOSE(VB_JOBQUEUE,
00148 QString("Cannot find details for %1").arg(inFile));
00149 return false;
00150 }
00151
00152 VERBOSE(VB_JOBQUEUE, QString("chanid: %1 starttime:%2 ").arg(chanID).arg(startTime));
00153
00154 return true;
00155 }
00156
00157 ProgramInfo *getProgramInfoForFile(const QString &inFile)
00158 {
00159 ProgramInfo *pinfo = NULL;
00160 QString chanID, startTime;
00161 bool bIsMythRecording = false;
00162
00163 bIsMythRecording = extractDetailsFromFilename(inFile, chanID, startTime);
00164
00165 if (bIsMythRecording)
00166 {
00167 pinfo = ProgramInfo::GetProgramFromRecorded(chanID, startTime);
00168
00169 if (pinfo)
00170 pinfo->pathname = pinfo->GetPlaybackURL(false, true);
00171 }
00172
00173 if (!pinfo)
00174 {
00175
00176 pinfo = new ProgramInfo();
00177 pinfo->pathname = inFile;
00178 pinfo->isVideo = true;
00179 VERBOSE(VB_JOBQUEUE, "File is not a Myth recording.");
00180 }
00181 else
00182 VERBOSE(VB_JOBQUEUE, "File is a Myth recording.");
00183
00184 return pinfo;
00185 }
00186
00187 bool getFileDetails(ArchiveItem *a)
00188 {
00189 QString tempDir = gContext->GetSetting("MythArchiveTempDir", "");
00190
00191 if (!tempDir.endsWith("/"))
00192 tempDir += "/";
00193
00194 QString inFile;
00195 int lenMethod = 0;
00196 if (a->type == "Recording")
00197 {
00198 inFile = a->filename;
00199 lenMethod = 2;
00200 }
00201 else
00202 {
00203 inFile = a->filename;
00204 }
00205
00206 inFile.replace("\'", "\\\'");
00207 inFile.replace("\"", "\\\"");
00208 inFile.replace("`", "\\`");
00209
00210 QString outFile = tempDir + "/work/file.xml";
00211
00212
00213 QString command = QString("mytharchivehelper -i \"%1\" \"%2\" %3 > /dev/null 2>&1")
00214 .arg(inFile).arg(outFile).arg(lenMethod);
00215
00216 int res = system(command);
00217 if (WIFEXITED(res))
00218 res = WEXITSTATUS(res);
00219 if (res != 0)
00220 return false;
00221
00222 QDomDocument doc("mydocument");
00223 QFile file(outFile);
00224 if (!file.open(IO_ReadOnly))
00225 return false;
00226
00227 if (!doc.setContent( &file ))
00228 {
00229 file.close();
00230 return false;
00231 }
00232 file.close();
00233
00234
00235 QDomElement docElem = doc.documentElement();
00236 QDomNodeList nodeList = doc.elementsByTagName("file");
00237 if (nodeList.count() < 1)
00238 return false;
00239 QDomNode n = nodeList.item(0);
00240 QDomElement e = n.toElement();
00241 a->fileCodec = e.attribute("type");
00242 a->duration = e.attribute("duration").toInt();
00243 a->cutDuration = e.attribute("cutduration").toInt();
00244
00245
00246 nodeList = doc.elementsByTagName("video");
00247 if (nodeList.count() < 1)
00248 return false;
00249 n = nodeList.item(0);
00250 e = n.toElement();
00251 a->videoCodec = e.attribute("codec");
00252 a->videoWidth = e.attribute("width").toInt();
00253 a->videoHeight = e.attribute("height").toInt();
00254
00255 return true;
00256 }
00257
00258 void showWarningDialog(const QString msg)
00259 {
00260 DialogBox *dialog = new DialogBox(gContext->GetMainWindow(), msg);
00261 dialog->AddButton(QObject::tr("OK"));
00262 dialog->exec();
00263 dialog->deleteLater();
00264 }
00265
00266