|
MythTV
0.26-pre
|
00001 // checksetup.cpp 00002 // 00003 // Some functions to do simple sanity checks on the MythTV setup. 00004 // CheckSetup() is currently meant for the mythtv-setup program, 00005 // but the other functions could probably be called from anywhere. 00006 // They all return true if any problems are found, and add to a 00007 // caller-supplied QString a message describing the problem. 00008 00009 #include <QDir> 00010 00011 #include "mythdb.h" 00012 #include "mythcorecontext.h" 00013 #include "mythmiscutil.h" 00014 #include "checksetup.h" 00015 00017 00018 static bool checkPath(QString path, QStringList &probs) 00019 { 00020 QDir dir(path); 00021 if (!dir.exists()) 00022 { 00023 probs.push_back(QObject::tr("Path \"%1\" doesn't exist.").arg(path)); 00024 return true; 00025 } 00026 00027 QFile test(path.append("/.test")); 00028 if (test.open(QIODevice::WriteOnly)) 00029 test.remove(); 00030 else 00031 { 00032 probs.push_back(QObject::tr("Unable to create file \"%1\" - directory " 00033 "is not writable?").arg(path)); 00034 return true; 00035 } 00036 00037 return false; 00038 } 00039 00042 00043 bool checkStoragePaths(QStringList &probs) 00044 { 00045 bool problemFound = false; 00046 00047 QString recordFilePrefix = 00048 gCoreContext->GetSetting("RecordFilePrefix", "EMPTY"); 00049 00050 MSqlQuery query(MSqlQuery::InitCon()); 00051 00052 query.prepare("SELECT count(groupname) FROM storagegroup;"); 00053 if (!query.exec() || !query.isActive() || query.size() < 1) 00054 { 00055 MythDB::DBError("checkStoragePaths", query); 00056 return false; 00057 } 00058 00059 query.next(); 00060 if (query.value(0).toInt() == 0) 00061 { 00062 QString trMesg = 00063 QObject::tr("No Storage Group directories are defined. You " 00064 "must add at least one directory to the Default " 00065 "Storage Group where new recordings will be " 00066 "stored."); 00067 probs.push_back(trMesg); 00068 LOG(VB_GENERAL, LOG_ERR, trMesg); 00069 return true; 00070 } 00071 00072 query.prepare("SELECT groupname, dirname " 00073 "FROM storagegroup " 00074 "WHERE hostname = :HOSTNAME;"); 00075 query.bindValue(":HOSTNAME", gCoreContext->GetHostName()); 00076 if (!query.exec() || !query.isActive()) 00077 { 00078 MythDB::DBError("checkStoragePaths", query); 00079 return false; 00080 } 00081 else if (query.size() < 1) 00082 { 00083 if (gCoreContext->IsMasterHost()) 00084 { 00085 // Master backend must have a defined Default SG 00086 QString trMesg = 00087 QObject::tr("No Storage Group directories are defined. " 00088 "You must add at least one directory to the " 00089 "Default Storage Group where new recordings " 00090 "will be stored."); 00091 probs.push_back(trMesg); 00092 LOG(VB_GENERAL, LOG_ERR, trMesg); 00093 return true; 00094 } 00095 else 00096 return false; 00097 } 00098 00099 QDir checkDir(""); 00100 QString dirname; 00101 while (query.next()) 00102 { 00103 /* The storagegroup.dirname column uses utf8_bin collation, so Qt 00104 * uses QString::fromAscii() for toString(). Explicitly convert the 00105 * value using QString::fromUtf8() to prevent corruption. */ 00106 dirname = QString::fromUtf8(query.value(1) 00107 .toByteArray().constData()); 00108 QStringList tokens = dirname.split(","); 00109 int curToken = 0; 00110 while (curToken < tokens.size()) 00111 { 00112 checkDir.setPath(tokens[curToken]); 00113 if (checkPath(tokens[curToken], probs)) 00114 { 00115 problemFound = true; 00116 } 00117 curToken++; 00118 } 00119 } 00120 00121 return problemFound; 00122 } 00123 00124 bool checkImageStoragePaths(QStringList &probs) 00125 { 00126 bool problemFound = false; 00127 00128 MSqlQuery query(MSqlQuery::InitCon()); 00129 00130 query.prepare("SELECT groupname " 00131 "FROM storagegroup " 00132 "WHERE hostname = :HOSTNAME;"); 00133 query.bindValue(":HOSTNAME", gCoreContext->GetHostName()); 00134 if (!query.exec() || !query.isActive()) 00135 { 00136 MythDB::DBError("checkImageStoragePaths", query); 00137 return false; 00138 } 00139 else if (query.size() < 1) 00140 { 00141 return false; 00142 } 00143 00144 QStringList groups; 00145 while (query.next()) 00146 { 00147 groups += query.value(0).toString(); 00148 } 00149 00150 if (groups.contains("Videos")) 00151 { 00152 if (groups.contains("Fanart") && 00153 groups.contains("Coverart") && 00154 groups.contains("Screenshots") && 00155 groups.contains("Banners")) 00156 problemFound = false; 00157 else 00158 { 00159 QString trMesg = 00160 QObject::tr("You have a Video Storage " 00161 "Group, but have not set up " 00162 "all Image Groups. If you continue, " 00163 "video image downloads will be saved in " 00164 "your Videos Storage Group. Do you want " 00165 "to store them in their own groups?"); 00166 probs.push_back(trMesg); 00167 LOG(VB_GENERAL, LOG_ERR, trMesg); 00168 problemFound = true; 00169 } 00170 } 00171 00172 return problemFound; 00173 } 00174 00175 // I keep forgetting to change the preset (starting channel) when I add cards, 00176 // so this checks that the assigned channel (which may be the default of 3) 00177 // actually exists. This should save a few beginner Live TV problems 00178 00179 bool checkChannelPresets(QStringList &probs) 00180 { 00181 bool problemFound = false; 00182 00183 MSqlQuery query(MSqlQuery::InitCon()); 00184 00185 query.prepare("SELECT cardid, startchan, sourceid, inputname" 00186 " FROM cardinput;"); 00187 00188 if (!query.exec() || !query.isActive()) 00189 { 00190 MythDB::DBError("checkChannelPresets", query); 00191 return false; 00192 } 00193 00194 while (query.next()) 00195 { 00196 int cardid = query.value(0).toInt(); 00197 QString startchan = query.value(1).toString(); 00198 int sourceid = query.value(2).toInt(); 00199 00200 if (query.value(1).toString().isEmpty()) // Logic from tv_rec.cpp 00201 startchan = "3"; 00202 00203 MSqlQuery channelExists(MSqlQuery::InitCon()); 00204 QString channelQuery; 00205 channelQuery = QString("SELECT chanid FROM channel" 00206 " WHERE channum='%1' AND sourceid=%2;") 00207 .arg(startchan).arg(sourceid); 00208 channelExists.prepare(channelQuery); 00209 00210 if (!channelExists.exec() || !channelExists.isActive()) 00211 { 00212 MythDB::DBError("checkChannelPresets", channelExists); 00213 return problemFound; 00214 } 00215 00216 if (channelExists.size() == 0) 00217 { 00218 probs.push_back(QObject::tr("Card %1 (type %2) is set to start on " 00219 "channel %3, which does not exist.") 00220 .arg(cardid).arg(query.value(3).toString()).arg(startchan)); 00221 problemFound = true; 00222 } 00223 } 00224 00225 return problemFound; 00226 } 00227 00230 00231 bool CheckSetup(QStringList &problems) 00232 { 00233 return checkStoragePaths(problems) 00234 || checkChannelPresets(problems) 00235 || checkImageStoragePaths(problems); 00236 } 00237 00238 bool needsMFDBReminder() 00239 { 00240 bool needsReminder = false; 00241 MSqlQuery query(MSqlQuery::InitCon()); 00242 00243 query.prepare("SELECT sourceid " 00244 "FROM videosource " 00245 "WHERE xmltvgrabber = 'schedulesdirect1' " 00246 "OR xmltvgrabber = 'datadirect' " 00247 "OR xmltvgrabber LIKE 'tv_grab_%';"); 00248 if (!query.exec() || !query.isActive()) 00249 { 00250 MythDB::DBError("needsMFDBReminder", query); 00251 } 00252 else if (query.size() >= 1) 00253 { 00254 needsReminder = true; 00255 } 00256 00257 return needsReminder; 00258 } 00259 00260 /* vim: set expandtab tabstop=4 shiftwidth=4: */
1.7.6.1