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" << std::endl
103 <<
"with both --sourceid and --xmlfile." << std::endl;
110 LOG(VB_GENERAL, LOG_INFO,
111 "Bypassing grabbers, reading directly from file");
127 std::cerr <<
"The --cardtype option must be used in combination" << std::endl
128 <<
"with a --sourceid option." << std::endl;
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(
"-"))
163 QStringList r = item.split(
"-");
165 uint lower = r[0].toUInt(&ok);
168 std::cerr << warn.toLocal8Bit().constData() << std::endl;
172 uint upper = r[1].toUInt(&ok);
175 std::cerr << warn.toLocal8Bit().constData() << std::endl;
181 std::cerr << warn.toLocal8Bit().constData() << std::endl;
185 for (
uint j = lower; j <= upper; ++j)
191 uint day = item.toUInt(&ok);
194 std::cerr << warn.toLocal8Bit().constData() << std::endl;
213 if (!context.Init(
false))
215 LOG(VB_GENERAL, LOG_ERR,
"Failed to init MythContext, exiting.");
225 LOG(VB_GENERAL, LOG_ERR,
"Incorrect database schema");
231 LOG(VB_GENERAL, LOG_INFO,
232 "Opening blocking connection to master backend");
236 LOG(VB_GENERAL, LOG_WARNING,
237 "Failed to connect to master backend. MythFillDatabase will "
238 "continue running but will be unable to prevent backend from "
239 "shutting down, or triggering a reschedule when complete.");
244 QString status = QObject::tr(
"currently running.");
245 QDateTime GuideDataBefore;
246 QDateTime GuideDataAfter;
252 query.
prepare(
"SELECT MAX(endtime) FROM program p "
253 "LEFT JOIN channel c ON p.chanid=c.chanid "
254 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
255 "AND manualid = 0 AND c.xmltvid != '';");
272 query.
prepare(
"SELECT MAX(endtime) FROM program p "
273 "LEFT JOIN channel c ON p.chanid=c.chanid "
274 "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
275 "AND manualid = 0 AND c.xmltvid != '';");
285 if (GuideDataAfter == GuideDataBefore)
287 status = QObject::tr(
"mythfilldatabase ran, but did not insert "
288 "any new data into the Guide. This can indicate a "
289 "potential problem with the XML file used for the update.");
293 status = QObject::tr(
"Successful.");
307 LOG(VB_GENERAL, LOG_INFO,
308 QString(
"Running for sourceid %1 ONLY because --sourceid "
309 "was given on command-line").arg(sourceid));
310 where = QString(
"WHERE sourceid = %1").arg(sourceid);
313 QString querystr = QString(
"SELECT sourceid,name,xmltvgrabber,userid,"
315 "FROM videosource ") + where +
316 QString(
" ORDER BY sourceid;");
318 if (sourcequery.
exec(querystr))
320 if (sourcequery.
size() > 0)
322 while (sourcequery.
next())
326 newsource.
id = sourcequery.
value(0).toInt();
327 newsource.
name = sourcequery.
value(1).toString();
329 newsource.
userid = sourcequery.
value(3).toString();
338 sourcelist.push_back(newsource);
343 LOG(VB_GENERAL, LOG_ERR,
344 "There are no channel sources defined, did you run "
345 "the setup program?");
355 if (!fill_data.
Run(sourcelist))
356 LOG(VB_GENERAL, LOG_ERR,
"Failed to fetch some program info");
358 LOG(VB_GENERAL, LOG_NOTICE,
"Data fetching complete.");
366 LOG(VB_GENERAL, LOG_INFO,
"Adjusting program database end times.");
368 if (update_count == -1)
369 LOG(VB_GENERAL, LOG_ERR,
"fix_end_times failed!");
371 LOG(VB_GENERAL, LOG_INFO,
372 QString(
" %1 replacements made").arg(update_count));
374 LOG(VB_GENERAL, LOG_INFO,
"Marking generic episodes.");
377 query.
prepare(
"UPDATE program SET generic = 1 WHERE "
378 "((programid = '' AND subtitle = '' AND description = '') OR "
379 " (programid <> '' AND category_type = 'series' AND "
380 " program.programid LIKE '%0000'));");
385 LOG(VB_GENERAL, LOG_INFO,
388 LOG(VB_GENERAL, LOG_INFO,
"Extending non-unique programids "
389 "with multiple parts.");
393 sel.
prepare(
"SELECT DISTINCT programid, partnumber, parttotal "
394 "FROM program WHERE partnumber > 0 AND parttotal > 0 AND "
395 "programid LIKE '%0000'");
399 repl.
prepare(
"UPDATE program SET programid = :NEWID "
400 "WHERE programid = :OLDID AND "
401 "partnumber = :PARTNUM AND "
402 "parttotal = :PARTTOTAL");
406 QString orig_programid = sel.
value(0).toString();
407 QString new_programid = orig_programid.left(10);
410 int partnum = sel.
value(1).toInt();
411 int parttotal = sel.
value(2).toInt();
413 part.setNum(parttotal);
414 new_programid.append(part.rightJustified(2,
'0'));
415 part.setNum(partnum);
416 new_programid.append(part.rightJustified(2,
'0'));
418 LOG(VB_GENERAL, LOG_INFO,
419 QString(
" %1 -> %2 (part %3 of %4)")
420 .arg(orig_programid, new_programid)
421 .arg(partnum).arg(parttotal));
424 repl.
bindValue(
":OLDID", orig_programid);
429 LOG(VB_GENERAL, LOG_INFO,
430 QString(
"Fudging programid from '%1' to '%2'")
431 .arg(orig_programid, new_programid));
440 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
442 LOG(VB_GENERAL, LOG_INFO,
"Fixing missing original airdates.");
443 query.
prepare(
"UPDATE program p "
445 " SELECT programid, MAX(originalairdate) maxoad "
447 " WHERE programid <> '' AND "
448 " originalairdate IS NOT NULL "
449 " GROUP BY programid ) oad "
450 " ON p.programid = oad.programid "
451 "SET p.originalairdate = oad.maxoad "
452 "WHERE p.originalairdate IS NULL");
456 LOG(VB_GENERAL, LOG_INFO,
457 QString(
" Found %1 with programids")
461 query.
prepare(
"UPDATE program p "
463 " SELECT title, subtitle, description, "
464 " MAX(originalairdate) maxoad "
466 " WHERE programid = '' AND "
467 " originalairdate IS NOT NULL "
468 " GROUP BY title, subtitle, description ) oad "
469 " ON p.programid = '' AND "
470 " p.title = oad.title AND "
471 " p.subtitle = oad.subtitle AND "
472 " p.description = oad.description "
473 "SET p.originalairdate = oad.maxoad "
474 "WHERE p.originalairdate IS NULL");
478 LOG(VB_GENERAL, LOG_INFO,
479 QString(
" Found %1 without programids")
485 LOG(VB_GENERAL, LOG_INFO,
"Marking repeats.");
490 query2.
prepare(
"UPDATE program SET previouslyshown = 1 "
491 "WHERE previouslyshown = 0 "
492 "AND originalairdate is not null "
493 "AND (to_days(starttime) - to_days(originalairdate)) "
495 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
498 LOG(VB_GENERAL, LOG_INFO,
501 LOG(VB_GENERAL, LOG_INFO,
"Unmarking new episode rebroadcast repeats.");
502 query2.
prepare(
"UPDATE program SET previouslyshown = 0 "
503 "WHERE previouslyshown = 1 "
504 "AND originalairdate is not null "
505 "AND (to_days(starttime) - to_days(originalairdate)) "
507 query2.
bindValue(
":NEWWINDOW", newEpiWindow);
510 LOG(VB_GENERAL, LOG_INFO,
516 updt.
prepare(
"UPDATE program SET first = 0, last = 0;");
520 LOG(VB_GENERAL, LOG_INFO,
"Marking episode first showings.");
522 "JOIN (SELECT MIN(p.starttime) AS starttime, p.programid "
523 " FROM program p, channel c "
524 " WHERE p.programid <> '' "
525 " AND p.chanid = c.chanid "
526 " AND c.deleted IS NULL "
527 " AND c.visible > 0 "
528 " GROUP BY p.programid "
530 "ON program.programid = firsts.programid "
531 " AND program.starttime = firsts.starttime "
532 "SET program.first=1;");
538 "JOIN (SELECT MIN(p.starttime) AS starttime, p.title, p.subtitle, "
539 " LEFT(p.description, 1024) AS partdesc "
540 " FROM program p, channel c "
541 " WHERE p.programid = '' "
542 " AND p.chanid = c.chanid "
543 " AND c.deleted IS NULL "
544 " AND c.visible > 0 "
545 " GROUP BY p.title, p.subtitle, partdesc "
547 "ON program.starttime = firsts.starttime "
548 " AND program.title = firsts.title "
549 " AND program.subtitle = firsts.subtitle "
550 " AND LEFT(program.description, 1024) = firsts.partdesc "
551 "SET program.first = 1 "
552 "WHERE program.programid = '';");
556 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
558 LOG(VB_GENERAL, LOG_INFO,
"Marking episode last showings.");
560 "JOIN (SELECT MAX(p.starttime) AS starttime, p.programid "
561 " FROM program p, channel c "
562 " WHERE p.programid <> '' "
563 " AND p.chanid = c.chanid "
564 " AND c.deleted IS NULL "
565 " AND c.visible > 0 "
566 " GROUP BY p.programid "
568 "ON program.programid = lasts.programid "
569 " AND program.starttime = lasts.starttime "
570 "SET program.last=1;");
576 "JOIN (SELECT MAX(p.starttime) AS starttime, p.title, p.subtitle, "
577 " LEFT(p.description, 1024) AS partdesc "
578 " FROM program p, channel c "
579 " WHERE p.programid = '' "
580 " AND p.chanid = c.chanid "
581 " AND c.deleted IS NULL "
582 " AND c.visible > 0 "
583 " GROUP BY p.title, p.subtitle, partdesc "
585 "ON program.starttime = lasts.starttime "
586 " AND program.title = lasts.title "
587 " AND program.subtitle = lasts.subtitle "
588 " AND LEFT(program.description, 1024) = lasts.partdesc "
589 "SET program.last = 1 "
590 "WHERE program.programid = '';");
594 LOG(VB_GENERAL, LOG_INFO, QString(
" Found %1").arg(found));
599 query2.
prepare(
"SELECT count(previouslyshown) "
600 "FROM program WHERE previouslyshown = 1;");
603 if (query2.
value(0).toInt() != 0)
612 LOG(VB_GENERAL, LOG_INFO,
"\n"
613 "===============================================================\n"
614 "| Attempting to contact the master backend for rescheduling. |\n"
615 "| If the master is not running, rescheduling will happen when |\n"
616 "| the master backend is restarted. |\n"
617 "===============================================================");
627 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