00001
00002 #include <unistd.h>
00003
00004
00005 #include <iostream>
00006 #include <cstdlib>
00007 using namespace std;
00008
00009
00010 #include <qapplication.h>
00011
00012
00013 #include "exitcodes.h"
00014 #include "mythcontext.h"
00015 #include "mythdbcon.h"
00016
00017
00018 #include "scheduledrecording.h"
00019 #include "remoteutil.h"
00020 #include "videosource.h"
00021
00022
00023 #include "filldata.h"
00024
00025 int main(int argc, char *argv[])
00026 {
00027 QApplication a(argc, argv, false);
00028 FillData fill_data;
00029 int argpos = 1;
00030 int fromfile_id = 1;
00031 int fromfile_offset = 0;
00032 QString fromfile_name;
00033 bool from_xawfile = false;
00034 int fromxawfile_id = 1;
00035 QString fromxawfile_name;
00036 bool from_file = false;
00037 bool mark_repeats = true;
00038
00039 bool usingDataDirect = false, usingDataDirectLabs = false;
00040 bool grab_data = true;
00041
00042 bool export_iconmap = false;
00043 bool import_iconmap = false;
00044 bool reset_iconmap = false;
00045 bool reset_iconmap_icons = false;
00046 QString import_icon_data_filename("iconmap.xml");
00047 QString export_icon_data_filename("iconmap.xml");
00048
00049 bool update_icon_data = false;
00050
00051 bool from_dd_file = false;
00052 int sourceid = -1;
00053 QString fromddfile_lineupid;
00054
00055 while (argpos < a.argc())
00056 {
00057
00058 if (!strcmp(a.argv()[argpos], "--manual"))
00059 {
00060 cout << "###\n";
00061 cout << "### Running in manual channel configuration mode.\n";
00062 cout << "### This will ask you questions about every channel.\n";
00063 cout << "###\n";
00064 fill_data.chan_data.interactive = true;
00065 }
00066 else if (!strcmp(a.argv()[argpos], "--preset"))
00067 {
00068
00069 cout << "###\n";
00070 cout << "### Running in preset channel configuration mode.\n";
00071 cout << "### This will assign channel ";
00072 cout << "preset numbers to every channel.\n";
00073 cout << "###\n";
00074 fill_data.chan_data.channel_preset = true;
00075 }
00076 else if (!strcmp(a.argv()[argpos], "--update"))
00077 {
00078
00079
00080 fill_data.chan_data.non_us_updating = true;
00081 }
00082 else if (!strcmp(a.argv()[argpos], "--file"))
00083 {
00084 if (((argpos + 2) >= a.argc()) ||
00085 !strncmp(a.argv()[argpos + 1], "--", 2) ||
00086 !strncmp(a.argv()[argpos + 2], "--", 2))
00087 {
00088 printf("missing or invalid parameters for --file option\n");
00089 return FILLDB_EXIT_INVALID_CMDLINE;
00090 }
00091
00092 if (!fromfile_name.isEmpty())
00093 {
00094 printf("only one --file option allowed\n");
00095 return FILLDB_EXIT_INVALID_CMDLINE;
00096 }
00097
00098 fromfile_id = atoi(a.argv()[++argpos]);
00099 fromfile_name = a.argv()[++argpos];
00100
00101 VERBOSE(VB_GENERAL, "Bypassing grabbers, reading directly from file");
00102 from_file = true;
00103 }
00104 else if (!strcmp(a.argv()[argpos], "--dd-file"))
00105 {
00106 if (((argpos + 4) >= a.argc()) ||
00107 !strncmp(a.argv()[argpos + 1], "--", 2) ||
00108 !strncmp(a.argv()[argpos + 2], "--", 2) ||
00109 !strncmp(a.argv()[argpos + 3], "--", 2) ||
00110 !strncmp(a.argv()[argpos + 4], "--", 2))
00111 {
00112 printf("missing or invalid parameters for --dd-file option\n");
00113 return FILLDB_EXIT_INVALID_CMDLINE;
00114 }
00115
00116 if (!fromfile_name.isEmpty())
00117 {
00118 printf("only one --dd-file option allowed\n");
00119 return FILLDB_EXIT_INVALID_CMDLINE;
00120 }
00121
00122 fromfile_id = atoi(a.argv()[++argpos]);
00123 fromfile_offset = atoi(a.argv()[++argpos]);
00124 fromddfile_lineupid = a.argv()[++argpos];
00125 fromfile_name = a.argv()[++argpos];
00126
00127 VERBOSE(VB_GENERAL, "Bypassing grabbers, reading directly from file");
00128 from_dd_file = true;
00129 }
00130 else if (!strcmp(a.argv()[argpos], "--xawchannels"))
00131 {
00132 if (((argpos + 2) >= a.argc()) ||
00133 !strncmp(a.argv()[argpos + 1], "--", 2) ||
00134 !strncmp(a.argv()[argpos + 2], "--", 2))
00135 {
00136 printf("missing or invalid parameters for --xawchannels option\n");
00137 return FILLDB_EXIT_INVALID_CMDLINE;
00138 }
00139
00140 if (!fromxawfile_name.isEmpty())
00141 {
00142 printf("only one --xawchannels option allowed\n");
00143 return FILLDB_EXIT_INVALID_CMDLINE;
00144 }
00145
00146 fromxawfile_id = atoi(a.argv()[++argpos]);
00147 fromxawfile_name = a.argv()[++argpos];
00148
00149 VERBOSE(VB_GENERAL, "Reading channels from xawtv configfile");
00150 from_xawfile = true;
00151 }
00152 else if (!strcmp(a.argv()[argpos], "--do-channel-updates"))
00153 {
00154 fill_data.chan_data.channel_updates = true;
00155 }
00156 else if (!strcmp(a.argv()[argpos], "--remove-new-channels"))
00157 {
00158 fill_data.chan_data.remove_new_channels = true;
00159 }
00160 else if (!strcmp(a.argv()[argpos], "--do-not-filter-new-channels"))
00161 {
00162 fill_data.chan_data.filter_new_channels = false;
00163 }
00164 else if (!strcmp(a.argv()[argpos], "--graboptions"))
00165 {
00166 if (((argpos + 1) >= a.argc()))
00167 {
00168 printf("missing parameter for --graboptions option\n");
00169 return FILLDB_EXIT_INVALID_CMDLINE;
00170 }
00171
00172 fill_data.graboptions = QString(" ") + QString(a.argv()[++argpos]);
00173 }
00174 else if (!strcmp(a.argv()[argpos], "--sourceid"))
00175 {
00176 if (((argpos + 1) >= a.argc()))
00177 {
00178 printf("missing parameter for --sourceid option\n");
00179 return FILLDB_EXIT_INVALID_CMDLINE;
00180 }
00181
00182 sourceid = QString(a.argv()[++argpos]).toInt();
00183 }
00184 else if (!strcmp(a.argv()[argpos], "--cardtype"))
00185 {
00186 if (!sourceid)
00187 {
00188 printf("--cardtype option must follow a --sourceid option\n");
00189 return FILLDB_EXIT_INVALID_CMDLINE;
00190 }
00191
00192 if (((argpos + 1) >= a.argc()))
00193 {
00194 printf("missing parameter for --cardtype option\n");
00195 return FILLDB_EXIT_INVALID_CMDLINE;
00196 }
00197
00198 fill_data.chan_data.cardtype =
00199 QString(a.argv()[++argpos]).stripWhiteSpace().upper();
00200 }
00201 else if (!strcmp(a.argv()[argpos], "--max-days"))
00202 {
00203 if (((argpos + 1) >= a.argc()))
00204 {
00205 printf("missing parameter for --max-days option\n");
00206 return FILLDB_EXIT_INVALID_CMDLINE;
00207 }
00208
00209 fill_data.maxDays = QString(a.argv()[++argpos]).toInt();
00210
00211 if (fill_data.maxDays < 1 || fill_data.maxDays > REFRESH_MAX)
00212 {
00213 printf("ignoring invalid parameter for --max-days\n");
00214 fill_data.maxDays = 0;
00215 }
00216 }
00217 else if (!strcmp(a.argv()[argpos], "--refresh-today"))
00218 {
00219 fill_data.refresh_request[0] = true;
00220 }
00221 else if (!strcmp(a.argv()[argpos], "--dont-refresh-tomorrow"))
00222 {
00223 fill_data.refresh_request[1] = false;
00224 }
00225 else if (!strcmp(a.argv()[argpos], "--refresh-second"))
00226 {
00227 fill_data.refresh_request[2] = true;
00228 }
00229 else if (!strcmp(a.argv()[argpos], "--refresh-all"))
00230 {
00231 for( int i = 0; i < REFRESH_MAX; i++ )
00232 fill_data.refresh_request[i] = true;
00233 }
00234 else if (!strcmp(a.argv()[argpos], "--refresh-day"))
00235 {
00236 if (((argpos + 1) >= a.argc()))
00237 {
00238 printf("missing parameter for --refresh-day option\n");
00239 return FILLDB_EXIT_INVALID_CMDLINE;
00240 }
00241
00242 int day = QString(a.argv()[++argpos]).toInt();
00243
00244 if (day < 0 || day > REFRESH_MAX)
00245 {
00246 printf("ignoring invalid parameter for --refresh-day\n");
00247 }
00248 else
00249 {
00250 fill_data.refresh_request[day] = true;
00251 }
00252 }
00253 else if (!strcmp(a.argv()[argpos], "--dont-refresh-tba"))
00254 {
00255 fill_data.refresh_tba = false;
00256 }
00257 else if (!strcmp(a.argv()[argpos], "--only-update-channels"))
00258 {
00259 fill_data.only_update_channels = true;
00260 }
00261 else if (!strcmp(a.argv()[argpos],"-v") ||
00262 !strcmp(a.argv()[argpos],"--verbose"))
00263 {
00264 if (a.argc()-1 > argpos)
00265 {
00266 if (parse_verbose_arg(a.argv()[argpos+1]) ==
00267 GENERIC_EXIT_INVALID_CMDLINE)
00268 return GENERIC_EXIT_INVALID_CMDLINE;
00269
00270 ++argpos;
00271 }
00272 else
00273 {
00274 cerr << "Missing argument to -v/--verbose option\n";
00275 return GENERIC_EXIT_INVALID_CMDLINE;
00276 }
00277 }
00278 #if 0
00279 else if (!strcmp(a.argv()[argpos], "--dd-grab-all"))
00280 {
00281 fill_data.dd_grab_all = true;
00282 for( int i = 0; i < REFRESH_MAX; i++ )
00283 fill_data.refresh_request[i] = false;
00284 }
00285 #endif
00286 else if (!strcmp(a.argv()[argpos], "--quiet"))
00287 {
00288 print_verbose_messages = VB_NONE;
00289 }
00290 else if (!strcmp(a.argv()[argpos], "--mark-repeats"))
00291 {
00292 mark_repeats = true;
00293 }
00294 else if (!strcmp(a.argv()[argpos], "--nomark-repeats"))
00295 {
00296 mark_repeats = false;
00297 }
00298 else if (!strcmp(a.argv()[argpos], "--export-icon-map"))
00299 {
00300 export_iconmap = true;
00301 grab_data = false;
00302
00303 if ((argpos + 1) >= a.argc() ||
00304 !strncmp(a.argv()[argpos + 1], "--", 2))
00305 {
00306 if (!isatty(fileno(stdout)))
00307 {
00308 export_icon_data_filename = "-";
00309 }
00310 }
00311 else
00312 {
00313 export_icon_data_filename = a.argv()[++argpos];
00314 }
00315 }
00316 else if (!strcmp(a.argv()[argpos], "--import-icon-map"))
00317 {
00318 import_iconmap = true;
00319 grab_data = false;
00320
00321 if ((argpos + 1) >= a.argc() ||
00322 !strncmp(a.argv()[argpos + 1], "--", 2))
00323 {
00324 if (!isatty(fileno(stdin)))
00325 {
00326 import_icon_data_filename = "-";
00327 }
00328 }
00329 else
00330 {
00331 import_icon_data_filename = a.argv()[++argpos];
00332 }
00333 }
00334 else if (!strcmp(a.argv()[argpos], "--update-icon-map"))
00335 {
00336 update_icon_data = true;
00337 grab_data = false;
00338 }
00339 else if (!strcmp(a.argv()[argpos], "--reset-icon-map"))
00340 {
00341 reset_iconmap = true;
00342 grab_data = false;
00343
00344 if ((argpos + 1) < a.argc() &&
00345 strncmp(a.argv()[argpos + 1], "--", 2))
00346 {
00347 ++argpos;
00348 if (QString(a.argv()[argpos]) == "all")
00349 {
00350 reset_iconmap_icons = true;
00351 }
00352 else
00353 {
00354 cerr << "Unknown icon group '" << a.argv()[argpos]
00355 << "' for --reset-icon-map option" << endl;
00356 return FILLDB_EXIT_UNKNOWN_ICON_GROUP;
00357 }
00358 }
00359 }
00360 else if (!strcmp(a.argv()[argpos], "-h") ||
00361 !strcmp(a.argv()[argpos], "--help"))
00362 {
00363 cout << "usage:\n";
00364 cout << "--manual\n";
00365 cout << " Run in manual channel configuration mode\n";
00366 cout << " This will ask you questions about every channel\n";
00367 cout << "\n";
00368 cout << "--update\n";
00369 cout << " For running non-destructive updates on the database for\n";
00370 cout << " users in xmltv zones that do not provide channel data\n";
00371 cout << " Stops the addition of new channels and the changing of channel icons.\n";
00372 cout << "\n";
00373 cout << "--preset\n";
00374 cout << " Use it in case that you want to assign a preset number for\n";
00375 cout << " each channel, useful for non US countries where people\n";
00376 cout << " are used to assigning a sequenced number for each channel, i.e.:\n";
00377 cout << " 1->TVE1(S41), 2->La 2(SE18), 3->TV3(21), 4->Canal 33(60)...\n";
00378 cout << "\n";
00379 cout << "--file <sourceid> <xmlfile>\n";
00380 cout << " Bypass the grabbers and read data directly from a file\n";
00381 cout << " <sourceid> = number of the video source to use with this file\n";
00382 cout << " <xmlfile> = file to read\n";
00383 cout << "\n";
00384 cout << "--dd-file <sourceid> <offset> <lineupid> <xmlfile>\n";
00385 cout << " <sourceid> = number of the video source to use with this file\n";
00386 cout << " <offset> = days from today that xmlfile defines\n";
00387 cout << " (-1 means to replace all data, up to 10 days)\n";
00388 cout << " <lineupid> = the lineup id\n";
00389 cout << " <xmlfile> = file to read\n";
00390 cout << "\n";
00391 cout << "--xawchannels <sourceid> <xawtvrcfile>\n";
00392 cout << " (--manual flag works in combination with this)\n";
00393 cout << " Read channels as defined in xawtvrc file given\n";
00394 cout << " <sourceid> = cardinput\n";
00395 cout << " <xawtvrcfile> = file to read\n";
00396 cout << "\n";
00397 cout << "--do-channel-updates\n";
00398 cout << " When using DataDirect, ask mythfilldatabase to\n";
00399 cout << " overwrite channel names, frequencies, etc. with the\n";
00400 cout << " values available from the data source. This will \n";
00401 cout << " override custom channel names, which is why it is\n";
00402 cout << " off by default.\n";
00403 cout << "\n";
00404 cout << "--remove-new-channels\n";
00405 cout << " When using DataDirect, ask mythfilldatabase to\n";
00406 cout << " remove new channels (those not in the database)\n";
00407 cout << " from the DataDirect lineup. These channels are\n";
00408 cout << " removed from the lineup as if you had done so\n";
00409 cout << " via the DataDirect website's Lineup Wizard, but\n";
00410 cout << " may be re-added manually and incorporated into\n";
00411 cout << " MythTV by running mythfilldatabase without this\n";
00412 cout << " option. New channels are automatically removed\n";
00413 cout << " for DVB and HDTV sources that use DataDirect.\n";
00414 cout << "\n";
00415 cout << "--do-not-filter-new-channels\n";
00416 cout << " Normally MythTV tries to avoid adding ATSC channels\n";
00417 cout << " to NTSC channel lineups. This option restores the\n";
00418 cout << " behaviour of adding every channel in the downloaded\n";
00419 cout << " channel lineup to MythTV's lineup, in case MythTV's\n";
00420 cout << " smarts fail you.\n";
00421 cout << "\n";
00422 cout << "--graboptions <\"options\">\n";
00423 cout << " Pass options to grabber. Do NOT use unless you know\n";
00424 cout << " what you are doing. Mythfilldatabase will\n";
00425 cout << " automatically use the correct options for xmltv\n";
00426 cout << " compliant grabbers.\n";
00427 cout << "\n";
00428 cout << "--sourceid <number>\n";
00429 cout << " Only refresh data for sourceid given\n";
00430 cout << "\n";
00431 cout << "--max-days <number>\n";
00432 cout << " Force the maximum number of days, counting today,\n";
00433 cout << " for the grabber to check for future listings\n";
00434 cout << "--only-update-channels\n";
00435 cout << " Get as little listings data as possible to update channels\n";
00436 cout << "--refresh-today\n";
00437 cout << "--refresh-second\n";
00438 cout << "--refresh-all\n";
00439 cout << "--refresh-day <number>";
00440 cout << " (Only valid for selected grabbers: e.g. DataDirect)\n";
00441 cout << " Force a refresh today, two days, every day, or a specific day from now,\n";
00442 cout << " to catch the latest changes\n";
00443 cout << "--dont-refresh-tomorrow\n";
00444 cout << " Tomorrow will always be refreshed unless this argument is used\n";
00445 cout << "--dont-refresh-tba\n";
00446 cout << " \"To be announced\" programs will always be refreshed \n";
00447 cout << " unless this argument is used\n";
00448 cout << "\n";
00449 cout << "--export-icon-map [<filename>]\n";
00450 cout << " Exports your current icon map to <filename> (default: "
00451 << export_icon_data_filename << ")\n";
00452 cout << "--import-icon-map [<filename>]\n";
00453 cout << " Imports an icon map from <filename> (default: " <<
00454 import_icon_data_filename << ")\n";
00455 cout << "--update-icon-map\n";
00456 cout << " Updates icon map icons only\n";
00457 cout << "--reset-icon-map [all]\n";
00458 cout << " Resets your icon map (pass all to reset channel icons as well)\n";
00459 cout << "\n";
00460 cout << "--mark-repeats\n";
00461 cout << " Marks any programs with a OriginalAirDate earlier\n";
00462 cout << " than their start date as a repeat\n";
00463 cout << "\n";
00464 cout << "-v or --verbose debug-level\n";
00465 cout << " Use '-v help' for level info\n";
00466 cout << "\n";
00467
00468 #if 0
00469 cout << "--dd-grab-all\n";
00470 cout << " The DataDirect grabber will grab all available data\n";
00471 #endif
00472 cout << "--help\n";
00473 cout << " This text\n";
00474 cout << "\n";
00475 cout << "\n";
00476 cout << " --manual and --update can not be used together.\n";
00477 cout << "\n";
00478 return FILLDB_EXIT_INVALID_CMDLINE;
00479 }
00480 else if (!strcmp(a.argv()[argpos], "--no-delete"))
00481 {
00482 cerr << "Deprecated option '" << a.argv()[argpos] << "'" << endl;
00483 }
00484 else
00485 {
00486 fprintf(stderr, "illegal option: '%s' (use --help)\n",
00487 a.argv()[argpos]);
00488 return FILLDB_EXIT_INVALID_CMDLINE;
00489 }
00490
00491 ++argpos;
00492 }
00493
00494 gContext = NULL;
00495 gContext = new MythContext(MYTH_BINARY_VERSION);
00496 if (!gContext->Init(false))
00497 {
00498 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
00499 return FILLDB_EXIT_NO_MYTHCONTEXT;
00500 }
00501
00502 gContext->LogEntry("mythfilldatabase", LP_INFO,
00503 "Listings Download Started", "");
00504
00505 if (!grab_data)
00506 {
00507 }
00508 else if (from_xawfile)
00509 {
00510 fill_data.readXawtvChannels(fromxawfile_id, fromxawfile_name);
00511 }
00512 else if (from_file)
00513 {
00514 QString status = QObject::tr("currently running.");
00515 QDateTime GuideDataBefore, GuideDataAfter;
00516
00517 MSqlQuery query(MSqlQuery::InitCon());
00518 query.exec(QString("UPDATE settings SET data ='%1' "
00519 "WHERE value='mythfilldatabaseLastRunStart'")
00520 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm")));
00521
00522 query.exec(QString("UPDATE settings SET data ='%1' "
00523 "WHERE value='mythfilldatabaseLastRunStatus'")
00524 .arg(status));
00525
00526 query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c "
00527 "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID "
00528 "AND manualid = 0;");
00529 query.bindValue(":SRCID", fromfile_id);
00530 query.exec();
00531 if (query.isActive() && query.size() > 0)
00532 {
00533 query.next();
00534
00535 if (!query.isNull(0))
00536 GuideDataBefore = QDateTime::fromString(query.value(0).toString(),
00537 Qt::ISODate);
00538 }
00539
00540 if (!fill_data.grabDataFromFile(fromfile_id, fromfile_name))
00541 return FILLDB_EXIT_GRAB_DATA_FAILED;
00542
00543 query.exec(QString("UPDATE settings SET data ='%1' "
00544 "WHERE value='mythfilldatabaseLastRunEnd'")
00545 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm")));
00546
00547 query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c "
00548 "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID "
00549 "AND manualid = 0;");
00550 query.bindValue(":SRCID", fromfile_id);
00551 query.exec();
00552 if (query.isActive() && query.size() > 0)
00553 {
00554 query.next();
00555
00556 if (!query.isNull(0))
00557 GuideDataAfter = QDateTime::fromString(query.value(0).toString(),
00558 Qt::ISODate);
00559 }
00560
00561 if (GuideDataAfter == GuideDataBefore)
00562 status = QObject::tr("mythfilldatabase ran, but did not insert "
00563 "any new data into the Guide. This can indicate a "
00564 "potential problem with the XML file used for the update.");
00565 else
00566 status = QObject::tr("Successful.");
00567
00568 query.exec(QString("UPDATE settings SET data ='%1' "
00569 "WHERE value='mythfilldatabaseLastRunStatus'")
00570 .arg(status));
00571 }
00572 else if (from_dd_file)
00573 {
00574 fill_data.grabDataFromDDFile(
00575 fromfile_id, fromfile_offset, fromfile_name, fromddfile_lineupid);
00576 }
00577 else
00578 {
00579 QValueList<Source> sourcelist;
00580
00581 MSqlQuery sourcequery(MSqlQuery::InitCon());
00582 QString where = "";
00583
00584 if (sourceid != -1)
00585 {
00586 VERBOSE(VB_GENERAL,
00587 QString("Running for sourceid %1 ONLY because --sourceid "
00588 "was given on command-line").arg(sourceid));
00589 where = QString("WHERE sourceid = %1").arg(sourceid);
00590 }
00591
00592 QString querystr = QString("SELECT sourceid,name,xmltvgrabber,userid,"
00593 "password,lineupid "
00594 "FROM videosource ") + where +
00595 QString(" ORDER BY sourceid;");
00596 sourcequery.exec(querystr);
00597
00598 if (sourcequery.isActive())
00599 {
00600 if (sourcequery.size() > 0)
00601 {
00602 while (sourcequery.next())
00603 {
00604 Source newsource;
00605
00606 newsource.id = sourcequery.value(0).toInt();
00607 newsource.name = sourcequery.value(1).toString();
00608 newsource.xmltvgrabber = sourcequery.value(2).toString();
00609 newsource.userid = sourcequery.value(3).toString();
00610 newsource.password = sourcequery.value(4).toString();
00611 newsource.lineupid = sourcequery.value(5).toString();
00612
00613 newsource.xmltvgrabber_baseline = false;
00614 newsource.xmltvgrabber_manualconfig = false;
00615 newsource.xmltvgrabber_cache = false;
00616 newsource.xmltvgrabber_prefmethod = "";
00617
00618 sourcelist.append(newsource);
00619 usingDataDirect |=
00620 is_grabber_datadirect(newsource.xmltvgrabber);
00621 usingDataDirectLabs |=
00622 is_grabber_labs(newsource.xmltvgrabber);
00623 }
00624 }
00625 else
00626 {
00627 VERBOSE(VB_IMPORTANT,
00628 "There are no channel sources defined, did you run "
00629 "the setup program?");
00630 gContext->LogEntry("mythfilldatabase", LP_CRITICAL,
00631 "No channel sources defined",
00632 "Could not find any defined channel "
00633 "sources - did you run the setup "
00634 "program?");
00635 return FILLDB_EXIT_NO_CHAN_SRC;
00636 }
00637 }
00638 else
00639 {
00640 MythContext::DBError("loading channel sources", sourcequery);
00641 return FILLDB_EXIT_DB_ERROR;
00642 }
00643
00644 if (!fill_data.fillData(sourcelist))
00645 {
00646 VERBOSE(VB_IMPORTANT, "Failed to fetch some program info");
00647 gContext->LogEntry("mythfilldatabase", LP_WARNING,
00648 "Failed to fetch some program info", "");
00649 }
00650 else
00651 VERBOSE(VB_IMPORTANT, "Data fetching complete.");
00652 }
00653
00654 if (fill_data.only_update_channels && !fill_data.need_post_grab_proc)
00655 {
00656 delete gContext;
00657 return FILLDB_EXIT_OK;
00658 }
00659
00660 if (reset_iconmap)
00661 {
00662 fill_data.icon_data.ResetIconMap(reset_iconmap_icons);
00663 }
00664
00665 if (import_iconmap)
00666 {
00667 fill_data.icon_data.ImportIconMap(import_icon_data_filename);
00668 }
00669
00670 if (export_iconmap)
00671 {
00672 fill_data.icon_data.ExportIconMap(export_icon_data_filename);
00673 }
00674
00675 if (update_icon_data)
00676 {
00677 MSqlQuery query(MSqlQuery::InitCon());
00678 query.exec("SELECT sourceid FROM videosource ORDER BY sourceid;");
00679 if (query.isActive() && query.size() > 0)
00680 {
00681 while (query.next())
00682 {
00683 fill_data.icon_data.UpdateSourceIcons(query.value(0).toInt());
00684 }
00685 }
00686 }
00687
00688 if (grab_data)
00689 {
00690 VERBOSE(VB_GENERAL, "Adjusting program database end times.");
00691 int update_count = ProgramData::fix_end_times();
00692 if (update_count == -1)
00693 VERBOSE(VB_IMPORTANT, "fix_end_times failed!");
00694 else
00695 VERBOSE(VB_GENERAL,
00696 QString(" %1 replacements made").arg(update_count));
00697
00698 gContext->LogEntry("mythfilldatabase", LP_INFO,
00699 "Listings Download Finished", "");
00700 }
00701
00702 if (grab_data)
00703 {
00704 VERBOSE(VB_GENERAL, "Marking generic episodes.");
00705
00706 MSqlQuery query(MSqlQuery::InitCon());
00707 query.exec("UPDATE program SET generic = 1 WHERE "
00708 "((programid = '' AND subtitle = '' AND description = '') OR "
00709 " (programid <> '' AND category_type = 'series' AND "
00710 " program.programid LIKE '%0000'));");
00711
00712 VERBOSE(VB_GENERAL,
00713 QString(" Found %1").arg(query.numRowsAffected()));
00714 }
00715
00716 if (mark_repeats)
00717 {
00718 VERBOSE(VB_GENERAL, "Marking repeats.");
00719
00720 int newEpiWindow = gContext->GetNumSetting( "NewEpisodeWindow", 14);
00721
00722 MSqlQuery query(MSqlQuery::InitCon());
00723 query.exec( QString( "UPDATE program SET previouslyshown = 1 "
00724 "WHERE previouslyshown = 0 "
00725 "AND originalairdate is not null "
00726 "AND (to_days(starttime) - to_days(originalairdate)) > %1;")
00727 .arg(newEpiWindow));
00728
00729 VERBOSE(VB_GENERAL,
00730 QString(" Found %1").arg(query.numRowsAffected()));
00731
00732 VERBOSE(VB_GENERAL, "Unmarking new episode rebroadcast repeats.");
00733 query.exec( QString( "UPDATE program SET previouslyshown = 0 "
00734 "WHERE previouslyshown = 1 "
00735 "AND originalairdate is not null "
00736 "AND (to_days(starttime) - to_days(originalairdate)) <= %1;")
00737 .arg(newEpiWindow));
00738
00739 VERBOSE(VB_GENERAL,
00740 QString(" Found %1").arg(query.numRowsAffected()));
00741 }
00742
00743
00744
00745 if (grab_data)
00746 {
00747 MSqlQuery updt(MSqlQuery::InitCon());
00748 updt.exec("UPDATE program SET first = 0, last = 0;");
00749
00750 VERBOSE(VB_GENERAL, "Marking episode first showings.");
00751
00752 MSqlQuery query(MSqlQuery::InitCon());
00753 query.exec("SELECT MIN(starttime),programid FROM program "
00754 "WHERE programid > '' GROUP BY programid;");
00755
00756 if (query.isActive() && query.size() > 0)
00757 {
00758 while(query.next())
00759 {
00760 updt.prepare("UPDATE program set first = 1 "
00761 "WHERE starttime = :STARTTIME "
00762 " AND programid = :PROGRAMID;");
00763 updt.bindValue(":STARTTIME", query.value(0).toDateTime());
00764 updt.bindValue(":PROGRAMID", query.value(1).toString());
00765 updt.exec();
00766 }
00767 }
00768 int found = query.numRowsAffected();
00769
00770 query.exec("SELECT MIN(starttime),title,subtitle,description "
00771 "FROM program WHERE programid = '' "
00772 "GROUP BY title,subtitle,description;");
00773
00774 if (query.isActive() && query.size() > 0)
00775 {
00776 while(query.next())
00777 {
00778 updt.prepare("UPDATE program set first = 1 "
00779 "WHERE starttime = :STARTTIME "
00780 " AND title = :TITLE "
00781 " AND subtitle = :SUBTITLE "
00782 " AND description = :DESCRIPTION");
00783 updt.bindValue(":STARTTIME", query.value(0).toDateTime());
00784 updt.bindValue(":TITLE", query.value(1).toString());
00785 updt.bindValue(":SUBTITLE", query.value(2).toString());
00786 updt.bindValue(":DESCRIPTION", query.value(3).toString());
00787 updt.exec();
00788 }
00789 }
00790 found += query.numRowsAffected();
00791 VERBOSE(VB_GENERAL, QString(" Found %1").arg(found));
00792
00793 VERBOSE(VB_GENERAL, "Marking episode last showings.");
00794
00795 query.exec("SELECT MAX(starttime),programid FROM program "
00796 "WHERE programid > '' GROUP BY programid;");
00797
00798 if (query.isActive() && query.size() > 0)
00799 {
00800 while(query.next())
00801 {
00802 updt.prepare("UPDATE program set last = 1 "
00803 "WHERE starttime = :STARTTIME "
00804 " AND programid = :PROGRAMID;");
00805 updt.bindValue(":STARTTIME", query.value(0).toDateTime());
00806 updt.bindValue(":PROGRAMID", query.value(1).toString());
00807 updt.exec();
00808 }
00809 }
00810 found = query.numRowsAffected();
00811
00812 query.exec("SELECT MAX(starttime),title,subtitle,description "
00813 "FROM program WHERE programid = '' "
00814 "GROUP BY title,subtitle,description;");
00815
00816 if (query.isActive() && query.size() > 0)
00817 {
00818 while(query.next())
00819 {
00820 updt.prepare("UPDATE program set last = 1 "
00821 "WHERE starttime = :STARTTIME "
00822 " AND title = :TITLE "
00823 " AND subtitle = :SUBTITLE "
00824 " AND description = :DESCRIPTION");
00825 updt.bindValue(":STARTTIME", query.value(0).toDateTime());
00826 updt.bindValue(":TITLE", query.value(1).toString());
00827 updt.bindValue(":SUBTITLE", query.value(2).toString());
00828 updt.bindValue(":DESCRIPTION", query.value(3).toString());
00829 updt.exec();
00830 }
00831 }
00832 found += query.numRowsAffected();
00833 VERBOSE(VB_GENERAL, QString(" Found %1").arg(found));
00834 }
00835
00836 if (1)
00837 {
00838 MSqlQuery query(MSqlQuery::InitCon());
00839 query.exec( "SELECT count(previouslyshown) FROM program WHERE previouslyshown = 1;");
00840 if (query.isActive() && query.size() > 0)
00841 {
00842 query.next();
00843 if (query.value(0).toInt() != 0)
00844 query.exec("UPDATE settings SET data = '1' WHERE value = 'HaveRepeats';");
00845 else
00846 query.exec("UPDATE settings SET data = '0' WHERE value = 'HaveRepeats';");
00847 }
00848 }
00849
00850 if ((usingDataDirect) &&
00851 (gContext->GetNumSetting("MythFillGrabberSuggestsTime", 1)))
00852 {
00853 fill_data.ddprocessor.GrabNextSuggestedTime();
00854 }
00855
00856 if (usingDataDirectLabs ||
00857 !gContext->GetNumSetting("MythFillFixProgramIDsHasRunOnce", 0))
00858 {
00859 DataDirectProcessor::FixProgramIDs();
00860 }
00861
00862 VERBOSE(VB_GENERAL, "\n"
00863 "===============================================================\n"
00864 "| Attempting to contact the master backend for rescheduling. |\n"
00865 "| If the master is not running, rescheduling will happen when |\n"
00866 "| the master backend is restarted. |\n"
00867 "===============================================================");
00868
00869 if (grab_data || mark_repeats)
00870 ScheduledRecording::signalChange(-1);
00871
00872 RemoteSendMessage("CLEAR_SETTINGS_CACHE");
00873
00874 delete gContext;
00875
00876 VERBOSE(VB_IMPORTANT, "mythfilldatabase run complete.");
00877
00878 return FILLDB_EXIT_OK;
00879 }
00880
00881