|
MythTV
0.26-pre
|
00001 // -*- Mode: c++ -*- 00002 00003 // Qt headers 00004 #include <QRegExp> 00005 00006 // MythTV headers 00007 #include "sourceutil.h" 00008 #include "cardutil.h" 00009 #include "mythdb.h" 00010 #include "mythdirs.h" 00011 #include "mythlogging.h" 00012 #include "mythmiscutil.h" 00013 00014 bool SourceUtil::HasDigitalChannel(uint sourceid) 00015 { 00016 MSqlQuery query(MSqlQuery::InitCon()); 00017 00018 query.prepare( 00019 "SELECT mplexid, atsc_minor_chan, serviceid " 00020 "FROM channel " 00021 "WHERE sourceid = :SOURCEID"); 00022 query.bindValue(":SOURCEID", sourceid); 00023 00024 if (!query.exec()) 00025 { 00026 MythDB::DBError("SourceUtil::HasDigitalChannel()", query); 00027 return false; 00028 } 00029 00030 while (query.next()) 00031 { 00032 uint mplexid = query.value(0).toUInt(); 00033 uint minor = query.value(1).toUInt(); 00034 uint prognum = query.value(2).toUInt(); 00035 mplexid = (32767 == mplexid) ? 0 : mplexid; 00036 00037 if (mplexid && (minor || prognum)) 00038 return true; 00039 } 00040 00041 return false; 00042 } 00043 00044 QString SourceUtil::GetSourceName(uint sourceid) 00045 { 00046 MSqlQuery query(MSqlQuery::InitCon()); 00047 00048 query.prepare( 00049 "SELECT name " 00050 "FROM videosource " 00051 "WHERE sourceid = :SOURCEID"); 00052 query.bindValue(":SOURCEID", sourceid); 00053 00054 if (!query.exec()) 00055 { 00056 MythDB::DBError("SourceUtil::GetSourceName()", query); 00057 return QString::null; 00058 } 00059 else if (!query.next()) 00060 { 00061 return QString::null; 00062 } 00063 00064 return query.value(0).toString(); 00065 } 00066 00067 QString SourceUtil::GetChannelSeparator(uint sourceid) 00068 { 00069 MSqlQuery query(MSqlQuery::InitCon()); 00070 query.prepare("SELECT channum " 00071 "FROM channel " 00072 "WHERE sourceid = :SOURCEID"); 00073 query.bindValue(":SOURCEID", sourceid); 00074 00075 if (query.exec() && query.isActive() && query.size() > 0) 00076 { 00077 QMap<QString,uint> counts; 00078 const QRegExp sepExpr("(_|-|#|\\.)"); 00079 while (query.next()) 00080 { 00081 const QString channum = query.value(0).toString(); 00082 const int where = channum.indexOf(sepExpr); 00083 if (channum.right(2).left(1) == "0") 00084 counts["0"]++; 00085 else 00086 counts[(where < 0) ? "" : QString(channum.at(where))]++; 00087 } 00088 QString sep = "_"; 00089 uint max = counts["_"]; 00090 static const char *spacers[6] = { "", "-", "#", ".", "0", NULL }; 00091 for (uint i=0; (spacers[i] != NULL); ++i) 00092 { 00093 if (counts[spacers[i]] > max) 00094 { 00095 max = counts[spacers[i]]; 00096 sep = spacers[i]; 00097 } 00098 } 00099 return sep; 00100 } 00101 return "_"; // default on failure 00102 } 00103 00104 QString SourceUtil::GetChannelFormat(uint sourceid) 00105 { 00106 return QString("%1") + GetChannelSeparator(sourceid) + QString("%2"); 00107 } 00108 00109 uint SourceUtil::GetChannelCount(uint sourceid) 00110 { 00111 MSqlQuery query(MSqlQuery::InitCon()); 00112 query.prepare("SELECT sum(1) " 00113 "FROM channel " 00114 "WHERE sourceid = :SOURCEID"); 00115 query.bindValue(":SOURCEID", sourceid); 00116 if (query.exec() && query.isActive() && query.next()) 00117 return query.value(0).toUInt(); 00118 return 0; 00119 } 00120 00121 vector<uint> SourceUtil::GetMplexIDs(uint sourceid) 00122 { 00123 MSqlQuery query(MSqlQuery::InitCon()); 00124 00125 query.prepare( 00126 "SELECT mplexid " 00127 "FROM dtv_multiplex " 00128 "WHERE sourceid = :SOURCEID"); 00129 query.bindValue(":SOURCEID", sourceid); 00130 00131 vector<uint> list; 00132 if (!query.exec()) 00133 { 00134 MythDB::DBError("SourceUtil::GetMplexIDs()", query); 00135 return list; 00136 } 00137 00138 while (query.next()) 00139 list.push_back(query.value(0).toUInt()); 00140 00141 return list; 00142 } 00143 00144 bool SourceUtil::GetListingsLoginData(uint sourceid, 00145 QString &grabber, QString &userid, 00146 QString &passwd, QString &lineupid) 00147 { 00148 MSqlQuery query(MSqlQuery::InitCon()); 00149 query.prepare( 00150 "SELECT xmltvgrabber, userid, password, lineupid " 00151 "FROM videosource " 00152 "WHERE sourceid = :SOURCEID"); 00153 query.bindValue(":SOURCEID", sourceid); 00154 00155 if (!query.exec() || !query.isActive()) 00156 { 00157 MythDB::DBError("SourceUtil::GetListingsLoginData()", query); 00158 return false; 00159 } 00160 00161 if (!query.next()) 00162 return false; 00163 00164 grabber = query.value(0).toString(); 00165 userid = query.value(1).toString(); 00166 passwd = query.value(2).toString(); 00167 lineupid = query.value(3).toString(); 00168 00169 return true; 00170 } 00171 00172 static QStringList get_cardtypes(uint sourceid) 00173 { 00174 QStringList list; 00175 00176 MSqlQuery query(MSqlQuery::InitCon()); 00177 query.prepare( 00178 "SELECT cardtype, inputname " 00179 "FROM capturecard, cardinput " 00180 "WHERE capturecard.cardid = cardinput.cardid AND " 00181 " cardinput.sourceid = :SOURCEID"); 00182 query.bindValue(":SOURCEID", sourceid); 00183 00184 if (!query.exec() || !query.isActive()) 00185 MythDB::DBError("get_cardtypes()", query); 00186 else 00187 { 00188 while (query.next()) 00189 { 00191 QString cardtype = query.value(0).toString().toUpper(); 00192 QString inputname = query.value(1).toString().toUpper(); 00193 cardtype = ((cardtype == "DVB") && (inputname.left(3) != "DVB")) ? 00194 "V4L" : cardtype; 00196 list += cardtype; 00197 } 00198 } 00199 00200 return list; 00201 } 00202 00203 uint SourceUtil::GetConnectionCount(uint sourceid) 00204 { 00205 QStringList types = get_cardtypes(sourceid); 00206 return types.size(); 00207 } 00208 00209 bool SourceUtil::IsProperlyConnected(uint sourceid, bool strict) 00210 { 00211 QStringList types = get_cardtypes(sourceid); 00212 QMap<QString,uint> counts; 00213 QStringList::const_iterator it = types.begin(); 00214 for (; it != types.end(); ++it) 00215 { 00216 counts[*it]++; 00217 00218 counts[CardUtil::IsEncoder(*it) ? "ENCODER" : "NOT_ENCODER"]++; 00219 counts[CardUtil::IsUnscanable(*it) ? "NO_SCAN" : "SCAN"]++; 00220 00221 if (CardUtil::IsTuningAnalog(*it)) 00222 counts["ANALOG_TUNING"]++; 00223 else if (CardUtil::IsTuningDigital(*it)) 00224 counts["DIGITAL_TUNING"]++; 00225 else if (CardUtil::IsTuningVirtual(*it)) 00226 counts["VIRTUAL_TUNING"]++; 00227 } 00228 00229 bool tune_mismatch = 00230 (counts["ANALOG_TUNING"] && counts["DIGITAL_TUNING"]) || 00231 (counts["VIRTUAL_TUNING"] && counts["DIGITAL_TUNING"]); 00232 bool enc_mismatch = counts["ENCODER"] && counts["NOT_ENCODER"]; 00233 bool scan_mismatch = counts["SCAN"] && counts["NO_SCAN"]; 00234 00235 if (tune_mismatch) 00236 { 00237 uint a = counts["ANALOG_TUNERS"]; 00238 uint d = counts["DIGITAL_TUNERS"]; 00239 uint v = counts["VIRTUAL_TUNERS"]; 00240 LOG(VB_GENERAL, LOG_NOTICE, 00241 QString("SourceUtil::IsProperlyConnected(): ") + 00242 QString("Connected to %1 analog, %2 digital and %3 virtual " 00243 "tuners\n\t\t\t").arg(a).arg(d).arg(v) + 00244 QString("Can not mix digital with other tuning information.")); 00245 } 00246 00247 if (enc_mismatch) 00248 { 00249 uint a = counts["ENCODER"]; 00250 uint d = counts["NOT_ENCODER"]; 00251 LOG(VB_GENERAL, LOG_NOTICE, 00252 QString("SourceUtil::IsProperlyConnected(): ") + 00253 QString("Source ID %1 ").arg(sourceid) + 00254 QString("appears to be connected\n\t\t\tto %1 encoder%2, ") 00255 .arg(a).arg((1 == a) ? "":"s") + 00256 QString("and %1 non-encoder%2. ") 00257 .arg(d).arg((1 == d) ? "":"s") + 00258 QString("This is probably a bad idea.")); 00259 } 00260 00261 if (scan_mismatch) 00262 { 00263 uint a = counts["SCAN"]; 00264 uint d = counts["NO_SCAN"]; 00265 LOG(VB_GENERAL, LOG_NOTICE, 00266 QString("SourceUtil::IsProperlyConnected(): ") + 00267 QString("Source ID %1 ").arg(sourceid) + 00268 QString("appears to be connected\n\t\t\t" 00269 "to %1 scanable input%2, ") 00270 .arg(a).arg((1 == a) ? "":"s") + 00271 QString("and %1 non-scanable input%2. ") 00272 .arg(d).arg((1 == d) ? "":"s") + 00273 QString("This may be a problem.")); 00274 } 00275 00276 if (!strict) 00277 return !tune_mismatch; 00278 00279 return !tune_mismatch && !enc_mismatch && !scan_mismatch; 00280 } 00281 00282 bool SourceUtil::IsEncoder(uint sourceid, bool strict) 00283 { 00284 bool encoder = true; 00285 00286 QStringList types = get_cardtypes(sourceid); 00287 QStringList::const_iterator it = types.begin(); 00288 for (; it != types.end(); ++it) 00289 encoder &= CardUtil::IsEncoder(*it); 00290 00291 // Source is connected, go by card types for type determination 00292 if (!types.empty()) 00293 return encoder; 00294 00295 // Try looking at channels if source is not connected, 00296 MSqlQuery query(MSqlQuery::InitCon()); 00297 query.prepare( 00298 "SELECT atsc_minor_chan, serviceid " 00299 "FROM channel " 00300 "WHERE sourceid = :SOURCEID"); 00301 query.bindValue(":SOURCEID", sourceid); 00302 00303 bool has_any_chan = false; 00304 if (!query.exec() || !query.isActive()) 00305 MythDB::DBError("SourceUtil::IsEncoder", query); 00306 else 00307 { 00308 while (query.next()) 00309 { 00310 encoder &= !query.value(0).toInt() && !query.value(1).toInt(); 00311 has_any_chan = true; 00312 } 00313 } 00314 00315 return (strict && !has_any_chan) ? false: encoder; 00316 } 00317 00318 bool SourceUtil::IsUnscanable(uint sourceid) 00319 { 00320 bool unscanable = true; 00321 QStringList types = get_cardtypes(sourceid); 00322 QStringList::const_iterator it = types.begin(); 00323 for (; it != types.end(); ++it) 00324 unscanable &= CardUtil::IsUnscanable(*it); 00325 00326 return types.empty() || unscanable; 00327 } 00328 00329 bool SourceUtil::IsCableCardPresent(uint sourceid) 00330 { 00331 bool ccpresent = false; 00332 vector<uint> cards = CardUtil::GetCardIDs(sourceid); 00333 vector<uint>::iterator it = cards.begin(); 00334 for (; it != cards.end(); ++it) 00335 { 00336 if (CardUtil::IsCableCardPresent(*it, CardUtil::GetRawCardType(*it))) 00337 ccpresent = true; 00338 } 00339 00340 return ccpresent; 00341 } 00342 00343 bool SourceUtil::IsAnySourceScanable(void) 00344 { 00345 MSqlQuery query(MSqlQuery::InitCon()); 00346 query.prepare("SELECT sourceid FROM videosource"); 00347 00348 if (!query.exec() || !query.isActive()) 00349 { 00350 MythDB::DBError("SourceUtil::IsAnySourceScanable", query); 00351 return false; 00352 } 00353 00354 while (query.next()) 00355 { 00356 if (!IsUnscanable(query.value(0).toUInt())) 00357 return true; 00358 } 00359 00360 return false; 00361 } 00362 00363 bool SourceUtil::UpdateChannelsFromListings(uint sourceid, QString cardtype, bool wait) 00364 { 00365 if (wait) 00366 { 00367 QString cmd = GetInstallPrefix() + 00368 "/bin/mythfilldatabase"; 00369 QStringList args; 00370 args.append("--only-update-channels"); 00371 00372 if (sourceid) 00373 { 00374 args.append(QString("--sourceid")); 00375 args.append(QString::number(sourceid)); 00376 } 00377 if (!cardtype.isEmpty()) 00378 { 00379 args.append(QString("--cardtype")); 00380 args.append(cardtype); 00381 } 00382 00383 MythSystem getchan(cmd, args, kMSRunShell | kMSAutoCleanup ); 00384 getchan.Run(); 00385 getchan.Wait(); 00386 } 00387 else 00388 { 00389 QString cmd = GetInstallPrefix() + 00390 "/bin/mythfilldatabase --only-update-channels"; 00391 if (sourceid) 00392 cmd += QString(" --sourceid %1").arg(sourceid); 00393 if (!cardtype.isEmpty()) 00394 cmd += QString(" --cardtype %1").arg(cardtype); 00395 cmd += logPropagateArgs; 00396 00397 myth_system(cmd); 00398 } 00399 00400 return true; 00401 } 00402 00403 bool SourceUtil::UpdateSource( uint sourceid, QString sourcename, 00404 QString grabber, QString userid, 00405 QString freqtable, QString lineupid, 00406 QString password, bool useeit, 00407 QString configpath, int nitid) 00408 { 00409 MSqlQuery query(MSqlQuery::InitCon()); 00410 00411 query.prepare("UPDATE videosource SET name = :NAME, xmltvgrabber = :XMLTVGRABBER, " 00412 "userid = :USERID, freqtable = :FREQTABLE, lineupid = :LINEUPID," 00413 "password = :PASSWORD, useeit = :USEEIT, configpath = :CONFIGPATH, " 00414 "dvb_nit_id = :NITID WHERE sourceid = :SOURCEID"); 00415 00416 query.bindValue(":NAME", sourcename); 00417 query.bindValue(":XMLTVGRABBER", grabber); 00418 query.bindValue(":USERID", userid); 00419 query.bindValue(":FREQTABLE", freqtable); 00420 query.bindValue(":LINEUPID", lineupid); 00421 query.bindValue(":PASSWORD", password); 00422 query.bindValue(":USEEIT", useeit); 00423 query.bindValue(":CONFIGPATH", configpath); 00424 query.bindValue(":NITID", nitid); 00425 query.bindValue(":SOURCEID", sourceid); 00426 00427 if (!query.exec() || !query.isActive()) 00428 { 00429 MythDB::DBError("Updating Video Source", query); 00430 return false; 00431 } 00432 00433 return true; 00434 } 00435 00436 int SourceUtil::CreateSource( QString sourcename, 00437 QString grabber, QString userid, 00438 QString freqtable, QString lineupid, 00439 QString password, bool useeit, 00440 QString configpath, int nitid) 00441 { 00442 MSqlQuery query(MSqlQuery::InitCon()); 00443 00444 query.prepare("INSERT INTO videosource (name,xmltvgrabber,userid,freqtable,lineupid," 00445 "password,useeit,configpath,dvb_nit_id) VALUES (:NAME, :XMLTVGRABBER, " 00446 ":USERID, :FREQTABLE, :LINEUPID, :PASSWORD, :USEEIT, :CONFIGPATH, :NITID)"); 00447 00448 query.bindValue(":NAME", sourcename); 00449 query.bindValue(":XMLTVGRABBER", grabber); 00450 query.bindValue(":USERID", userid); 00451 query.bindValue(":FREQTABLE", freqtable); 00452 query.bindValue(":LINEUPID", lineupid); 00453 query.bindValue(":PASSWORD", password); 00454 query.bindValue(":USEEIT", useeit); 00455 query.bindValue(":CONFIGPATH", configpath); 00456 query.bindValue(":NITID", nitid); 00457 00458 if (!query.exec() || !query.isActive()) 00459 { 00460 MythDB::DBError("Adding Video Source", query); 00461 return -1; 00462 } 00463 00464 query.prepare("SELECT MAX(sourceid) FROM videosource"); 00465 00466 if (!query.exec()) 00467 { 00468 MythDB::DBError("CreateSource maxsource", query); 00469 return -1; 00470 } 00471 00472 uint sourceid = -1; 00473 00474 if (query.next()) 00475 sourceid = query.value(0).toUInt(); 00476 00477 return sourceid; 00478 } 00479 00480 bool SourceUtil::DeleteSource(uint sourceid) 00481 { 00482 MSqlQuery query(MSqlQuery::InitCon()); 00483 00484 // Delete the channels associated with the source 00485 query.prepare("DELETE FROM channel " 00486 "WHERE sourceid = :SOURCEID"); 00487 query.bindValue(":SOURCEID", sourceid); 00488 00489 if (!query.exec() || !query.isActive()) 00490 { 00491 MythDB::DBError("Deleting Channels", query); 00492 return false; 00493 } 00494 00495 // Delete the multiplexes associated with the source 00496 query.prepare("DELETE FROM dtv_multiplex " 00497 "WHERE sourceid = :SOURCEID"); 00498 query.bindValue(":SOURCEID", sourceid); 00499 00500 if (!query.exec() || !query.isActive()) 00501 { 00502 MythDB::DBError("Deleting Multiplexes", query); 00503 return false; 00504 } 00505 00506 // Delete the inputs associated with the source 00507 query.prepare("DELETE FROM cardinput " 00508 "WHERE sourceid = :SOURCEID"); 00509 query.bindValue(":SOURCEID", sourceid); 00510 00511 if (!query.exec() || !query.isActive()) 00512 { 00513 MythDB::DBError("Deleting cardinputs", query); 00514 return false; 00515 } 00516 00517 // Delete the source itself 00518 query.prepare("DELETE FROM videosource " 00519 "WHERE sourceid = :SOURCEID"); 00520 query.bindValue(":SOURCEID", sourceid); 00521 00522 if (!query.exec() || !query.isActive()) 00523 { 00524 MythDB::DBError("Deleting VideoSource", query); 00525 return false; 00526 } 00527 00528 // Delete any orphaned inputs & unused input groups 00529 CardUtil::DeleteOrphanInputs(); 00530 CardUtil::UnlinkInputGroup(0,0); 00531 00532 return true; 00533 } 00534 00535 bool SourceUtil::DeleteAllSources(void) 00536 { 00537 MSqlQuery query(MSqlQuery::InitCon()); 00538 return (query.exec("TRUNCATE TABLE channel") && 00539 query.exec("TRUNCATE TABLE program") && 00540 query.exec("TRUNCATE TABLE videosource") && 00541 query.exec("TRUNCATE TABLE credits") && 00542 query.exec("TRUNCATE TABLE programrating") && 00543 query.exec("TRUNCATE TABLE programgenres") && 00544 query.exec("TRUNCATE TABLE dtv_multiplex") && 00545 query.exec("TRUNCATE TABLE inputgroup") && 00546 query.exec("TRUNCATE TABLE diseqc_config") && 00547 query.exec("TRUNCATE TABLE diseqc_tree") && 00548 query.exec("TRUNCATE TABLE eit_cache") && 00549 query.exec("TRUNCATE TABLE channelgroup") && 00550 query.exec("TRUNCATE TABLE channelgroupnames") && 00551 query.exec("TRUNCATE TABLE cardinput")); 00552 }
1.7.6.1