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();
161 for (
const auto & item : qAsConst(sl))
163 QString warn = QString(
"Invalid entry in --refresh list: %1")
166 bool enable = !item.contains(
"not");
168 if (item.contains(
"today"))
170 else if (item.contains(
"tomorrow"))
172 else if (item.contains(
"second"))
174 else if (item.contains(
"all"))
176 else if (item.contains(
"-"))
179 QStringList r = item.split(
"-");
181 uint lower = r[0].toUInt(&ok);
184 std::cerr << warn.toLocal8Bit().constData() << std::endl;
188 uint upper = r[1].toUInt(&ok);
191 std::cerr << warn.toLocal8Bit().constData() << std::endl;
197 std::cerr << warn.toLocal8Bit().constData() << std::endl;
201 for (
uint j = lower; j <= upper; ++j)
207 uint day = item.toUInt(&ok);
210 std::cerr << warn.toLocal8Bit().constData() << std::endl;
237 LOG(VB_GENERAL, LOG_ERR,
"Failed to init MythContext, exiting.");
247 LOG(VB_GENERAL, LOG_ERR,
"Incorrect database schema");
253 LOG(VB_GENERAL, LOG_INFO,
254 "Opening blocking connection to master backend");
258 LOG(VB_GENERAL, LOG_WARNING,
259 "Failed to connect to master backend. MythFillDatabase will "
260 "continue running but will be unable to prevent backend from "
261 "shutting down, or triggering a reschedule when complete.");
266 QString status = QObject::tr(
"currently running.");
267 QDateTime GuideDataBefore;
268 QDateTime GuideDataAfter;
274 query.
prepare(
"SELECT MAX(endtime) FROM program p "
275 "LEFT JOIN channel c ON p.chanid=c.chanid "
276 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
277 "AND manualid = 0 AND c.xmltvid != '';");
294 query.
prepare(
"SELECT MAX(endtime) FROM program p "
295 "LEFT JOIN channel c ON p.chanid=c.chanid "
296 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
297 "AND manualid = 0 AND c.xmltvid != '';");
307 if (GuideDataAfter == GuideDataBefore)
309 status = QObject::tr(
"mythfilldatabase ran, but did not insert "
310 "any new data into the Guide. This can indicate a "
311 "potential problem with the XML file used for the update.");
315 status = QObject::tr(
"Successful.");
329 LOG(VB_GENERAL, LOG_INFO,
330 QString(
"Running for sourceid %1 ONLY because --sourceid "
331 "was given on command-line").arg(sourceid));
332 where = QString(
"WHERE sourceid = %1").arg(sourceid);
335 QString querystr = QString(
"SELECT sourceid,name,xmltvgrabber,userid,"
337 "FROM videosource ") + where +
338 QString(
" ORDER BY sourceid;");
340 if (sourcequery.
exec(querystr))
342 if (sourcequery.
size() > 0)
344 while (sourcequery.
next())
348 newsource.
id = sourcequery.
value(0).toInt();
349 newsource.
name = sourcequery.
value(1).toString();
351 newsource.
userid = sourcequery.
value(3).toString();
360 sourcelist.push_back(newsource);
365 LOG(VB_GENERAL, LOG_ERR,
366 "There are no channel sources defined, did you run "
367 "the setup program?");
377 if (!fill_data.
Run(sourcelist))
378 LOG(VB_GENERAL, LOG_ERR,
"Failed to fetch some program info");
380 LOG(VB_GENERAL, LOG_NOTICE,
"Data fetching complete.");
388 LOG(VB_GENERAL, LOG_INFO,
"Adjusting program database end times.");
390 if (update_count == -1)
391 LOG(VB_GENERAL, LOG_ERR,
"fix_end_times failed!");
393 LOG(VB_GENERAL, LOG_INFO,
394 QString(
" %1 replacements made").arg(update_count));
396 LOG(VB_GENERAL, LOG_INFO,
"Marking generic episodes.");
399 query.
prepare(
"UPDATE program SET generic = 1 WHERE "
400 "((programid = '' AND subtitle = '' AND description = '') OR "
401 " (programid <> '' AND category_type = 'series' AND "
402 " program.programid LIKE '%0000'));");
407 LOG(VB_GENERAL, LOG_INFO,
410 LOG(VB_GENERAL, LOG_INFO,
"Extending non-unique programids "
411 "with multiple parts.");
415 sel.
prepare(
"SELECT DISTINCT programid, partnumber, parttotal "
416 "FROM program WHERE partnumber > 0 AND parttotal > 0 AND "
417 "programid LIKE '%0000'");
421 repl.
prepare(
"UPDATE program SET programid = :NEWID "
422 "WHERE programid = :OLDID AND "
423 "partnumber = :PARTNUM AND "
424 "parttotal = :PARTTOTAL");
428 QString orig_programid = sel.
value(0).toString();
429 QString new_programid = orig_programid.left(10);
432 int partnum = sel.
value(1).toInt();
433 int parttotal = sel.
value(2).toInt();
435 part.setNum(parttotal);
436 new_programid.append(part.rightJustified(2,
'0'));
437 part.setNum(partnum);
438 new_programid.append(part.rightJustified(2,
'0'));
440 LOG(VB_GENERAL, LOG_INFO,
441 QString(
" %1 -> %2 (part %3 of %4)")
442 .arg(orig_programid, new_programid)
443 .arg(partnum).arg(parttotal));
446 repl.
bindValue(
":OLDID", orig_programid);
451 LOG(VB_GENERAL, LOG_INFO,
452 QString(
"Fudging programid from '%1' to '%2'")
453 .arg(orig_programid, new_programid));
460 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
462 LOG(VB_GENERAL, LOG_INFO,
"Fixing missing original airdates.");
463 query.
prepare(
"UPDATE program p "
465 " SELECT programid, MAX(originalairdate) maxoad "
467 " WHERE programid <> '' AND "
468 " originalairdate IS NOT NULL "
469 " GROUP BY programid ) oad "
470 " ON p.programid = oad.programid "
471 "SET p.originalairdate = oad.maxoad "
472 "WHERE p.originalairdate IS NULL");
476 LOG(VB_GENERAL, LOG_INFO,
477 QString(
" Found %1 with programids")
481 query.
prepare(
"UPDATE program p "
483 " SELECT title, subtitle, description, "
484 " MAX(originalairdate) maxoad "
486 " WHERE programid = '' AND "
487 " originalairdate IS NOT NULL "
488 " GROUP BY title, subtitle, description ) oad "
489 " ON p.programid = '' AND "
490 " p.title = oad.title AND "
491 " p.subtitle = oad.subtitle AND "
492 " p.description = oad.description "
493 "SET p.originalairdate = oad.maxoad "
494 "WHERE p.originalairdate IS NULL");
498 LOG(VB_GENERAL, LOG_INFO,
499 QString(
" Found %1 without programids")
505 LOG(VB_GENERAL, LOG_INFO,
"Marking repeats.");
510 query2.
prepare(
"UPDATE program SET previouslyshown = 1 "
511 "WHERE previouslyshown = 0 "
512 "AND originalairdate is not null "
513 "AND (to_days(starttime) - to_days(originalairdate)) "
515 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
518 LOG(VB_GENERAL, LOG_INFO,
521 LOG(VB_GENERAL, LOG_INFO,
"Unmarking new episode rebroadcast repeats.");
522 query2.
prepare(
"UPDATE program SET previouslyshown = 0 "
523 "WHERE previouslyshown = 1 "
524 "AND originalairdate is not null "
525 "AND (to_days(starttime) - to_days(originalairdate)) "
527 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
530 LOG(VB_GENERAL, LOG_INFO,
536 updt.
prepare(
"UPDATE program SET first = 0, last = 0;");
540 LOG(VB_GENERAL, LOG_INFO,
"Marking episode first showings.");
542 "JOIN (SELECT MIN(p.starttime) AS starttime, p.programid "
543 " FROM program p, channel c "
544 " WHERE p.programid <> '' "
545 " AND p.chanid = c.chanid "
546 " AND c.deleted IS NULL "
547 " AND c.visible > 0 "
548 " GROUP BY p.programid "
550 "ON program.programid = firsts.programid "
551 " AND program.starttime = firsts.starttime "
552 "SET program.first=1;");
558 "JOIN (SELECT MIN(p.starttime) AS starttime, p.title, p.subtitle, "
559 " LEFT(p.description, 1024) AS partdesc "
560 " FROM program p, channel c "
561 " WHERE p.programid = '' "
562 " AND p.chanid = c.chanid "
563 " AND c.deleted IS NULL "
564 " AND c.visible > 0 "
565 " GROUP BY p.title, p.subtitle, partdesc "
567 "ON program.starttime = firsts.starttime "
568 " AND program.title = firsts.title "
569 " AND program.subtitle = firsts.subtitle "
570 " AND LEFT(program.description, 1024) = firsts.partdesc "
571 "SET program.first = 1 "
572 "WHERE program.programid = '';");
576 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
578 LOG(VB_GENERAL, LOG_INFO,
"Marking episode last showings.");
580 "JOIN (SELECT MAX(p.starttime) AS starttime, p.programid "
581 " FROM program p, channel c "
582 " WHERE p.programid <> '' "
583 " AND p.chanid = c.chanid "
584 " AND c.deleted IS NULL "
585 " AND c.visible > 0 "
586 " GROUP BY p.programid "
588 "ON program.programid = lasts.programid "
589 " AND program.starttime = lasts.starttime "
590 "SET program.last=1;");
596 "JOIN (SELECT MAX(p.starttime) AS starttime, p.title, p.subtitle, "
597 " LEFT(p.description, 1024) AS partdesc "
598 " FROM program p, channel c "
599 " WHERE p.programid = '' "
600 " AND p.chanid = c.chanid "
601 " AND c.deleted IS NULL "
602 " AND c.visible > 0 "
603 " GROUP BY p.title, p.subtitle, partdesc "
605 "ON program.starttime = lasts.starttime "
606 " AND program.title = lasts.title "
607 " AND program.subtitle = lasts.subtitle "
608 " AND LEFT(program.description, 1024) = lasts.partdesc "
609 "SET program.last = 1 "
610 "WHERE program.programid = '';");
614 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
619 query2.
prepare(
"SELECT count(previouslyshown) "
620 "FROM program WHERE previouslyshown = 1;");
623 if (query2.
value(0).toInt() != 0)
632 LOG(VB_GENERAL, LOG_INFO,
"\n"
633 "===============================================================\n"
634 "| Attempting to contact the master backend for rescheduling. |\n"
635 "| If the master is not running, rescheduling will happen when |\n"
636 "| the master backend is restarted. |\n"
637 "===============================================================");
647 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)
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)
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed, const bool upgradeIfNoUI, [[maybe_unused]] const bool informSystemd)
Called from outside dbcheck.cpp to update the schema.
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 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.