Go to the documentation of this file.
9 #include <QCoreApplication>
16 #include "libmythbase/mythconfig.h"
22 #include "libmythbase/mythversion.h"
44 int main(
int argc,
char *argv[])
48 QString fromfile_name;
49 bool from_file =
false;
50 bool mark_repeats =
true;
73 QCoreApplication a(argc, argv);
83 LOG(VB_GENERAL, LOG_WARNING,
84 "Invalid option, see: mythfilldatabase --help dd-grab-all");
89 std::cout <<
"### Running in manual channel configuration mode.\n";
90 std::cout <<
"### This will ask you questions about every channel.\n";
97 LOG(VB_GENERAL, LOG_NOTICE,
98 "Only updating guide data, channel and icon updates will be ignored");
104 std::cout <<
"###\n";
105 std::cout <<
"### Running in preset channel configuration mode.\n";
106 std::cout <<
"### This will assign channel ";
107 std::cout <<
"preset numbers to every channel.\n";
108 std::cout <<
"###\n";
118 std::cerr <<
"The --file option must be used in combination" << std::endl
119 <<
"with both --sourceid and --xmlfile." << std::endl;
126 LOG(VB_GENERAL, LOG_INFO,
127 "Bypassing grabbers, reading directly from file");
143 std::cerr <<
"The --cardtype option must be used in combination" << std::endl
144 <<
"with a --sourceid option." << std::endl;
149 .trimmed().toUpper();
180 for (
const auto & item : qAsConst(sl))
182 QString warn = QString(
"Invalid entry in --refresh list: %1")
185 bool enable = !item.contains(
"not");
187 if (item.contains(
"today"))
189 else if (item.contains(
"tomorrow"))
191 else if (item.contains(
"second"))
193 else if (item.contains(
"all"))
195 else if (item.contains(
"-"))
198 QStringList r = item.split(
"-");
200 uint lower = r[0].toUInt(&ok);
203 std::cerr << warn.toLocal8Bit().constData() << std::endl;
207 uint upper = r[1].toUInt(&ok);
210 std::cerr << warn.toLocal8Bit().constData() << std::endl;
216 std::cerr << warn.toLocal8Bit().constData() << std::endl;
220 for (
uint j = lower; j <= upper; ++j)
226 uint day = item.toUInt(&ok);
229 std::cerr << warn.toLocal8Bit().constData() << std::endl;
256 LOG(VB_GENERAL, LOG_ERR,
"Failed to init MythContext, exiting.");
266 LOG(VB_GENERAL, LOG_ERR,
"Incorrect database schema");
272 LOG(VB_GENERAL, LOG_INFO,
273 "Opening blocking connection to master backend");
277 LOG(VB_GENERAL, LOG_WARNING,
278 "Failed to connect to master backend. MythFillDatabase will "
279 "continue running but will be unable to prevent backend from "
280 "shutting down, or triggering a reschedule when complete.");
285 QString status = QObject::tr(
"currently running.");
286 QDateTime GuideDataBefore;
287 QDateTime GuideDataAfter;
293 query.
prepare(
"SELECT MAX(endtime) FROM program p "
294 "LEFT JOIN channel c ON p.chanid=c.chanid "
295 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
296 "AND manualid = 0 AND c.xmltvid != '';");
313 query.
prepare(
"SELECT MAX(endtime) FROM program p "
314 "LEFT JOIN channel c ON p.chanid=c.chanid "
315 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
316 "AND manualid = 0 AND c.xmltvid != '';");
326 if (GuideDataAfter == GuideDataBefore)
328 status = QObject::tr(
"mythfilldatabase ran, but did not insert "
329 "any new data into the Guide. This can indicate a "
330 "potential problem with the XML file used for the update.");
334 status = QObject::tr(
"Successful.");
348 LOG(VB_GENERAL, LOG_INFO,
349 QString(
"Running for sourceid %1 ONLY because --sourceid "
350 "was given on command-line").arg(sourceid));
351 where = QString(
"WHERE sourceid = %1").arg(sourceid);
354 QString querystr = QString(
"SELECT sourceid,name,xmltvgrabber,userid,"
356 "FROM videosource ") + where +
357 QString(
" ORDER BY sourceid;");
359 if (sourcequery.
exec(querystr))
361 if (sourcequery.
size() > 0)
363 while (sourcequery.
next())
367 newsource.
id = sourcequery.
value(0).toInt();
368 newsource.
name = sourcequery.
value(1).toString();
370 newsource.
userid = sourcequery.
value(3).toString();
379 sourcelist.push_back(newsource);
384 LOG(VB_GENERAL, LOG_ERR,
385 "There are no channel sources defined, did you run "
386 "the setup program?");
396 if (!fill_data.
Run(sourcelist))
397 LOG(VB_GENERAL, LOG_ERR,
"Failed to fetch some program info");
399 LOG(VB_GENERAL, LOG_NOTICE,
"Data fetching complete.");
407 LOG(VB_GENERAL, LOG_INFO,
"Adjusting program database end times.");
409 if (update_count == -1)
410 LOG(VB_GENERAL, LOG_ERR,
"fix_end_times failed!");
412 LOG(VB_GENERAL, LOG_INFO,
413 QString(
" %1 replacements made").arg(update_count));
415 LOG(VB_GENERAL, LOG_INFO,
"Marking generic episodes.");
418 query.
prepare(
"UPDATE program SET generic = 1 WHERE "
419 "((programid = '' AND subtitle = '' AND description = '') OR "
420 " (programid <> '' AND category_type = 'series' AND "
421 " program.programid LIKE '%0000'));");
426 LOG(VB_GENERAL, LOG_INFO,
429 LOG(VB_GENERAL, LOG_INFO,
"Extending non-unique programids "
430 "with multiple parts.");
434 sel.
prepare(
"SELECT DISTINCT programid, partnumber, parttotal "
435 "FROM program WHERE partnumber > 0 AND parttotal > 0 AND "
436 "programid LIKE '%0000'");
440 repl.
prepare(
"UPDATE program SET programid = :NEWID "
441 "WHERE programid = :OLDID AND "
442 "partnumber = :PARTNUM AND "
443 "parttotal = :PARTTOTAL");
447 QString orig_programid = sel.
value(0).toString();
448 QString new_programid = orig_programid.left(10);
451 int partnum = sel.
value(1).toInt();
452 int parttotal = sel.
value(2).toInt();
454 part.setNum(parttotal);
455 new_programid.append(part.rightJustified(2,
'0'));
456 part.setNum(partnum);
457 new_programid.append(part.rightJustified(2,
'0'));
459 LOG(VB_GENERAL, LOG_INFO,
460 QString(
" %1 -> %2 (part %3 of %4)")
461 .arg(orig_programid, new_programid)
462 .arg(partnum).arg(parttotal));
465 repl.
bindValue(
":OLDID", orig_programid);
470 LOG(VB_GENERAL, LOG_INFO,
471 QString(
"Fudging programid from '%1' to '%2'")
472 .arg(orig_programid, new_programid));
479 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
481 LOG(VB_GENERAL, LOG_INFO,
"Fixing missing original airdates.");
482 query.
prepare(
"UPDATE program p "
484 " SELECT programid, MAX(originalairdate) maxoad "
486 " WHERE programid <> '' AND "
487 " originalairdate IS NOT NULL "
488 " GROUP BY programid ) oad "
489 " ON p.programid = oad.programid "
490 "SET p.originalairdate = oad.maxoad "
491 "WHERE p.originalairdate IS NULL");
495 LOG(VB_GENERAL, LOG_INFO,
496 QString(
" Found %1 with programids")
500 query.
prepare(
"UPDATE program p "
502 " SELECT title, subtitle, description, "
503 " MAX(originalairdate) maxoad "
505 " WHERE programid = '' AND "
506 " originalairdate IS NOT NULL "
507 " GROUP BY title, subtitle, description ) oad "
508 " ON p.programid = '' AND "
509 " p.title = oad.title AND "
510 " p.subtitle = oad.subtitle AND "
511 " p.description = oad.description "
512 "SET p.originalairdate = oad.maxoad "
513 "WHERE p.originalairdate IS NULL");
517 LOG(VB_GENERAL, LOG_INFO,
518 QString(
" Found %1 without programids")
524 LOG(VB_GENERAL, LOG_INFO,
"Marking repeats.");
529 query2.
prepare(
"UPDATE program SET previouslyshown = 1 "
530 "WHERE previouslyshown = 0 "
531 "AND originalairdate is not null "
532 "AND (to_days(starttime) - to_days(originalairdate)) "
534 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
537 LOG(VB_GENERAL, LOG_INFO,
540 LOG(VB_GENERAL, LOG_INFO,
"Unmarking new episode rebroadcast repeats.");
541 query2.
prepare(
"UPDATE program SET previouslyshown = 0 "
542 "WHERE previouslyshown = 1 "
543 "AND originalairdate is not null "
544 "AND (to_days(starttime) - to_days(originalairdate)) "
546 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
549 LOG(VB_GENERAL, LOG_INFO,
555 updt.
prepare(
"UPDATE program SET first = 0, last = 0;");
559 LOG(VB_GENERAL, LOG_INFO,
"Marking episode first showings.");
561 "JOIN (SELECT MIN(p.starttime) AS starttime, p.programid "
562 " FROM program p, channel c "
563 " WHERE p.programid <> '' "
564 " AND p.chanid = c.chanid "
565 " AND c.deleted IS NULL "
566 " AND c.visible > 0 "
567 " GROUP BY p.programid "
569 "ON program.programid = firsts.programid "
570 " AND program.starttime = firsts.starttime "
571 "SET program.first=1;");
577 "JOIN (SELECT MIN(p.starttime) AS starttime, p.title, p.subtitle, "
578 " LEFT(p.description, 1024) AS partdesc "
579 " FROM program p, channel c "
580 " WHERE p.programid = '' "
581 " AND p.chanid = c.chanid "
582 " AND c.deleted IS NULL "
583 " AND c.visible > 0 "
584 " GROUP BY p.title, p.subtitle, partdesc "
586 "ON program.starttime = firsts.starttime "
587 " AND program.title = firsts.title "
588 " AND program.subtitle = firsts.subtitle "
589 " AND LEFT(program.description, 1024) = firsts.partdesc "
590 "SET program.first = 1 "
591 "WHERE program.programid = '';");
595 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
597 LOG(VB_GENERAL, LOG_INFO,
"Marking episode last showings.");
599 "JOIN (SELECT MAX(p.starttime) AS starttime, p.programid "
600 " FROM program p, channel c "
601 " WHERE p.programid <> '' "
602 " AND p.chanid = c.chanid "
603 " AND c.deleted IS NULL "
604 " AND c.visible > 0 "
605 " GROUP BY p.programid "
607 "ON program.programid = lasts.programid "
608 " AND program.starttime = lasts.starttime "
609 "SET program.last=1;");
615 "JOIN (SELECT MAX(p.starttime) AS starttime, p.title, p.subtitle, "
616 " LEFT(p.description, 1024) AS partdesc "
617 " FROM program p, channel c "
618 " WHERE p.programid = '' "
619 " AND p.chanid = c.chanid "
620 " AND c.deleted IS NULL "
621 " AND c.visible > 0 "
622 " GROUP BY p.title, p.subtitle, partdesc "
624 "ON program.starttime = lasts.starttime "
625 " AND program.title = lasts.title "
626 " AND program.subtitle = lasts.subtitle "
627 " AND LEFT(program.description, 1024) = lasts.partdesc "
628 "SET program.last = 1 "
629 "WHERE program.programid = '';");
633 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
638 query2.
prepare(
"SELECT count(previouslyshown) "
639 "FROM program WHERE previouslyshown = 1;");
642 if (query2.
value(0).toInt() != 0)
651 LOG(VB_GENERAL, LOG_INFO,
"\n"
652 "===============================================================\n"
653 "| Attempting to contact the master backend for rescheduling. |\n"
654 "| If the master is not running, rescheduling will happen when |\n"
655 "| the master backend is restarted. |\n"
656 "===============================================================");
666 LOG(VB_GENERAL, LOG_NOTICE,
"mythfilldatabase run complete.");
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
void SendMessage(const QString &message)
@ GENERIC_EXIT_SETUP_ERROR
Incorrectly setup system.
void setHttpProxy(void)
Get network proxy settings from OS, and use for [Q]Http[Comms].
bool isNull(int field) const
bool updateLastRunStart(void)
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed, const bool upgradeIfNoUI, const bool informSystemd)
Called from outside dbcheck.cpp to update the schema.
MythCommFlagCommandLineParser cmdline
std::vector< DataSource > DataSourceList
Startup context for MythTV.
QVariant value(int i) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
@ GENERIC_EXIT_OK
Exited with no error.
bool SafeConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
static int fix_end_times(void)
bool updateLastRunEnd(void)
void SendSystemEvent(const QString &msg)
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void DBError(const QString &where, const MSqlQuery &query)
bool Run(DataSourceList &sourcelist)
Goes through the sourcelist and updates its channels with program info grabbed with the associated gr...
static void PrintVersion(void)
Print application version information.
void PrintHelp(void) const
Print command line option help.
@ GENERIC_EXIT_NOT_OK
Exited with error.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
int GetNumSetting(const QString &key, int defaultval=0)
static QString cleanup(const QString &str)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
bool GrabDataFromFile(int id, const QString &filename)
static void Init(QObject *parent=nullptr)
QString xmltvgrabber_prefmethod
static constexpr const char * MYTH_APPNAME_MYTHFILLDATABASE
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
bool m_onlyUpdateChannels
bool SetValue(const QString &key, const QVariant &value)
Set a new stored value for an existing argument definition, or spawn a new definition store value in.
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
int main(int argc, char *argv[])
QStringList toStringList(const QString &key, const QString &sep="") const
Returns stored QVariant as a QStringList, falling to default if not provided.
@ GENERIC_EXIT_DB_OUTOFDATE
Database needs upgrade.
void SetRefresh(int day, bool set)
bool xmltvgrabber_baseline
int numRowsAffected() const
bool xmltvgrabber_manualconfig
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
bool updateLastRunStatus(QString &status)
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
int toInt(const QString &key) const
Returns stored QVariant as an integer, falling to default if not provided.
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
QString GetPassthrough(void) const
Return any text supplied on the command line after a bare '–'.
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
MythContext * gContext
This global variable contains the MythContext instance for the application.
bool Init(bool gui=true, bool promptForBackend=false, bool disableAutoDiscovery=false, bool ignoreDB=false)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
@ GENERIC_EXIT_DB_ERROR
Database error.