9#include <QCoreApplication>
22#include "libmythbase/mythversion.h"
32int main(
int argc,
char *argv[])
36 QString fromfile_name;
37 bool from_file =
false;
38 bool mark_repeats =
true;
61 QCoreApplication a(argc, argv);
73 std::cout <<
"### Running in manual channel configuration mode.\n";
74 std::cout <<
"### This will ask you questions about every channel.\n";
81 LOG(VB_GENERAL, LOG_NOTICE,
82 "Only updating guide data, channel and icon updates will be ignored");
89 std::cout <<
"### Running in preset channel configuration mode.\n";
90 std::cout <<
"### This will assign channel ";
91 std::cout <<
"preset numbers to every channel.\n";
102 std::cerr <<
"The --file option must be used in combination\n"
103 <<
"with both --sourceid and --xmlfile.\n";
110 LOG(VB_GENERAL, LOG_INFO,
111 "Bypassing grabbers, reading directly from file");
127 std::cerr <<
"The --cardtype option must be used in combination\n"
128 <<
"with a --sourceid option.\n";
133 .trimmed().toUpper();
145 for (
const auto & item : std::as_const(sl))
147 QString warn = QString(
"Invalid entry in --refresh list: %1")
150 bool enable = !item.contains(
"not");
152 if (item.contains(
"today")) {
154 }
else if (item.contains(
"tomorrow")) {
156 }
else if (item.contains(
"second")) {
158 }
else if (item.contains(
"all")) {
160 }
else if (item.contains(
"-")) {
162 QStringList r = item.split(
"-");
164 uint lower = r[0].toUInt(&ok);
167 std::cerr << warn.toLocal8Bit().constData() <<
'\n';
171 uint upper = r[1].toUInt(&ok);
174 std::cerr << warn.toLocal8Bit().constData() <<
'\n';
180 std::cerr << warn.toLocal8Bit().constData() <<
'\n';
184 for (
uint j = lower; j <= upper; ++j)
190 uint day = item.toUInt(&ok);
193 std::cerr << warn.toLocal8Bit().constData() <<
'\n';
212 if (!context.Init(
false))
214 LOG(VB_GENERAL, LOG_ERR,
"Failed to init MythContext, exiting.");
224 LOG(VB_GENERAL, LOG_ERR,
"Incorrect database schema");
230 LOG(VB_GENERAL, LOG_INFO,
231 "Opening blocking connection to master backend");
235 LOG(VB_GENERAL, LOG_WARNING,
236 "Failed to connect to master backend. MythFillDatabase will "
237 "continue running but will be unable to prevent backend from "
238 "shutting down, or triggering a reschedule when complete.");
243 QString status = QObject::tr(
"currently running.");
244 QDateTime GuideDataBefore;
245 QDateTime GuideDataAfter;
251 query.
prepare(
"SELECT MAX(endtime) FROM program p "
252 "LEFT JOIN channel c ON p.chanid=c.chanid "
253 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
254 "AND manualid = 0 AND c.xmltvid != '';");
271 query.
prepare(
"SELECT MAX(endtime) FROM program p "
272 "LEFT JOIN channel c ON p.chanid=c.chanid "
273 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
274 "AND manualid = 0 AND c.xmltvid != '';");
284 if (GuideDataAfter == GuideDataBefore)
286 status = QObject::tr(
"mythfilldatabase ran, but did not insert "
287 "any new data into the Guide. This can indicate a "
288 "potential problem with the XML file used for the update.");
292 status = QObject::tr(
"Successful.");
306 LOG(VB_GENERAL, LOG_INFO,
307 QString(
"Running for sourceid %1 ONLY because --sourceid "
308 "was given on command-line").arg(sourceid));
309 where = QString(
"WHERE sourceid = %1").arg(sourceid);
312 QString querystr = QString(
"SELECT sourceid,name,xmltvgrabber,userid,"
314 "FROM videosource ") + where +
315 QString(
" ORDER BY sourceid;");
317 if (sourcequery.
exec(querystr))
319 if (sourcequery.
size() > 0)
321 while (sourcequery.
next())
325 newsource.
id = sourcequery.
value(0).toInt();
326 newsource.
name = sourcequery.
value(1).toString();
328 newsource.
userid = sourcequery.
value(3).toString();
337 sourcelist.push_back(newsource);
342 LOG(VB_GENERAL, LOG_ERR,
343 "There are no channel sources defined, did you run "
344 "the setup program?");
354 if (!fill_data.
Run(sourcelist))
355 LOG(VB_GENERAL, LOG_ERR,
"Failed to fetch some program info");
357 LOG(VB_GENERAL, LOG_NOTICE,
"Data fetching complete.");
365 LOG(VB_GENERAL, LOG_INFO,
"Adjusting program database end times.");
367 if (update_count == -1)
368 LOG(VB_GENERAL, LOG_ERR,
"fix_end_times failed!");
370 LOG(VB_GENERAL, LOG_INFO,
371 QString(
" %1 replacements made").arg(update_count));
373 LOG(VB_GENERAL, LOG_INFO,
"Marking generic episodes.");
376 query.
prepare(
"UPDATE program SET generic = 1 WHERE "
377 "((programid = '' AND subtitle = '' AND description = '') OR "
378 " (programid <> '' AND category_type = 'series' AND "
379 " program.programid LIKE '%0000'));");
384 LOG(VB_GENERAL, LOG_INFO,
387 LOG(VB_GENERAL, LOG_INFO,
"Extending non-unique programids "
388 "with multiple parts.");
392 sel.
prepare(
"SELECT DISTINCT programid, partnumber, parttotal "
393 "FROM program WHERE partnumber > 0 AND parttotal > 0 AND "
394 "programid LIKE '%0000'");
398 repl.
prepare(
"UPDATE program SET programid = :NEWID "
399 "WHERE programid = :OLDID AND "
400 "partnumber = :PARTNUM AND "
401 "parttotal = :PARTTOTAL");
405 QString orig_programid = sel.
value(0).toString();
406 QString new_programid = orig_programid.left(10);
409 int partnum = sel.
value(1).toInt();
410 int parttotal = sel.
value(2).toInt();
412 part.setNum(parttotal);
413 new_programid.append(part.rightJustified(2,
'0'));
414 part.setNum(partnum);
415 new_programid.append(part.rightJustified(2,
'0'));
417 LOG(VB_GENERAL, LOG_INFO,
418 QString(
" %1 -> %2 (part %3 of %4)")
419 .arg(orig_programid, new_programid)
420 .arg(partnum).arg(parttotal));
423 repl.
bindValue(
":OLDID", orig_programid);
428 LOG(VB_GENERAL, LOG_INFO,
429 QString(
"Fudging programid from '%1' to '%2'")
430 .arg(orig_programid, new_programid));
439 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
441 LOG(VB_GENERAL, LOG_INFO,
"Fixing missing original airdates.");
442 query.
prepare(
"UPDATE program p "
444 " SELECT programid, MAX(originalairdate) maxoad "
446 " WHERE programid <> '' AND "
447 " originalairdate IS NOT NULL "
448 " GROUP BY programid ) oad "
449 " ON p.programid = oad.programid "
450 "SET p.originalairdate = oad.maxoad "
451 "WHERE p.originalairdate IS NULL");
455 LOG(VB_GENERAL, LOG_INFO,
456 QString(
" Found %1 with programids")
460 query.
prepare(
"UPDATE program p "
462 " SELECT title, subtitle, description, "
463 " MAX(originalairdate) maxoad "
465 " WHERE programid = '' AND "
466 " originalairdate IS NOT NULL "
467 " GROUP BY title, subtitle, description ) oad "
468 " ON p.programid = '' AND "
469 " p.title = oad.title AND "
470 " p.subtitle = oad.subtitle AND "
471 " p.description = oad.description "
472 "SET p.originalairdate = oad.maxoad "
473 "WHERE p.originalairdate IS NULL");
477 LOG(VB_GENERAL, LOG_INFO,
478 QString(
" Found %1 without programids")
484 LOG(VB_GENERAL, LOG_INFO,
"Marking repeats.");
489 query2.
prepare(
"UPDATE program SET previouslyshown = 1 "
490 "WHERE previouslyshown = 0 "
491 "AND originalairdate is not null "
492 "AND (to_days(starttime) - to_days(originalairdate)) "
494 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
497 LOG(VB_GENERAL, LOG_INFO,
500 LOG(VB_GENERAL, LOG_INFO,
"Unmarking new episode rebroadcast repeats.");
501 query2.
prepare(
"UPDATE program SET previouslyshown = 0 "
502 "WHERE previouslyshown = 1 "
503 "AND originalairdate is not null "
504 "AND (to_days(starttime) - to_days(originalairdate)) "
506 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
509 LOG(VB_GENERAL, LOG_INFO,
515 updt.
prepare(
"UPDATE program SET first = 0, last = 0;");
519 LOG(VB_GENERAL, LOG_INFO,
"Marking episode first showings.");
521 "JOIN (SELECT MIN(p.starttime) AS starttime, p.programid "
522 " FROM program p, channel c "
523 " WHERE p.programid <> '' "
524 " AND p.chanid = c.chanid "
525 " AND c.deleted IS NULL "
526 " AND c.visible > 0 "
527 " GROUP BY p.programid "
529 "ON program.programid = firsts.programid "
530 " AND program.starttime = firsts.starttime "
531 "SET program.first=1;");
537 "JOIN (SELECT MIN(p.starttime) AS starttime, p.title, p.subtitle, "
538 " LEFT(p.description, 1024) AS partdesc "
539 " FROM program p, channel c "
540 " WHERE p.programid = '' "
541 " AND p.chanid = c.chanid "
542 " AND c.deleted IS NULL "
543 " AND c.visible > 0 "
544 " GROUP BY p.title, p.subtitle, partdesc "
546 "ON program.starttime = firsts.starttime "
547 " AND program.title = firsts.title "
548 " AND program.subtitle = firsts.subtitle "
549 " AND LEFT(program.description, 1024) = firsts.partdesc "
550 "SET program.first = 1 "
551 "WHERE program.programid = '';");
555 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
557 LOG(VB_GENERAL, LOG_INFO,
"Marking episode last showings.");
559 "JOIN (SELECT MAX(p.starttime) AS starttime, p.programid "
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.programid "
567 "ON program.programid = lasts.programid "
568 " AND program.starttime = lasts.starttime "
569 "SET program.last=1;");
575 "JOIN (SELECT MAX(p.starttime) AS starttime, p.title, p.subtitle, "
576 " LEFT(p.description, 1024) AS partdesc "
577 " FROM program p, channel c "
578 " WHERE p.programid = '' "
579 " AND p.chanid = c.chanid "
580 " AND c.deleted IS NULL "
581 " AND c.visible > 0 "
582 " GROUP BY p.title, p.subtitle, partdesc "
584 "ON program.starttime = lasts.starttime "
585 " AND program.title = lasts.title "
586 " AND program.subtitle = lasts.subtitle "
587 " AND LEFT(program.description, 1024) = lasts.partdesc "
588 "SET program.last = 1 "
589 "WHERE program.programid = '';");
593 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
598 query2.
prepare(
"SELECT count(previouslyshown) "
599 "FROM program WHERE previouslyshown = 1;");
602 if (query2.
value(0).toInt() != 0)
611 LOG(VB_GENERAL, LOG_INFO,
"\n"
612 "===============================================================\n"
613 "| Attempting to contact the master backend for rescheduling. |\n"
614 "| If the master is not running, rescheduling will happen when |\n"
615 "| the master backend is restarted. |\n"
616 "===============================================================");
626 LOG(VB_GENERAL, LOG_NOTICE,
"mythfilldatabase run complete.");
void SetRefresh(int day, bool set)
bool m_onlyUpdateChannels
bool GrabDataFromFile(int id, const QString &filename)
bool Run(DataSourceList &sourcelist)
Goes through the sourcelist and updates its channels with program info grabbed with the associated gr...
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
bool isNull(int field) const
QVariant value(int i) const
int numRowsAffected() const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
int toInt(const QString &key) const
Returns stored QVariant as an integer, falling to default if not provided.
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
QString GetPassthrough(void) const
Return any text supplied on the command line after a bare '–'.
static void PrintVersion(void)
Print application version information.
QStringList toStringList(const QString &key, const QString &sep="") const
Returns stored QVariant as a QStringList, falling to default if not provided.
void PrintHelp(void) const
Print command line option help.
Startup context for MythTV.
bool SafeConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
void SendSystemEvent(const QString &msg)
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
void SendMessage(const QString &message)
int GetNumSetting(const QString &key, int defaultval=0)
static void DBError(const QString &where, const MSqlQuery &query)
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
static int fix_end_times(void)
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed, const bool upgradeIfNoUI, const bool informSystemd)
Called from outside dbcheck.cpp to update the schema.
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
@ GENERIC_EXIT_DB_OUTOFDATE
Database needs upgrade.
@ GENERIC_EXIT_OK
Exited with no error.
@ GENERIC_EXIT_SETUP_ERROR
Incorrectly setup system.
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
@ GENERIC_EXIT_DB_ERROR
Database error.
@ GENERIC_EXIT_NOT_OK
Exited with error.
bool updateLastRunStatus(QString &status)
bool updateLastRunEnd(void)
bool updateLastRunStart(void)
std::vector< DataSource > DataSourceList
static constexpr const char * MYTH_APPNAME_MYTHFILLDATABASE
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
int main(int argc, char *argv[])
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void setHttpProxy(void)
Get network proxy settings from OS, and use for [Q]Http[Comms].
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
MythCommFlagCommandLineParser cmdline
bool xmltvgrabber_baseline
QString xmltvgrabber_prefmethod
bool xmltvgrabber_manualconfig