MythTV master
mythfilldatabase.cpp
Go to the documentation of this file.
1// C headers
2#include <unistd.h>
3
4// C++ headers
5#include <iostream>
6
7// Qt headers
8#include <QtGlobal>
9#include <QCoreApplication>
10#include <QFileInfo>
11
12// MythTV headers
13#include "libmyth/mythcontext.h"
16#include "libmythbase/mythconfig.h"
19#include "libmythbase/mythdb.h"
23#include "libmythbase/mythversion.h"
25#include "libmythtv/dbcheck.h"
28#include "libmythtv/videosource.h" // for is_grabber..
29
30// filldata headers
31#include "filldata.h"
33
34int main(int argc, char *argv[])
35{
36 FillData fill_data;
37 int fromfile_id = 1;
38 QString fromfile_name;
39 bool from_file = false;
40 bool mark_repeats = true;
41
42 int sourceid = -1;
43
45 if (!cmdline.Parse(argc, argv))
46 {
49 }
50
51 if (cmdline.toBool("showhelp"))
52 {
54 return GENERIC_EXIT_OK;
55 }
56
57 if (cmdline.toBool("showversion"))
58 {
60 return GENERIC_EXIT_OK;
61 }
62
63 QCoreApplication a(argc, argv);
64 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHFILLDATABASE);
65
66 myth_nice(19);
67
68 int retval = cmdline.ConfigureLogging();
69 if (retval != GENERIC_EXIT_OK)
70 return retval;
71
72 if (cmdline.toBool("manual"))
73 {
74 std::cout << "###\n";
75 std::cout << "### Running in manual channel configuration mode.\n";
76 std::cout << "### This will ask you questions about every channel.\n";
77 std::cout << "###\n";
78 fill_data.m_chanData.m_interactive = true;
79 }
80
81 if (cmdline.toBool("onlyguide"))
82 {
83 LOG(VB_GENERAL, LOG_NOTICE,
84 "Only updating guide data, channel and icon updates will be ignored");
85 fill_data.m_chanData.m_guideDataOnly = true;
86 }
87
88 if (cmdline.toBool("preset"))
89 {
90 std::cout << "###\n";
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";
94 std::cout << "###\n";
95 fill_data.m_chanData.m_channelPreset = true;
96 }
97
98 if (cmdline.toBool("file"))
99 {
100 // manual file mode
101 if (!cmdline.toBool("sourceid") ||
102 !cmdline.toBool("xmlfile"))
103 {
104 std::cerr << "The --file option must be used in combination" << std::endl
105 << "with both --sourceid and --xmlfile." << std::endl;
107 }
108
109 fromfile_id = cmdline.toInt("sourceid");
110 fromfile_name = cmdline.toString("xmlfile");
111
112 LOG(VB_GENERAL, LOG_INFO,
113 "Bypassing grabbers, reading directly from file");
114 from_file = true;
115 }
116
117 if (cmdline.toBool("dochannelupdates"))
118 fill_data.m_chanData.m_channelUpdates = true;
119 if (cmdline.toBool("nofilterchannels"))
120 fill_data.m_chanData.m_filterNewChannels = false;
121 if (!cmdline.GetPassthrough().isEmpty())
122 fill_data.m_grabOptions = " " + cmdline.GetPassthrough();
123 if (cmdline.toBool("sourceid"))
124 sourceid = cmdline.toInt("sourceid");
125 if (cmdline.toBool("cardtype"))
126 {
127 if (!cmdline.toBool("sourceid"))
128 {
129 std::cerr << "The --cardtype option must be used in combination" << std::endl
130 << "with a --sourceid option." << std::endl;
132 }
133
134 fill_data.m_chanData.m_cardType = cmdline.toString("cardtype")
135 .trimmed().toUpper();
136 }
137 if (cmdline.toBool("maxdays") && cmdline.toInt("maxdays") > 0)
138 {
139 fill_data.m_maxDays = cmdline.toInt("maxdays");
140 if (fill_data.m_maxDays == 1)
141 fill_data.SetRefresh(0, true);
142 }
143
144 QStringList sl = cmdline.toStringList("refresh");
145 if (!sl.isEmpty())
146 {
147 for (const auto & item : std::as_const(sl))
148 {
149 QString warn = QString("Invalid entry in --refresh list: %1")
150 .arg(item);
151
152 bool enable = !item.contains("not");
153
154 if (item.contains("today"))
155 fill_data.SetRefresh(0, enable);
156 else if (item.contains("tomorrow"))
157 fill_data.SetRefresh(1, enable);
158 else if (item.contains("second"))
159 fill_data.SetRefresh(2, enable);
160 else if (item.contains("all"))
161 fill_data.SetRefresh(FillData::kRefreshAll, enable);
162 else if (item.contains("-"))
163 {
164 bool ok = false;
165 QStringList r = item.split("-");
166
167 uint lower = r[0].toUInt(&ok);
168 if (!ok)
169 {
170 std::cerr << warn.toLocal8Bit().constData() << std::endl;
171 return 0;
172 }
173
174 uint upper = r[1].toUInt(&ok);
175 if (!ok)
176 {
177 std::cerr << warn.toLocal8Bit().constData() << std::endl;
178 return 0;
179 }
180
181 if (lower > upper)
182 {
183 std::cerr << warn.toLocal8Bit().constData() << std::endl;
184 return 0;
185 }
186
187 for (uint j = lower; j <= upper; ++j)
188 fill_data.SetRefresh(j, true);
189 }
190 else
191 {
192 bool ok = false;
193 uint day = item.toUInt(&ok);
194 if (!ok)
195 {
196 std::cerr << warn.toLocal8Bit().constData() << std::endl;
197 return 0;
198 }
199
200 fill_data.SetRefresh(day, true);
201 }
202 }
203 }
204
205 if (cmdline.toBool("dontrefreshtba"))
206 fill_data.m_refreshTba = false;
207 if (cmdline.toBool("onlychannels"))
208 fill_data.m_onlyUpdateChannels = true;
209 if (cmdline.toBool("noallatonce"))
210 fill_data.m_noAllAtOnce = true;
211
212 mark_repeats = cmdline.toBool("markrepeats");
213
214 MythContext context {MYTH_BINARY_VERSION};
215 if (!context.Init(false))
216 {
217 LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext, exiting.");
219 }
220
221 setHttpProxy();
222
223 MythTranslation::load("mythfrontend");
224
225 if (!UpgradeTVDatabaseSchema(false))
226 {
227 LOG(VB_GENERAL, LOG_ERR, "Incorrect database schema");
229 }
230
231 if (gCoreContext->SafeConnectToMasterServer(true, false))
232 {
233 LOG(VB_GENERAL, LOG_INFO,
234 "Opening blocking connection to master backend");
235 }
236 else
237 {
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.");
242 }
243
244 if (from_file)
245 {
246 QString status = QObject::tr("currently running.");
247 QDateTime GuideDataBefore;
248 QDateTime GuideDataAfter;
249
251 updateLastRunStatus(status);
252
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 != '';");
258 query.bindValue(":SRCID", fromfile_id);
259
260 if (query.exec() && query.next())
261 {
262 if (!query.isNull(0))
263 GuideDataBefore =
264 MythDate::fromString(query.value(0).toString());
265 }
266
267 if (!fill_data.GrabDataFromFile(fromfile_id, fromfile_name))
268 {
269 return GENERIC_EXIT_NOT_OK;
270 }
271
273
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 != '';");
278 query.bindValue(":SRCID", fromfile_id);
279
280 if (query.exec() && query.next())
281 {
282 if (!query.isNull(0))
283 GuideDataAfter =
284 MythDate::fromString(query.value(0).toString());
285 }
286
287 if (GuideDataAfter == GuideDataBefore)
288 {
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.");
292 }
293 else
294 {
295 status = QObject::tr("Successful.");
296 }
297
298 updateLastRunStatus(status);
299 }
300 else
301 {
302 DataSourceList sourcelist;
303
304 MSqlQuery sourcequery(MSqlQuery::InitCon());
305 QString where;
306
307 if (sourceid != -1)
308 {
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);
313 }
314
315 QString querystr = QString("SELECT sourceid,name,xmltvgrabber,userid,"
316 "password,lineupid "
317 "FROM videosource ") + where +
318 QString(" ORDER BY sourceid;");
319
320 if (sourcequery.exec(querystr))
321 {
322 if (sourcequery.size() > 0)
323 {
324 while (sourcequery.next())
325 {
326 DataSource newsource;
327
328 newsource.id = sourcequery.value(0).toInt();
329 newsource.name = sourcequery.value(1).toString();
330 newsource.xmltvgrabber = sourcequery.value(2).toString();
331 newsource.userid = sourcequery.value(3).toString();
332 newsource.password = sourcequery.value(4).toString();
333 newsource.lineupid = sourcequery.value(5).toString();
334
335 newsource.xmltvgrabber_baseline = false;
336 newsource.xmltvgrabber_manualconfig = false;
337 newsource.xmltvgrabber_cache = false;
338 newsource.xmltvgrabber_prefmethod = "";
339
340 sourcelist.push_back(newsource);
341 }
342 }
343 else
344 {
345 LOG(VB_GENERAL, LOG_ERR,
346 "There are no channel sources defined, did you run "
347 "the setup program?");
349 }
350 }
351 else
352 {
353 MythDB::DBError("loading channel sources", sourcequery);
355 }
356
357 if (!fill_data.Run(sourcelist))
358 LOG(VB_GENERAL, LOG_ERR, "Failed to fetch some program info");
359 else
360 LOG(VB_GENERAL, LOG_NOTICE, "Data fetching complete.");
361 }
362
363 if (fill_data.m_onlyUpdateChannels && !fill_data.m_needPostGrabProc)
364 {
365 return GENERIC_EXIT_OK;
366 }
367
368 LOG(VB_GENERAL, LOG_INFO, "Adjusting program database end times.");
369 int update_count = ProgramData::fix_end_times();
370 if (update_count == -1)
371 LOG(VB_GENERAL, LOG_ERR, "fix_end_times failed!");
372 else
373 LOG(VB_GENERAL, LOG_INFO,
374 QString(" %1 replacements made").arg(update_count));
375
376 LOG(VB_GENERAL, LOG_INFO, "Marking generic episodes.");
377
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'));");
383
384 if (!query.exec())
385 MythDB::DBError("mark generic", query);
386 else
387 LOG(VB_GENERAL, LOG_INFO,
388 QString(" Found %1").arg(query.numRowsAffected()));
389
390 LOG(VB_GENERAL, LOG_INFO, "Extending non-unique programids "
391 "with multiple parts.");
392
393 int found = 0;
395 sel.prepare("SELECT DISTINCT programid, partnumber, parttotal "
396 "FROM program WHERE partnumber > 0 AND parttotal > 0 AND "
397 "programid LIKE '%0000'");
398 if (sel.exec())
399 {
401 repl.prepare("UPDATE program SET programid = :NEWID "
402 "WHERE programid = :OLDID AND "
403 "partnumber = :PARTNUM AND "
404 "parttotal = :PARTTOTAL");
405
406 while (sel.next())
407 {
408 QString orig_programid = sel.value(0).toString();
409 QString new_programid = orig_programid.left(10);
410 QString part;
411
412 int partnum = sel.value(1).toInt();
413 int parttotal = sel.value(2).toInt();
414
415 part.setNum(parttotal);
416 new_programid.append(part.rightJustified(2, '0'));
417 part.setNum(partnum);
418 new_programid.append(part.rightJustified(2, '0'));
419
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));
424
425 repl.bindValue(":NEWID", new_programid);
426 repl.bindValue(":OLDID", orig_programid);
427 repl.bindValue(":PARTNUM", partnum);
428 repl.bindValue(":PARTTOTAL", parttotal);
429 if (!repl.exec())
430 {
431 LOG(VB_GENERAL, LOG_INFO,
432 QString("Fudging programid from '%1' to '%2'")
433 .arg(orig_programid, new_programid));
434 }
435 else
436 {
437 found += repl.numRowsAffected();
438 }
439 }
440 }
441
442 LOG(VB_GENERAL, LOG_INFO, QString(" Found %1").arg(found));
443
444 LOG(VB_GENERAL, LOG_INFO, "Fixing missing original airdates.");
445 query.prepare("UPDATE program p "
446 "JOIN ( "
447 " SELECT programid, MAX(originalairdate) maxoad "
448 " FROM program "
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");
455
456 if (query.exec())
457 {
458 LOG(VB_GENERAL, LOG_INFO,
459 QString(" Found %1 with programids")
460 .arg(query.numRowsAffected()));
461 }
462
463 query.prepare("UPDATE program p "
464 "JOIN ( "
465 " SELECT title, subtitle, description, "
466 " MAX(originalairdate) maxoad "
467 " FROM program "
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");
477
478 if (query.exec())
479 {
480 LOG(VB_GENERAL, LOG_INFO,
481 QString(" Found %1 without programids")
482 .arg(query.numRowsAffected()));
483 }
484
485 if (mark_repeats)
486 {
487 LOG(VB_GENERAL, LOG_INFO, "Marking repeats.");
488
489 int newEpiWindow = gCoreContext->GetNumSetting( "NewEpisodeWindow", 14);
490
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)) "
496 " > :NEWWINDOW;");
497 query2.bindValue(":NEWWINDOW", newEpiWindow);
498
499 if (query2.exec())
500 LOG(VB_GENERAL, LOG_INFO,
501 QString(" Found %1").arg(query2.numRowsAffected()));
502
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)) "
508 " <= :NEWWINDOW;");
509 query2.bindValue(":NEWWINDOW", newEpiWindow);
510
511 if (query2.exec())
512 LOG(VB_GENERAL, LOG_INFO,
513 QString(" Found %1").arg(query2.numRowsAffected()));
514 }
515
516 // Mark first and last showings
518 updt.prepare("UPDATE program SET first = 0, last = 0;");
519 if (!updt.exec())
520 MythDB::DBError("Clearing first and last showings", updt);
521
522 LOG(VB_GENERAL, LOG_INFO, "Marking episode first showings.");
523 updt.prepare("UPDATE program "
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 "
531 " ) AS firsts "
532 "ON program.programid = firsts.programid "
533 " AND program.starttime = firsts.starttime "
534 "SET program.first=1;");
535 if (!updt.exec())
536 MythDB::DBError("Marking first showings by id", updt);
537 found = updt.numRowsAffected();
538
539 updt.prepare("UPDATE program "
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 "
548 " ) AS firsts "
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 = '';");
555 if (!updt.exec())
556 MythDB::DBError("Marking first showings", updt);
557 found += updt.numRowsAffected();
558 LOG(VB_GENERAL, LOG_INFO, QString(" Found %1").arg(found));
559
560 LOG(VB_GENERAL, LOG_INFO, "Marking episode last showings.");
561 updt.prepare("UPDATE program "
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 "
569 " ) AS lasts "
570 "ON program.programid = lasts.programid "
571 " AND program.starttime = lasts.starttime "
572 "SET program.last=1;");
573 if (!updt.exec())
574 MythDB::DBError("Marking last showings by id", updt);
575 found = updt.numRowsAffected();
576
577 updt.prepare("UPDATE program "
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 "
586 " ) AS lasts "
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 = '';");
593 if (!updt.exec())
594 MythDB::DBError("Marking last showings", updt);
595 found += updt.numRowsAffected();
596 LOG(VB_GENERAL, LOG_INFO, QString(" Found %1").arg(found));
597
598#if 1
599 // limit MSqlQuery's lifetime
601 query2.prepare("SELECT count(previouslyshown) "
602 "FROM program WHERE previouslyshown = 1;");
603 if (query2.exec() && query2.next())
604 {
605 if (query2.value(0).toInt() != 0)
606 gCoreContext->SaveSettingOnHost("HaveRepeats", "1", nullptr);
607 else
608 gCoreContext->SaveSettingOnHost("HaveRepeats", "0", nullptr);
609 }
610#endif
611
612 if (!cmdline.toBool("noresched"))
613 {
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 "===============================================================");
620
621 ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
622 "MythFillDatabase");
623 }
624
625 gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE");
626
627 gCoreContext->SendSystemEvent("MYTHFILLDATABASE_RAN");
628
629 LOG(VB_GENERAL, LOG_NOTICE, "mythfilldatabase run complete.");
630
631 return GENERIC_EXIT_OK;
632}
633
634/* vim: set expandtab tabstop=4 shiftwidth=4: */
bool m_interactive
Definition: channeldata.h:28
bool m_guideDataOnly
Definition: channeldata.h:29
bool m_channelPreset
Definition: channeldata.h:30
QString m_cardType
Definition: channeldata.h:33
bool m_filterNewChannels
Definition: channeldata.h:32
bool m_channelUpdates
Definition: channeldata.h:31
bool m_noAllAtOnce
Definition: filldata.h:75
void SetRefresh(int day, bool set)
Definition: filldata.cpp:69
QString m_grabOptions
Definition: filldata.h:66
bool m_onlyUpdateChannels
Definition: filldata.h:73
bool GrabDataFromFile(int id, const QString &filename)
Definition: filldata.cpp:87
uint m_maxDays
Definition: filldata.h:67
bool m_needPostGrabProc
Definition: filldata.h:72
bool Run(DataSourceList &sourcelist)
Goes through the sourcelist and updates its channels with program info grabbed with the associated gr...
Definition: filldata.cpp:245
bool m_refreshTba
Definition: filldata.h:71
ChannelData m_chanData
Definition: filldata.h:63
@ kRefreshAll
Definition: filldata.h:59
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
bool isNull(int field) const
Definition: mythdbcon.h:219
QVariant value(int i) const
Definition: mythdbcon.h:204
int size(void) const
Definition: mythdbcon.h:214
int numRowsAffected() const
Definition: mythdbcon.h:217
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
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.
Definition: mythcontext.h:20
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)
Definition: mythdb.cpp:226
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.
Definition: dbcheck.cpp:362
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:16
@ GENERIC_EXIT_DB_OUTOFDATE
Database needs upgrade.
Definition: exitcodes.h:19
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
@ GENERIC_EXIT_SETUP_ERROR
Incorrectly setup system.
Definition: exitcodes.h:24
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:18
@ GENERIC_EXIT_DB_ERROR
Database error.
Definition: exitcodes.h:20
@ GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:14
bool updateLastRunStatus(QString &status)
Definition: filldata.cpp:54
bool updateLastRunEnd(void)
Definition: filldata.cpp:37
bool updateLastRunStart(void)
Definition: filldata.cpp:45
std::vector< DataSource > DataSourceList
Definition: filldata.h:40
unsigned int uint
Definition: freesurround.h:24
static constexpr const char * MYTH_APPNAME_MYTHFILLDATABASE
Definition: mythappname.h:8
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_)
Definition: mythlogging.h:39
void setHttpProxy(void)
Get network proxy settings from OS, and use for [Q]Http[Comms].
bool myth_nice(int val)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:39
bool xmltvgrabber_baseline
Definition: filldata.h:33
bool xmltvgrabber_cache
Definition: filldata.h:35
QString lineupid
Definition: filldata.h:32
QString xmltvgrabber
Definition: filldata.h:29
QString name
Definition: filldata.h:28
int id
Definition: filldata.h:27
QString userid
Definition: filldata.h:30
QString xmltvgrabber_prefmethod
Definition: filldata.h:38
QString password
Definition: filldata.h:31
bool xmltvgrabber_manualconfig
Definition: filldata.h:34