9#include <QCoreApplication>
16#include "libmythbase/mythconfig.h"
23#include "libmythbase/mythversion.h"
34int main(
int argc,
char *argv[])
38 QString fromfile_name;
39 bool from_file =
false;
40 bool mark_repeats =
true;
63 QCoreApplication a(argc, argv);
75 std::cout <<
"### Running in manual channel configuration mode.\n";
76 std::cout <<
"### This will ask you questions about every channel.\n";
83 LOG(VB_GENERAL, LOG_NOTICE,
84 "Only updating guide data, channel and icon updates will be ignored");
91 std::cout <<
"### Running in preset channel configuration mode.\n";
92 std::cout <<
"### This will assign channel ";
93 std::cout <<
"preset numbers to every channel.\n";
104 std::cerr <<
"The --file option must be used in combination" << std::endl
105 <<
"with both --sourceid and --xmlfile." << std::endl;
112 LOG(VB_GENERAL, LOG_INFO,
113 "Bypassing grabbers, reading directly from file");
129 std::cerr <<
"The --cardtype option must be used in combination" << std::endl
130 <<
"with a --sourceid option." << std::endl;
135 .trimmed().toUpper();
147 for (
const auto & item : std::as_const(sl))
149 QString warn = QString(
"Invalid entry in --refresh list: %1")
152 bool enable = !item.contains(
"not");
154 if (item.contains(
"today"))
156 else if (item.contains(
"tomorrow"))
158 else if (item.contains(
"second"))
160 else if (item.contains(
"all"))
162 else if (item.contains(
"-"))
165 QStringList r = item.split(
"-");
167 uint lower = r[0].toUInt(&ok);
170 std::cerr << warn.toLocal8Bit().constData() << std::endl;
174 uint upper = r[1].toUInt(&ok);
177 std::cerr << warn.toLocal8Bit().constData() << std::endl;
183 std::cerr << warn.toLocal8Bit().constData() << std::endl;
187 for (
uint j = lower; j <= upper; ++j)
193 uint day = item.toUInt(&ok);
196 std::cerr << warn.toLocal8Bit().constData() << std::endl;
215 if (!context.Init(
false))
217 LOG(VB_GENERAL, LOG_ERR,
"Failed to init MythContext, exiting.");
227 LOG(VB_GENERAL, LOG_ERR,
"Incorrect database schema");
233 LOG(VB_GENERAL, LOG_INFO,
234 "Opening blocking connection to master backend");
238 LOG(VB_GENERAL, LOG_WARNING,
239 "Failed to connect to master backend. MythFillDatabase will "
240 "continue running but will be unable to prevent backend from "
241 "shutting down, or triggering a reschedule when complete.");
246 QString status = QObject::tr(
"currently running.");
247 QDateTime GuideDataBefore;
248 QDateTime GuideDataAfter;
254 query.
prepare(
"SELECT MAX(endtime) FROM program p "
255 "LEFT JOIN channel c ON p.chanid=c.chanid "
256 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
257 "AND manualid = 0 AND c.xmltvid != '';");
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 != '';");
287 if (GuideDataAfter == GuideDataBefore)
289 status = QObject::tr(
"mythfilldatabase ran, but did not insert "
290 "any new data into the Guide. This can indicate a "
291 "potential problem with the XML file used for the update.");
295 status = QObject::tr(
"Successful.");
309 LOG(VB_GENERAL, LOG_INFO,
310 QString(
"Running for sourceid %1 ONLY because --sourceid "
311 "was given on command-line").arg(sourceid));
312 where = QString(
"WHERE sourceid = %1").arg(sourceid);
315 QString querystr = QString(
"SELECT sourceid,name,xmltvgrabber,userid,"
317 "FROM videosource ") + where +
318 QString(
" ORDER BY sourceid;");
320 if (sourcequery.
exec(querystr))
322 if (sourcequery.
size() > 0)
324 while (sourcequery.
next())
328 newsource.
id = sourcequery.
value(0).toInt();
329 newsource.
name = sourcequery.
value(1).toString();
331 newsource.
userid = sourcequery.
value(3).toString();
340 sourcelist.push_back(newsource);
345 LOG(VB_GENERAL, LOG_ERR,
346 "There are no channel sources defined, did you run "
347 "the setup program?");
357 if (!fill_data.
Run(sourcelist))
358 LOG(VB_GENERAL, LOG_ERR,
"Failed to fetch some program info");
360 LOG(VB_GENERAL, LOG_NOTICE,
"Data fetching complete.");
368 LOG(VB_GENERAL, LOG_INFO,
"Adjusting program database end times.");
370 if (update_count == -1)
371 LOG(VB_GENERAL, LOG_ERR,
"fix_end_times failed!");
373 LOG(VB_GENERAL, LOG_INFO,
374 QString(
" %1 replacements made").arg(update_count));
376 LOG(VB_GENERAL, LOG_INFO,
"Marking generic episodes.");
379 query.
prepare(
"UPDATE program SET generic = 1 WHERE "
380 "((programid = '' AND subtitle = '' AND description = '') OR "
381 " (programid <> '' AND category_type = 'series' AND "
382 " program.programid LIKE '%0000'));");
387 LOG(VB_GENERAL, LOG_INFO,
390 LOG(VB_GENERAL, LOG_INFO,
"Extending non-unique programids "
391 "with multiple parts.");
395 sel.
prepare(
"SELECT DISTINCT programid, partnumber, parttotal "
396 "FROM program WHERE partnumber > 0 AND parttotal > 0 AND "
397 "programid LIKE '%0000'");
401 repl.
prepare(
"UPDATE program SET programid = :NEWID "
402 "WHERE programid = :OLDID AND "
403 "partnumber = :PARTNUM AND "
404 "parttotal = :PARTTOTAL");
408 QString orig_programid = sel.
value(0).toString();
409 QString new_programid = orig_programid.left(10);
412 int partnum = sel.
value(1).toInt();
413 int parttotal = sel.
value(2).toInt();
415 part.setNum(parttotal);
416 new_programid.append(part.rightJustified(2,
'0'));
417 part.setNum(partnum);
418 new_programid.append(part.rightJustified(2,
'0'));
420 LOG(VB_GENERAL, LOG_INFO,
421 QString(
" %1 -> %2 (part %3 of %4)")
422 .arg(orig_programid, new_programid)
423 .arg(partnum).arg(parttotal));
426 repl.
bindValue(
":OLDID", orig_programid);
431 LOG(VB_GENERAL, LOG_INFO,
432 QString(
"Fudging programid from '%1' to '%2'")
433 .arg(orig_programid, new_programid));
442 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
444 LOG(VB_GENERAL, LOG_INFO,
"Fixing missing original airdates.");
445 query.
prepare(
"UPDATE program p "
447 " SELECT programid, MAX(originalairdate) maxoad "
449 " WHERE programid <> '' AND "
450 " originalairdate IS NOT NULL "
451 " GROUP BY programid ) oad "
452 " ON p.programid = oad.programid "
453 "SET p.originalairdate = oad.maxoad "
454 "WHERE p.originalairdate IS NULL");
458 LOG(VB_GENERAL, LOG_INFO,
459 QString(
" Found %1 with programids")
463 query.
prepare(
"UPDATE program p "
465 " SELECT title, subtitle, description, "
466 " MAX(originalairdate) maxoad "
468 " WHERE programid = '' AND "
469 " originalairdate IS NOT NULL "
470 " GROUP BY title, subtitle, description ) oad "
471 " ON p.programid = '' AND "
472 " p.title = oad.title AND "
473 " p.subtitle = oad.subtitle AND "
474 " p.description = oad.description "
475 "SET p.originalairdate = oad.maxoad "
476 "WHERE p.originalairdate IS NULL");
480 LOG(VB_GENERAL, LOG_INFO,
481 QString(
" Found %1 without programids")
487 LOG(VB_GENERAL, LOG_INFO,
"Marking repeats.");
492 query2.
prepare(
"UPDATE program SET previouslyshown = 1 "
493 "WHERE previouslyshown = 0 "
494 "AND originalairdate is not null "
495 "AND (to_days(starttime) - to_days(originalairdate)) "
497 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
500 LOG(VB_GENERAL, LOG_INFO,
503 LOG(VB_GENERAL, LOG_INFO,
"Unmarking new episode rebroadcast repeats.");
504 query2.
prepare(
"UPDATE program SET previouslyshown = 0 "
505 "WHERE previouslyshown = 1 "
506 "AND originalairdate is not null "
507 "AND (to_days(starttime) - to_days(originalairdate)) "
509 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
512 LOG(VB_GENERAL, LOG_INFO,
518 updt.
prepare(
"UPDATE program SET first = 0, last = 0;");
522 LOG(VB_GENERAL, LOG_INFO,
"Marking episode first showings.");
524 "JOIN (SELECT MIN(p.starttime) AS starttime, p.programid "
525 " FROM program p, channel c "
526 " WHERE p.programid <> '' "
527 " AND p.chanid = c.chanid "
528 " AND c.deleted IS NULL "
529 " AND c.visible > 0 "
530 " GROUP BY p.programid "
532 "ON program.programid = firsts.programid "
533 " AND program.starttime = firsts.starttime "
534 "SET program.first=1;");
540 "JOIN (SELECT MIN(p.starttime) AS starttime, p.title, p.subtitle, "
541 " LEFT(p.description, 1024) AS partdesc "
542 " FROM program p, channel c "
543 " WHERE p.programid = '' "
544 " AND p.chanid = c.chanid "
545 " AND c.deleted IS NULL "
546 " AND c.visible > 0 "
547 " GROUP BY p.title, p.subtitle, partdesc "
549 "ON program.starttime = firsts.starttime "
550 " AND program.title = firsts.title "
551 " AND program.subtitle = firsts.subtitle "
552 " AND LEFT(program.description, 1024) = firsts.partdesc "
553 "SET program.first = 1 "
554 "WHERE program.programid = '';");
558 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
560 LOG(VB_GENERAL, LOG_INFO,
"Marking episode last showings.");
562 "JOIN (SELECT MAX(p.starttime) AS starttime, p.programid "
563 " FROM program p, channel c "
564 " WHERE p.programid <> '' "
565 " AND p.chanid = c.chanid "
566 " AND c.deleted IS NULL "
567 " AND c.visible > 0 "
568 " GROUP BY p.programid "
570 "ON program.programid = lasts.programid "
571 " AND program.starttime = lasts.starttime "
572 "SET program.last=1;");
578 "JOIN (SELECT MAX(p.starttime) AS starttime, p.title, p.subtitle, "
579 " LEFT(p.description, 1024) AS partdesc "
580 " FROM program p, channel c "
581 " WHERE p.programid = '' "
582 " AND p.chanid = c.chanid "
583 " AND c.deleted IS NULL "
584 " AND c.visible > 0 "
585 " GROUP BY p.title, p.subtitle, partdesc "
587 "ON program.starttime = lasts.starttime "
588 " AND program.title = lasts.title "
589 " AND program.subtitle = lasts.subtitle "
590 " AND LEFT(program.description, 1024) = lasts.partdesc "
591 "SET program.last = 1 "
592 "WHERE program.programid = '';");
596 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
601 query2.
prepare(
"SELECT count(previouslyshown) "
602 "FROM program WHERE previouslyshown = 1;");
605 if (query2.
value(0).toInt() != 0)
614 LOG(VB_GENERAL, LOG_INFO,
"\n"
615 "===============================================================\n"
616 "| Attempting to contact the master backend for rescheduling. |\n"
617 "| If the master is not running, rescheduling will happen when |\n"
618 "| the master backend is restarted. |\n"
619 "===============================================================");
629 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
MythCommFlagCommandLineParser cmdline
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.
bool xmltvgrabber_baseline
QString xmltvgrabber_prefmethod
bool xmltvgrabber_manualconfig