|
MythTV
0.26-pre
|
00001 // C headers 00002 #include <unistd.h> 00003 00004 // C++ headers 00005 #include <iostream> 00006 using namespace std; 00007 00008 // Qt headers 00009 #include <QCoreApplication> 00010 #include <QFileInfo> 00011 00012 // libmyth headers 00013 #include "exitcodes.h" 00014 #include "mythcontext.h" 00015 #include "mythdb.h" 00016 #include "mythversion.h" 00017 #include "mythmiscutil.h" 00018 #include "mythtranslation.h" 00019 00020 #include "mythconfig.h" 00021 00022 // libmythtv headers 00023 #include "commandlineparser.h" 00024 #include "scheduledrecording.h" 00025 #include "remoteutil.h" 00026 #include "videosource.h" // for is_grabber.. 00027 #include "dbcheck.h" 00028 #include "mythsystemevent.h" 00029 #include "mythlogging.h" 00030 00031 // filldata headers 00032 #include "filldata.h" 00033 namespace 00034 { 00035 void cleanup() 00036 { 00037 delete gContext; 00038 gContext = NULL; 00039 00040 } 00041 00042 class CleanupGuard 00043 { 00044 public: 00045 typedef void (*CleanupFunc)(); 00046 00047 public: 00048 CleanupGuard(CleanupFunc cleanFunction) : 00049 m_cleanFunction(cleanFunction) {} 00050 00051 ~CleanupGuard() 00052 { 00053 m_cleanFunction(); 00054 } 00055 00056 private: 00057 CleanupFunc m_cleanFunction; 00058 }; 00059 } 00060 00061 int main(int argc, char *argv[]) 00062 { 00063 FillData fill_data; 00064 int fromfile_id = 1; 00065 int fromfile_offset = 0; 00066 QString fromfile_name; 00067 bool from_xawfile = false; 00068 int fromxawfile_id = 1; 00069 QString fromxawfile_name; 00070 bool from_file = false; 00071 bool mark_repeats = true; 00072 00073 bool usingDataDirect = false; 00074 bool grab_data = true; 00075 00076 bool export_iconmap = false; 00077 bool import_iconmap = false; 00078 bool reset_iconmap = false; 00079 bool reset_iconmap_icons = false; 00080 QString import_icon_data_filename("iconmap.xml"); 00081 QString export_icon_data_filename("iconmap.xml"); 00082 00083 bool update_icon_data = false; 00084 00085 bool from_dd_file = false; 00086 int sourceid = -1; 00087 QString fromddfile_lineupid; 00088 00089 MythFillDatabaseCommandLineParser cmdline; 00090 if (!cmdline.Parse(argc, argv)) 00091 { 00092 cmdline.PrintHelp(); 00093 return GENERIC_EXIT_INVALID_CMDLINE; 00094 } 00095 00096 if (cmdline.toBool("showhelp")) 00097 { 00098 cmdline.PrintHelp(); 00099 return GENERIC_EXIT_OK; 00100 } 00101 00102 if (cmdline.toBool("showversion")) 00103 { 00104 cmdline.PrintVersion(); 00105 return GENERIC_EXIT_OK; 00106 } 00107 00108 QCoreApplication a(argc, argv); 00109 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHFILLDATABASE); 00110 00111 myth_nice(19); 00112 00113 int retval; 00114 if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK) 00115 return retval; 00116 00117 if (cmdline.toBool("manual")) 00118 { 00119 cout << "###\n"; 00120 cout << "### Running in manual channel configuration mode.\n"; 00121 cout << "### This will ask you questions about every channel.\n"; 00122 cout << "###\n"; 00123 fill_data.chan_data.interactive = true; 00124 } 00125 00126 if (cmdline.toBool("update")) 00127 { 00128 if (cmdline.toBool("manual")) 00129 { 00130 cerr << "--update and --manual cannot be used simultaneously" 00131 << endl; 00132 return GENERIC_EXIT_INVALID_CMDLINE; 00133 } 00134 fill_data.chan_data.non_us_updating = true; 00135 } 00136 00137 if (cmdline.toBool("preset")) 00138 { 00139 cout << "###\n"; 00140 cout << "### Running in preset channel configuration mode.\n"; 00141 cout << "### This will assign channel "; 00142 cout << "preset numbers to every channel.\n"; 00143 cout << "###\n"; 00144 fill_data.chan_data.channel_preset = true; 00145 } 00146 00147 if (cmdline.toBool("file")) 00148 { 00149 // manual file mode 00150 if (!cmdline.toBool("sourceid") || 00151 !cmdline.toBool("xmlfile")) 00152 { 00153 cerr << "The --file option must be used in combination" << endl 00154 << "with both --sourceid and --xmlfile." << endl; 00155 return GENERIC_EXIT_INVALID_CMDLINE; 00156 } 00157 00158 fromfile_id = cmdline.toInt("sourceid"); 00159 fromfile_name = cmdline.toString("xmlfile"); 00160 00161 LOG(VB_GENERAL, LOG_INFO, 00162 "Bypassing grabbers, reading directly from file"); 00163 from_file = true; 00164 } 00165 00166 if (cmdline.toBool("ddfile")) 00167 { 00168 // datadirect file mode 00169 if (!cmdline.toBool("sourceid") || 00170 !cmdline.toBool("offset") || 00171 !cmdline.toBool("lineupid") || 00172 !cmdline.toBool("xmlfile")) 00173 { 00174 cerr << "The --dd-file option must be used in combination" << endl 00175 << "with each of --sourceid, --offset, --lineupid," << endl 00176 << "and --xmlfile." << endl; 00177 return GENERIC_EXIT_INVALID_CMDLINE; 00178 } 00179 00180 fromfile_id = cmdline.toInt("sourceid"); 00181 fromfile_offset = cmdline.toInt("offset"); 00182 fromddfile_lineupid = cmdline.toInt("lineupid"); 00183 fromfile_name = cmdline.toString("xmlfile"); 00184 00185 LOG(VB_GENERAL, LOG_INFO, 00186 "Bypassing grabbers, reading directly from file"); 00187 from_dd_file = true; 00188 } 00189 00190 if (cmdline.toBool("xawchannels")) 00191 { 00192 // xaw channel import mode 00193 if (!cmdline.toBool("sourceid") || 00194 !cmdline.toBool("xawtvrcfile")) 00195 { 00196 cerr << "The --xawchannels option must be used in combination" 00197 << endl 00198 << "with both --sourceid and --xawtvrcfile" << endl; 00199 } 00200 00201 fromxawfile_id = cmdline.toInt("sourceid"); 00202 fromxawfile_name = cmdline.toString("xawtvrcfile"); 00203 00204 LOG(VB_GENERAL, LOG_INFO, "Reading channels from xawtv configfile"); 00205 from_xawfile = true; 00206 } 00207 00208 if (cmdline.toBool("dochannelupdates")) 00209 fill_data.chan_data.channel_updates = true; 00210 if (cmdline.toBool("removechannels")) 00211 fill_data.chan_data.remove_new_channels = true; 00212 if (cmdline.toBool("nofilterchannels")) 00213 fill_data.chan_data.filter_new_channels = false; 00214 if (!cmdline.GetPassthrough().isEmpty()) 00215 fill_data.graboptions = " " + cmdline.GetPassthrough(); 00216 if (cmdline.toBool("sourceid")) 00217 sourceid = cmdline.toInt("sourceid"); 00218 if (cmdline.toBool("cardtype")) 00219 { 00220 if (!cmdline.toBool("sourceid")) 00221 { 00222 cerr << "The --cardtype option must be used in combination" << endl 00223 << "with a --sourceid option." << endl; 00224 return GENERIC_EXIT_INVALID_CMDLINE; 00225 } 00226 00227 fill_data.chan_data.cardtype = cmdline.toString("cardtype") 00228 .trimmed().toUpper(); 00229 } 00230 if (cmdline.toBool("maxdays") && cmdline.toInt("maxdays") > 0) 00231 { 00232 fill_data.maxDays = cmdline.toInt("maxdays"); 00233 if (fill_data.maxDays == 1) 00234 fill_data.SetRefresh(0, true); 00235 } 00236 00237 if (cmdline.toBool("refreshtoday")) 00238 cmdline.SetValue("refresh", 00239 cmdline.toStringList("refresh") << "today"); 00240 if (cmdline.toBool("dontrefreshtomorrow")) 00241 cmdline.SetValue("refresh", 00242 cmdline.toStringList("refresh") << "nottomorrow"); 00243 if (cmdline.toBool("refreshsecond")) 00244 cmdline.SetValue("refresh", 00245 cmdline.toStringList("refresh") << "second"); 00246 if (cmdline.toBool("refreshall")) 00247 cmdline.SetValue("refresh", 00248 cmdline.toStringList("refresh") << "all"); 00249 if (cmdline.toBool("refreshday")) 00250 cmdline.SetValue("refresh", 00251 cmdline.toStringList("refresh") << 00252 cmdline.toStringList("refreshday")); 00253 00254 QStringList sl = cmdline.toStringList("refresh"); 00255 if (!sl.isEmpty()) 00256 { 00257 QStringList::const_iterator i = sl.constBegin(); 00258 for (; i != sl.constEnd(); ++i) 00259 { 00260 QString warn = QString("Invalid entry in --refresh list: %1") 00261 .arg(*i); 00262 00263 bool enable = (*i).contains("not") ? false : true; 00264 00265 if ((*i).contains("today")) 00266 fill_data.SetRefresh(0, enable); 00267 else if ((*i).contains("tomorrow")) 00268 fill_data.SetRefresh(1, enable); 00269 else if ((*i).contains("second")) 00270 fill_data.SetRefresh(2, enable); 00271 else if ((*i).contains("all")) 00272 fill_data.SetRefresh(FillData::kRefreshAll, enable); 00273 else if ((*i).contains("-")) 00274 { 00275 bool ok; 00276 QStringList r = (*i).split("-"); 00277 00278 uint lower = r[0].toUInt(&ok); 00279 if (!ok) 00280 { 00281 cerr << warn.toLocal8Bit().constData() << endl; 00282 return false; 00283 } 00284 00285 uint upper = r[1].toUInt(&ok); 00286 if (!ok) 00287 { 00288 cerr << warn.toLocal8Bit().constData() << endl; 00289 return false; 00290 } 00291 00292 if (lower > upper) 00293 { 00294 cerr << warn.toLocal8Bit().constData() << endl; 00295 return false; 00296 } 00297 00298 for (uint j = lower; j <= upper; ++j) 00299 fill_data.SetRefresh(j, true); 00300 } 00301 else 00302 { 00303 bool ok; 00304 uint day = (*i).toUInt(&ok); 00305 if (!ok) 00306 { 00307 cerr << warn.toLocal8Bit().constData() << endl; 00308 return false; 00309 } 00310 00311 fill_data.SetRefresh(day, true); 00312 } 00313 } 00314 } 00315 00316 if (cmdline.toBool("dontrefreshtba")) 00317 fill_data.refresh_tba = false; 00318 if (cmdline.toBool("ddgraball")) 00319 { 00320 fill_data.SetRefresh(FillData::kRefreshClear, false); 00321 fill_data.dd_grab_all = true; 00322 } 00323 if (cmdline.toBool("onlychannels")) 00324 fill_data.only_update_channels = true; 00325 00326 mark_repeats = cmdline.toBool("markrepeats"); 00327 if (cmdline.toBool("exporticonmap")) 00328 export_icon_data_filename = cmdline.toString("exporticonmap"); 00329 if (cmdline.toBool("importiconmap")) 00330 import_icon_data_filename = cmdline.toString("importiconmap"); 00331 if (cmdline.toBool("updateiconmap")) 00332 { 00333 update_icon_data = true; 00334 grab_data = false; 00335 } 00336 if (cmdline.toBool("reseticonmap")) 00337 { 00338 reset_iconmap = true; 00339 grab_data = false; 00340 if (cmdline.toString("reseticonmap") == "all") 00341 reset_iconmap_icons = true; 00342 } 00343 00344 CleanupGuard callCleanup(cleanup); 00345 00346 gContext = new MythContext(MYTH_BINARY_VERSION); 00347 if (!gContext->Init(false)) 00348 { 00349 LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext, exiting."); 00350 return GENERIC_EXIT_NO_MYTHCONTEXT; 00351 } 00352 00353 setHttpProxy(); 00354 00355 MythTranslation::load("mythfrontend"); 00356 00357 if (!UpgradeTVDatabaseSchema(false)) 00358 { 00359 LOG(VB_GENERAL, LOG_ERR, "Incorrect database schema"); 00360 return GENERIC_EXIT_DB_OUTOFDATE; 00361 } 00362 00363 if (!grab_data) 00364 { 00365 } 00366 else if (from_xawfile) 00367 { 00368 fill_data.readXawtvChannels(fromxawfile_id, fromxawfile_name); 00369 } 00370 else if (from_file) 00371 { 00372 QString status = QObject::tr("currently running."); 00373 QDateTime GuideDataBefore, GuideDataAfter; 00374 00375 MSqlQuery query(MSqlQuery::InitCon()); 00376 updateLastRunStart(query); 00377 updateLastRunStatus(query, status); 00378 00379 query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c " 00380 "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID " 00381 "AND manualid = 0 AND c.xmltvid != '';"); 00382 query.bindValue(":SRCID", fromfile_id); 00383 00384 if (query.exec() && query.next()) 00385 { 00386 if (!query.isNull(0)) 00387 GuideDataBefore = 00388 QDateTime::fromString(query.value(0).toString(), 00389 Qt::ISODate); 00390 } 00391 00392 if (!fill_data.GrabDataFromFile(fromfile_id, fromfile_name)) 00393 { 00394 return GENERIC_EXIT_NOT_OK; 00395 } 00396 00397 updateLastRunEnd(query); 00398 00399 query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c " 00400 "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID " 00401 "AND manualid = 0 AND c.xmltvid != '';"); 00402 query.bindValue(":SRCID", fromfile_id); 00403 00404 if (query.exec() && query.next()) 00405 { 00406 if (!query.isNull(0)) 00407 GuideDataAfter = 00408 QDateTime::fromString(query.value(0).toString(), 00409 Qt::ISODate); 00410 } 00411 00412 if (GuideDataAfter == GuideDataBefore) 00413 status = QObject::tr("mythfilldatabase ran, but did not insert " 00414 "any new data into the Guide. This can indicate a " 00415 "potential problem with the XML file used for the update."); 00416 else 00417 status = QObject::tr("Successful."); 00418 00419 updateLastRunStatus(query, status); 00420 } 00421 else if (from_dd_file) 00422 { 00423 fill_data.GrabDataFromDDFile( 00424 fromfile_id, fromfile_offset, fromfile_name, fromddfile_lineupid); 00425 } 00426 else 00427 { 00428 SourceList sourcelist; 00429 00430 MSqlQuery sourcequery(MSqlQuery::InitCon()); 00431 QString where = ""; 00432 00433 if (sourceid != -1) 00434 { 00435 LOG(VB_GENERAL, LOG_INFO, 00436 QString("Running for sourceid %1 ONLY because --sourceid " 00437 "was given on command-line").arg(sourceid)); 00438 where = QString("WHERE sourceid = %1").arg(sourceid); 00439 } 00440 00441 QString querystr = QString("SELECT sourceid,name,xmltvgrabber,userid," 00442 "password,lineupid " 00443 "FROM videosource ") + where + 00444 QString(" ORDER BY sourceid;"); 00445 00446 if (sourcequery.exec(querystr)) 00447 { 00448 if (sourcequery.size() > 0) 00449 { 00450 while (sourcequery.next()) 00451 { 00452 Source newsource; 00453 00454 newsource.id = sourcequery.value(0).toInt(); 00455 newsource.name = sourcequery.value(1).toString(); 00456 newsource.xmltvgrabber = sourcequery.value(2).toString(); 00457 newsource.userid = sourcequery.value(3).toString(); 00458 newsource.password = sourcequery.value(4).toString(); 00459 newsource.lineupid = sourcequery.value(5).toString(); 00460 00461 newsource.xmltvgrabber_baseline = false; 00462 newsource.xmltvgrabber_manualconfig = false; 00463 newsource.xmltvgrabber_cache = false; 00464 newsource.xmltvgrabber_prefmethod = ""; 00465 00466 sourcelist.push_back(newsource); 00467 usingDataDirect |= 00468 is_grabber_datadirect(newsource.xmltvgrabber); 00469 } 00470 } 00471 else 00472 { 00473 LOG(VB_GENERAL, LOG_ERR, 00474 "There are no channel sources defined, did you run " 00475 "the setup program?"); 00476 return GENERIC_EXIT_SETUP_ERROR; 00477 } 00478 } 00479 else 00480 { 00481 MythDB::DBError("loading channel sources", sourcequery); 00482 return GENERIC_EXIT_DB_ERROR; 00483 } 00484 00485 if (!fill_data.Run(sourcelist)) 00486 LOG(VB_GENERAL, LOG_ERR, "Failed to fetch some program info"); 00487 else 00488 LOG(VB_GENERAL, LOG_NOTICE, "Data fetching complete."); 00489 } 00490 00491 if (fill_data.only_update_channels && !fill_data.need_post_grab_proc) 00492 { 00493 return GENERIC_EXIT_OK; 00494 } 00495 00496 if (reset_iconmap) 00497 { 00498 fill_data.icon_data.ResetIconMap(reset_iconmap_icons); 00499 } 00500 00501 if (import_iconmap) 00502 { 00503 fill_data.icon_data.ImportIconMap(import_icon_data_filename); 00504 } 00505 00506 if (export_iconmap) 00507 { 00508 fill_data.icon_data.ExportIconMap(export_icon_data_filename); 00509 } 00510 00511 if (update_icon_data) 00512 { 00513 MSqlQuery query(MSqlQuery::InitCon()); 00514 query.prepare("SELECT sourceid FROM videosource ORDER BY sourceid"); 00515 if (!query.exec()) 00516 { 00517 MythDB::DBError("Querying sources", query); 00518 return GENERIC_EXIT_DB_ERROR; 00519 } 00520 00521 while (query.next()) 00522 fill_data.icon_data.UpdateSourceIcons(query.value(0).toInt()); 00523 } 00524 00525 if (grab_data) 00526 { 00527 LOG(VB_GENERAL, LOG_INFO, "Adjusting program database end times."); 00528 int update_count = ProgramData::fix_end_times(); 00529 if (update_count == -1) 00530 LOG(VB_GENERAL, LOG_ERR, "fix_end_times failed!"); 00531 else 00532 LOG(VB_GENERAL, LOG_INFO, 00533 QString(" %1 replacements made").arg(update_count)); 00534 } 00535 00536 if (grab_data) 00537 { 00538 LOG(VB_GENERAL, LOG_INFO, "Marking generic episodes."); 00539 00540 MSqlQuery query(MSqlQuery::InitCon()); 00541 query.prepare("UPDATE program SET generic = 1 WHERE " 00542 "((programid = '' AND subtitle = '' AND description = '') OR " 00543 " (programid <> '' AND category_type = 'series' AND " 00544 " program.programid LIKE '%0000'));"); 00545 00546 if (!query.exec()) 00547 MythDB::DBError("mark generic", query); 00548 else 00549 LOG(VB_GENERAL, LOG_INFO, 00550 QString(" Found %1").arg(query.numRowsAffected())); 00551 } 00552 00553 if (grab_data) 00554 { 00555 LOG(VB_GENERAL, LOG_INFO, "Extending non-unique programids " 00556 "with multiple parts."); 00557 00558 int found = 0; 00559 MSqlQuery sel(MSqlQuery::InitCon()); 00560 sel.prepare("SELECT DISTINCT programid, partnumber, parttotal " 00561 "FROM program WHERE partnumber > 0 AND parttotal > 0 AND " 00562 "programid LIKE '%0000'"); 00563 if (sel.exec()) 00564 { 00565 MSqlQuery repl(MSqlQuery::InitCon()); 00566 repl.prepare("UPDATE program SET programid = :NEWID " 00567 "WHERE programid = :OLDID AND " 00568 "partnumber = :PARTNUM AND " 00569 "parttotal = :PARTTOTAL"); 00570 00571 while (sel.next()) 00572 { 00573 QString orig_programid = sel.value(0).toString(); 00574 QString new_programid = orig_programid.left(10); 00575 int partnum, parttotal; 00576 QString part; 00577 00578 partnum = sel.value(1).toInt(); 00579 parttotal = sel.value(2).toInt(); 00580 00581 part.setNum(parttotal); 00582 new_programid.append(part.rightJustified(2, '0')); 00583 part.setNum(partnum); 00584 new_programid.append(part.rightJustified(2, '0')); 00585 00586 LOG(VB_GENERAL, LOG_INFO, 00587 QString(" %1 -> %2 (part %3 of %4)") 00588 .arg(orig_programid).arg(new_programid) 00589 .arg(partnum).arg(parttotal)); 00590 00591 repl.bindValue(":NEWID", new_programid); 00592 repl.bindValue(":OLDID", orig_programid); 00593 repl.bindValue(":PARTNUM", partnum); 00594 repl.bindValue(":PARTTOTAL", parttotal); 00595 if (!repl.exec()) 00596 { 00597 LOG(VB_GENERAL, LOG_INFO, 00598 QString("Fudging programid from '%1' to '%2'") 00599 .arg(orig_programid) 00600 .arg(new_programid)); 00601 } 00602 else 00603 found += repl.numRowsAffected(); 00604 } 00605 } 00606 00607 LOG(VB_GENERAL, LOG_INFO, QString(" Found %1").arg(found)); 00608 } 00609 00610 if (mark_repeats) 00611 { 00612 LOG(VB_GENERAL, LOG_INFO, "Marking repeats."); 00613 00614 int newEpiWindow = gCoreContext->GetNumSetting( "NewEpisodeWindow", 14); 00615 00616 MSqlQuery query(MSqlQuery::InitCon()); 00617 query.prepare("UPDATE program SET previouslyshown = 1 " 00618 "WHERE previouslyshown = 0 " 00619 "AND originalairdate is not null " 00620 "AND (to_days(starttime) - to_days(originalairdate)) " 00621 " > :NEWWINDOW;"); 00622 query.bindValue(":NEWWINDOW", newEpiWindow); 00623 00624 if (query.exec()) 00625 LOG(VB_GENERAL, LOG_INFO, 00626 QString(" Found %1").arg(query.numRowsAffected())); 00627 00628 LOG(VB_GENERAL, LOG_INFO, "Unmarking new episode rebroadcast repeats."); 00629 query.prepare("UPDATE program SET previouslyshown = 0 " 00630 "WHERE previouslyshown = 1 " 00631 "AND originalairdate is not null " 00632 "AND (to_days(starttime) - to_days(originalairdate)) " 00633 " <= :NEWWINDOW;"); 00634 query.bindValue(":NEWWINDOW", newEpiWindow); 00635 00636 if (query.exec()) 00637 LOG(VB_GENERAL, LOG_INFO, 00638 QString(" Found %1").arg(query.numRowsAffected())); 00639 } 00640 00641 // Mark first and last showings 00642 00643 if (grab_data) 00644 { 00645 MSqlQuery updt(MSqlQuery::InitCon()); 00646 updt.prepare("UPDATE program SET first = 0, last = 0;"); 00647 if (!updt.exec()) 00648 MythDB::DBError("Clearing first and last showings", updt); 00649 00650 LOG(VB_GENERAL, LOG_INFO, "Marking episode first showings."); 00651 updt.prepare("UPDATE program " 00652 "JOIN (SELECT MIN(starttime) AS starttime, programid " 00653 " FROM program " 00654 " WHERE programid <> '' " 00655 " GROUP BY programid " 00656 " ) AS firsts " 00657 "ON program.programid = firsts.programid " 00658 " AND program.starttime = firsts.starttime " 00659 "SET program.first=1;"); 00660 if (!updt.exec()) 00661 MythDB::DBError("Marking first showings by id", updt); 00662 int found = updt.numRowsAffected(); 00663 00664 updt.prepare("UPDATE program " 00665 "JOIN (SELECT MIN(starttime) AS starttime, title, subtitle," 00666 " LEFT(description, 1024) AS partdesc " 00667 " FROM program " 00668 " WHERE programid = '' " 00669 " GROUP BY title, subtitle, partdesc " 00670 " ) AS firsts " 00671 "ON program.starttime = firsts.starttime " 00672 " AND program.title = firsts.title " 00673 " AND program.subtitle = firsts.subtitle " 00674 " AND LEFT(program.description, 1024) = firsts.partdesc " 00675 "SET program.first = 1 " 00676 "WHERE program.programid = '';"); 00677 if (!updt.exec()) 00678 MythDB::DBError("Marking first showings", updt); 00679 found += updt.numRowsAffected(); 00680 LOG(VB_GENERAL, LOG_INFO, QString(" Found %1").arg(found)); 00681 00682 LOG(VB_GENERAL, LOG_INFO, "Marking episode last showings."); 00683 updt.prepare("UPDATE program " 00684 "JOIN (SELECT MAX(starttime) AS starttime, programid " 00685 " FROM program " 00686 " WHERE programid <> '' " 00687 " GROUP BY programid " 00688 " ) AS lasts " 00689 "ON program.programid = lasts.programid " 00690 " AND program.starttime = lasts.starttime " 00691 "SET program.last=1;"); 00692 if (!updt.exec()) 00693 MythDB::DBError("Marking last showings by id", updt); 00694 found = updt.numRowsAffected(); 00695 00696 updt.prepare("UPDATE program " 00697 "JOIN (SELECT MAX(starttime) AS starttime, title, subtitle," 00698 " LEFT(description, 1024) AS partdesc " 00699 " FROM program " 00700 " WHERE programid = '' " 00701 " GROUP BY title, subtitle, partdesc " 00702 " ) AS lasts " 00703 "ON program.starttime = lasts.starttime " 00704 " AND program.title = lasts.title " 00705 " AND program.subtitle = lasts.subtitle " 00706 " AND LEFT(program.description, 1024) = lasts.partdesc " 00707 "SET program.last = 1 " 00708 "WHERE program.programid = '';"); 00709 if (!updt.exec()) 00710 MythDB::DBError("Marking last showings", updt); 00711 found += updt.numRowsAffected(); 00712 LOG(VB_GENERAL, LOG_INFO, QString(" Found %1").arg(found)); 00713 } 00714 00715 if (1) // limit MSqlQuery's lifetime 00716 { 00717 MSqlQuery query(MSqlQuery::InitCon()); 00718 query.prepare("SELECT count(previouslyshown) " 00719 "FROM program WHERE previouslyshown = 1;"); 00720 if (query.exec() && query.next()) 00721 { 00722 if (query.value(0).toInt() != 0) 00723 gCoreContext->SaveSettingOnHost("HaveRepeats", "1", NULL); 00724 else 00725 gCoreContext->SaveSettingOnHost("HaveRepeats", "0", NULL); 00726 } 00727 } 00728 00729 if ((usingDataDirect) && 00730 (gCoreContext->GetNumSetting("MythFillGrabberSuggestsTime", 1))) 00731 { 00732 fill_data.ddprocessor.GrabNextSuggestedTime(); 00733 } 00734 00735 LOG(VB_GENERAL, LOG_INFO, "\n" 00736 "===============================================================\n" 00737 "| Attempting to contact the master backend for rescheduling. |\n" 00738 "| If the master is not running, rescheduling will happen when |\n" 00739 "| the master backend is restarted. |\n" 00740 "==============================================================="); 00741 00742 if (grab_data || mark_repeats) 00743 ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(), 00744 "MythFillDatabase"); 00745 00746 gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE"); 00747 00748 gCoreContext->SendSystemEvent("MYTHFILLDATABASE_RAN"); 00749 00750 LOG(VB_GENERAL, LOG_NOTICE, "mythfilldatabase run complete."); 00751 00752 return GENERIC_EXIT_OK; 00753 } 00754 00755 /* vim: set expandtab tabstop=4 shiftwidth=4: */
1.7.6.1