MythTV  master
filldata.cpp
Go to the documentation of this file.
1 // POSIX headers
2 #include <unistd.h>
3 
4 // C++ headers
5 #include <algorithm>
6 #include <cstdlib>
7 #include <ctime>
8 #include <fstream>
9 
10 // Qt headers
11 #include <QDateTime>
12 #include <QDir>
13 #include <QFile>
14 #include <QList>
15 #include <QMap>
16 #include <QTextStream>
17 
18 // MythTV headers
19 #include "libmythbase/compat.h"
20 #include "libmythbase/exitcodes.h"
22 #include "libmythbase/mythdate.h"
23 #include "libmythbase/mythdb.h"
24 #include "libmythbase/mythdbcon.h"
25 #include "libmythbase/mythdirs.h"
29 #include "libmythtv/videosource.h" // for is_grabber..
30 
31 // filldata headers
32 #include "filldata.h"
33 
34 #define LOC QString("FillData: ")
35 #define LOC_WARN QString("FillData, Warning: ")
36 #define LOC_ERR QString("FillData, Error: ")
37 
38 bool updateLastRunEnd(void)
39 {
40  QDateTime qdtNow = MythDate::current();
41  return gCoreContext->SaveSettingOnHost("mythfilldatabaseLastRunEnd",
42  qdtNow.toString(Qt::ISODate),
43  nullptr);
44 }
45 
47 {
49  QDateTime qdtNow = MythDate::current();
50  return gCoreContext->SaveSettingOnHost("mythfilldatabaseLastRunStart",
51  qdtNow.toString(Qt::ISODate),
52  nullptr);
53 }
54 
55 bool updateLastRunStatus(QString &status)
56 {
57  return gCoreContext->SaveSettingOnHost("mythfilldatabaseLastRunStatus",
58  status,
59  nullptr);
60 }
61 
63 {
64  QDateTime nextSuggestedTime = MythDate::current().addDays(1);
65  return gCoreContext->SaveSettingOnHost("MythFillSuggestedRunTime",
66  nextSuggestedTime.toString(Qt::ISODate),
67  nullptr);
68 }
69 
70 void FillData::SetRefresh(int day, bool set)
71 {
72  if (kRefreshClear == day)
73  {
74  m_refreshAll = set;
75  m_refreshDay.clear();
76  }
77  else if (kRefreshAll == day)
78  {
79  m_refreshAll = set;
80  }
81  else
82  {
83  m_refreshDay[(uint)day] = set;
84  }
85 }
86 
87 // XMLTV stuff
88 bool FillData::GrabDataFromFile(int id, const QString &filename)
89 {
90  ChannelInfoList chanlist;
91  QMap<QString, QList<ProgInfo> > proglist;
92 
93  if (!m_xmltvParser.parseFile(filename, &chanlist, &proglist))
94  return false;
95 
96  m_chanData.handleChannels(id, &chanlist);
98  {
99  if (proglist.count() != 0)
100  {
101  LOG(VB_GENERAL, LOG_INFO, "Skipping program guide updates");
102  }
103  }
104  else
105  {
106  if (proglist.count() == 0)
107  {
108  LOG(VB_GENERAL, LOG_INFO, "No programs found in data.");
109  m_endOfData = true;
110  }
111  else
112  {
113  ProgramData::HandlePrograms(id, proglist);
114  }
115  }
116  return true;
117 }
118 
119 bool FillData::GrabData(const DataSource& source, int offset)
120 {
121  QString xmltv_grabber = source.xmltvgrabber;
122 
123  const QString templatename = "/tmp/mythXXXXXX";
124  const QString tempfilename = createTempFile(templatename);
125  if (templatename == tempfilename)
126  {
127  m_fatalErrors.push_back("Failed to create temporary file.");
128  return false;
129  }
130 
131  QString filename = QString(tempfilename);
132 
133  QString configfile;
134 
135  MSqlQuery query1(MSqlQuery::InitCon());
136  query1.prepare("SELECT configpath FROM videosource"
137  " WHERE sourceid = :ID AND configpath IS NOT NULL");
138  query1.bindValue(":ID", source.id);
139  if (!query1.exec())
140  {
141  MythDB::DBError("FillData::grabData", query1);
142  return false;
143  }
144 
145  if (query1.next())
146  configfile = query1.value(0).toString();
147  else
148  configfile = QString("%1/%2.xmltv").arg(GetConfDir(), source.name);
149 
150  LOG(VB_GENERAL, LOG_INFO,
151  QString("XMLTV config file is: %1").arg(configfile));
152 
153  QString command = QString("nice %1 --config-file '%2' --output %3")
154  .arg(xmltv_grabber, configfile, filename);
155 
157  {
158  command += " --list-channels";
159  }
160  else if (source.xmltvgrabber_prefmethod != "allatonce" || m_noAllAtOnce || m_onlyUpdateChannels)
161  {
162  // XMLTV Docs don't recommend grabbing one day at a
163  // time but the current MythTV code is heavily geared
164  // that way so until it is re-written behave as
165  // we always have done.
166  command += QString(" --days 1 --offset %1").arg(offset);
167  }
168 
169  if (!VERBOSE_LEVEL_CHECK(VB_XMLTV, LOG_ANY))
170  command += " --quiet";
171 
172  // Append additional arguments passed to mythfilldatabase
173  // using --graboptions
174  if (!m_grabOptions.isEmpty())
175  {
176  command += m_grabOptions;
177  LOG(VB_XMLTV, LOG_INFO,
178  QString("Using graboptions: %1").arg(m_grabOptions));
179  }
180 
181  QString status = QObject::tr("currently running.");
182 
184  updateLastRunStatus(status);
185 
186  LOG(VB_XMLTV, LOG_INFO, QString("Grabber Command: %1").arg(command));
187 
188  LOG(VB_XMLTV, LOG_INFO,
189  "----------------- Start of XMLTV output -----------------");
190 
191  MythSystemLegacy run_grabber(command, kMSRunShell | kMSStdErr);
192 
193  run_grabber.Run();
194  uint systemcall_status = run_grabber.Wait();
195  bool succeeded = (systemcall_status == GENERIC_EXIT_OK);
196 
197  QByteArray result = run_grabber.ReadAllErr();
198  QTextStream ostream(result);
199  while (!ostream.atEnd())
200  {
201  QString line = ostream.readLine().simplified();
202  LOG(VB_XMLTV, LOG_INFO, line);
203  }
204 
205  LOG(VB_XMLTV, LOG_INFO,
206  "------------------ End of XMLTV output ------------------");
207 
209 
210  status = QObject::tr("Successful.");
211 
212  if (!succeeded)
213  {
214  if (systemcall_status == GENERIC_EXIT_KILLED)
215  {
216  m_interrupted = true;
217  status = QObject::tr("FAILED: XMLTV grabber ran but was interrupted.");
218  LOG(VB_GENERAL, LOG_ERR,
219  QString("XMLTV grabber ran but was interrupted."));
220  }
221  else
222  {
223  status = QObject::tr("FAILED: XMLTV grabber returned error code %1.")
224  .arg(systemcall_status);
225  LOG(VB_GENERAL, LOG_ERR,
226  QString("XMLTV grabber returned error code %1")
227  .arg(systemcall_status));
228  }
229  }
230 
231  updateLastRunStatus(status);
232 
233  succeeded &= GrabDataFromFile(source.id, filename);
234 
235  QFile thefile(filename);
236  thefile.remove();
237 
238  return succeeded;
239 }
240 
246 bool FillData::Run(DataSourceList &sourcelist)
247 {
248  DataSourceList::iterator it;
249 
250  QString status;
251  QString querystr;
252  MSqlQuery query(MSqlQuery::InitCon());
253  QDateTime GuideDataBefore;
254  QDateTime GuideDataAfter;
255  int failures = 0;
256  int externally_handled = 0;
257  int total_sources = sourcelist.size();
258  int source_channels = 0;
259 
260  QString sidStr = QString("Updating source #%1 (%2) with grabber %3");
261 
262  m_needPostGrabProc = false;
263  int nonewdata = 0;
264 
265  for (it = sourcelist.begin(); it != sourcelist.end(); ++it)
266  {
267  if (!m_fatalErrors.empty())
268  break;
269 
270  QString xmltv_grabber = (*it).xmltvgrabber;
271 
272  if (xmltv_grabber == "datadirect" ||
273  xmltv_grabber == "schedulesdirect1")
274  {
275  LOG(VB_GENERAL, LOG_ERR,
276  QString("Source %1 is configured to use the DataDirect guide"
277  "service from Schedules Direct. That service is no "
278  "longer supported by MythTV. Update to use one of "
279  "the XMLTV grabbers that use the JSON-based guide "
280  "service from Schedules Direct.")
281  .arg((*it).id));
282  continue;
283  }
284 
285  query.prepare("SELECT MAX(endtime) "
286  "FROM program p "
287  "LEFT JOIN channel c ON p.chanid=c.chanid "
288  "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
289  " AND manualid = 0 AND c.xmltvid != '';");
290  query.bindValue(":SRCID", (*it).id);
291 
292  if (query.exec() && query.next())
293  {
294  if (!query.isNull(0))
295  GuideDataBefore =
296  MythDate::fromString(query.value(0).toString());
297  }
298 
299  m_channelUpdateRun = false;
300  m_endOfData = false;
301 
302  if (xmltv_grabber == "eitonly")
303  {
304  LOG(VB_GENERAL, LOG_INFO,
305  QString("Source %1 configured to use only the "
306  "broadcasted guide data. Skipping.") .arg((*it).id));
307 
308  externally_handled++;
311  continue;
312  }
313  if (xmltv_grabber.trimmed().isEmpty() ||
314  xmltv_grabber == "/bin/true" ||
315  xmltv_grabber == "none")
316  {
317  LOG(VB_GENERAL, LOG_INFO,
318  QString("Source %1 configured with no grabber. Nothing to do.")
319  .arg((*it).id));
320 
321  externally_handled++;
324  continue;
325  }
326 
327  LOG(VB_GENERAL, LOG_INFO, sidStr.arg(QString::number((*it).id),
328  (*it).name,
329  xmltv_grabber));
330 
331  query.prepare(
332  "SELECT COUNT(chanid) FROM channel "
333  "WHERE deleted IS NULL AND "
334  " sourceid = :SRCID AND xmltvid != ''");
335  query.bindValue(":SRCID", (*it).id);
336 
337  if (query.exec() && query.next())
338  {
339  source_channels = query.value(0).toInt();
340  if (source_channels > 0)
341  {
342  LOG(VB_GENERAL, LOG_INFO,
343  QString("Found %1 channels for source %2 which use grabber")
344  .arg(source_channels).arg((*it).id));
345  }
346  else
347  {
348  LOG(VB_GENERAL, LOG_INFO,
349  QString("No channels are configured to use grabber (none have XMLTVIDs)."));
350  }
351  }
352  else
353  {
354  source_channels = 0;
355  LOG(VB_GENERAL, LOG_INFO,
356  QString("Can't get a channel count for source id %1")
357  .arg((*it).id));
358  }
359 
360  bool hasprefmethod = false;
361 
362  if (is_grabber_external(xmltv_grabber))
363  {
364  uint flags = kMSRunShell | kMSStdOut;
365  MythSystemLegacy grabber_capabilities_proc(xmltv_grabber,
366  QStringList("--capabilities"),
367  flags);
368  grabber_capabilities_proc.Run(25s);
369  if (grabber_capabilities_proc.Wait() != GENERIC_EXIT_OK)
370  {
371  LOG(VB_GENERAL, LOG_ERR,
372  QString("%1 --capabilities failed or we timed out waiting."
373  " You may need to upgrade your xmltv grabber")
374  .arg(xmltv_grabber));
375  }
376  else
377  {
378  QByteArray result = grabber_capabilities_proc.ReadAll();
379  QTextStream ostream(result);
380  QString capabilities;
381  while (!ostream.atEnd())
382  {
383  QString capability
384  = ostream.readLine().simplified();
385 
386  if (capability.isEmpty())
387  continue;
388 
389  capabilities += capability + ' ';
390 
391  if (capability == "baseline")
392  (*it).xmltvgrabber_baseline = true;
393 
394  if (capability == "manualconfig")
395  (*it).xmltvgrabber_manualconfig = true;
396 
397  if (capability == "cache")
398  (*it).xmltvgrabber_cache = true;
399 
400  if (capability == "apiconfig")
401  (*it).xmltvgrabber_apiconfig = true;
402 
403  if (capability == "lineups")
404  (*it).xmltvgrabber_lineups = true;
405 
406  if (capability == "preferredmethod")
407  hasprefmethod = true;
408  }
409  LOG(VB_GENERAL, LOG_INFO,
410  QString("Grabber has capabilities: %1") .arg(capabilities));
411  }
412  }
413 
414  if (hasprefmethod)
415  {
416  uint flags = kMSRunShell | kMSStdOut;
417  MythSystemLegacy grabber_method_proc(xmltv_grabber,
418  QStringList("--preferredmethod"),
419  flags);
420  grabber_method_proc.Run(15s);
421  if (grabber_method_proc.Wait() != GENERIC_EXIT_OK)
422  {
423  LOG(VB_GENERAL, LOG_ERR,
424  QString("%1 --preferredmethod failed or we timed out "
425  "waiting. You may need to upgrade your xmltv "
426  "grabber").arg(xmltv_grabber));
427  }
428  else
429  {
430  QTextStream ostream(grabber_method_proc.ReadAll());
431  (*it).xmltvgrabber_prefmethod =
432  ostream.readLine().simplified();
433 
434  LOG(VB_GENERAL, LOG_INFO, QString("Grabber prefers method: %1")
435  .arg((*it).xmltvgrabber_prefmethod));
436  }
437  }
438 
439  m_needPostGrabProc |= true;
440 
441  if ((*it).xmltvgrabber_prefmethod == "allatonce" && !m_noAllAtOnce && !m_onlyUpdateChannels)
442  {
443  if (!GrabData(*it, 0))
444  ++failures;
445  }
446  else if ((*it).xmltvgrabber_baseline)
447  {
448 
449  QDate qCurrentDate = MythDate::current().date();
450 
451  // We'll keep grabbing until it returns nothing
452  // Max days currently supported is 21
453  int grabdays = REFRESH_MAX;
454 
455  grabdays = (m_maxDays > 0) ? m_maxDays : grabdays;
456  grabdays = (m_onlyUpdateChannels) ? 1 : grabdays;
457 
458  std::vector<bool> refresh_request;
459  refresh_request.resize(grabdays, m_refreshAll);
460  if (!m_refreshAll)
461  {
462  // Set up days to grab if all is not specified
463  // If all was specified the vector was initialized
464  // with true in all occurrences.
465  for (int i = 0; i < grabdays; i++)
466  refresh_request[i] = m_refreshDay[i];
467  }
468 
469  for (int i = 0; i < grabdays; i++)
470  {
471  if (!m_fatalErrors.empty())
472  break;
473 
474  // We need to check and see if the current date has changed
475  // since we started in this loop. If it has, we need to adjust
476  // the value of 'i' to compensate for this.
477  if (MythDate::current().date() != qCurrentDate)
478  {
479  QDate newDate = MythDate::current().date();
480  i += (newDate.daysTo(qCurrentDate));
481  i = std::max(i, 0);
482  qCurrentDate = newDate;
483  }
484 
485  QString currDate(qCurrentDate.addDays(i).toString());
486 
487  LOG(VB_GENERAL, LOG_INFO, ""); // add a space between days
488  LOG(VB_GENERAL, LOG_INFO, "Checking day @ " +
489  QString("offset %1, date: %2").arg(i).arg(currDate));
490 
491  bool download_needed = false;
492 
493  if (refresh_request[i])
494  {
495  if ( i == 1 )
496  {
497  LOG(VB_GENERAL, LOG_INFO,
498  "Data Refresh always needed for tomorrow");
499  }
500  else
501  {
502  LOG(VB_GENERAL, LOG_INFO,
503  "Data Refresh needed because of user request");
504  }
505  download_needed = true;
506  }
507  else
508  {
509  // Check to see if we already downloaded data for this date.
510 
511  querystr = "SELECT c.chanid, COUNT(p.starttime) "
512  "FROM channel c "
513  "LEFT JOIN program p ON c.chanid = p.chanid "
514  " AND starttime >= "
515  "DATE_ADD(DATE_ADD(CURRENT_DATE(), "
516  "INTERVAL '%1' DAY), INTERVAL '20' HOUR) "
517  " AND starttime < DATE_ADD(CURRENT_DATE(), "
518  "INTERVAL '%2' DAY) "
519  "WHERE c.deleted IS NULL AND c.sourceid = %3 AND c.xmltvid != '' "
520  "GROUP BY c.chanid;";
521 
522  if (query.exec(querystr.arg(i-1).arg(i).arg((*it).id)) &&
523  query.isActive())
524  {
525  int prevChanCount = 0;
526  int currentChanCount = 0;
527  int previousDayCount = 0;
528  int currentDayCount = 0;
529 
530  LOG(VB_CHANNEL, LOG_INFO,
531  QString("Checking program counts for day %1")
532  .arg(i-1));
533 
534  while (query.next())
535  {
536  if (query.value(1).toInt() > 0)
537  prevChanCount++;
538  previousDayCount += query.value(1).toInt();
539 
540  LOG(VB_CHANNEL, LOG_INFO,
541  QString(" chanid %1 -> %2 programs")
542  .arg(query.value(0).toString())
543  .arg(query.value(1).toInt()));
544  }
545 
546  if (query.exec(querystr.arg(i).arg(i+1).arg((*it).id))
547  && query.isActive())
548  {
549  LOG(VB_CHANNEL, LOG_INFO,
550  QString("Checking program counts for day %1")
551  .arg(i));
552  while (query.next())
553  {
554  if (query.value(1).toInt() > 0)
555  currentChanCount++;
556  currentDayCount += query.value(1).toInt();
557 
558  LOG(VB_CHANNEL, LOG_INFO,
559  QString(" chanid %1 -> %2 programs")
560  .arg(query.value(0).toString())
561  .arg(query.value(1).toInt()));
562  }
563  }
564  else
565  {
566  LOG(VB_GENERAL, LOG_INFO,
567  QString("Data Refresh because we are unable to "
568  "query the data for day %1 to "
569  "determine if we have enough").arg(i));
570  download_needed = true;
571  }
572 
573  if (currentChanCount < (prevChanCount * 0.90))
574  {
575  LOG(VB_GENERAL, LOG_INFO,
576  QString("Data refresh needed because only %1 "
577  "out of %2 channels have at least one "
578  "program listed for day @ offset %3 "
579  "from 8PM - midnight. Previous day "
580  "had %4 channels with data in that "
581  "time period.")
582  .arg(currentChanCount).arg(source_channels)
583  .arg(i).arg(prevChanCount));
584  download_needed = true;
585  }
586  else if (currentDayCount == 0)
587  {
588  LOG(VB_GENERAL, LOG_INFO,
589  QString("Data refresh needed because no data "
590  "exists for day @ offset %1 from 8PM - "
591  "midnight.").arg(i));
592  download_needed = true;
593  }
594  else if (previousDayCount == 0)
595  {
596  LOG(VB_GENERAL, LOG_INFO,
597  QString("Data refresh needed because no data "
598  "exists for day @ offset %1 from 8PM - "
599  "midnight. Unable to calculate how "
600  "much we should have for the current "
601  "day so a refresh is being forced.")
602  .arg(i-1));
603  download_needed = true;
604  }
605  else if (currentDayCount < (currentChanCount * 3))
606  {
607  LOG(VB_GENERAL, LOG_INFO,
608  QString("Data Refresh needed because offset "
609  "day %1 has less than 3 programs "
610  "per channel for the 8PM - midnight "
611  "time window for channels that "
612  "normally have data. "
613  "We want at least %2 programs, but "
614  "only found %3")
615  .arg(i).arg(currentChanCount * 3)
616  .arg(currentDayCount));
617  download_needed = true;
618  }
619  else if (currentDayCount < (previousDayCount / 2))
620  {
621  LOG(VB_GENERAL, LOG_INFO,
622  QString("Data Refresh needed because offset "
623  "day %1 has less than half the number "
624  "of programs as the previous day for "
625  "the 8PM - midnight time window. "
626  "We want at least %2 programs, but "
627  "only found %3").arg(i)
628  .arg(previousDayCount / 2)
629  .arg(currentDayCount));
630  download_needed = true;
631  }
632  }
633  else
634  {
635  LOG(VB_GENERAL, LOG_INFO,
636  QString("Data Refresh needed because we are unable "
637  "to query the data for day @ offset %1 to "
638  "determine how much we should have for "
639  "offset day %2.").arg(i-1).arg(i));
640  download_needed = true;
641  }
642  }
643 
644  if (download_needed)
645  {
646  LOG(VB_GENERAL, LOG_NOTICE,
647  QString("Refreshing data for ") + currDate);
648  if (!GrabData(*it, i))
649  {
650  ++failures;
651  if (!m_fatalErrors.empty() || m_interrupted)
652  {
653  break;
654  }
655  }
656 
657  if (m_endOfData)
658  {
659  LOG(VB_GENERAL, LOG_INFO,
660  "Grabber is no longer returning program data, "
661  "finishing");
662  break;
663  }
664  }
665  else
666  {
667  LOG(VB_GENERAL, LOG_NOTICE,
668  QString("Data is already present for ") + currDate +
669  ", skipping");
670  }
671  }
672  if (!m_fatalErrors.empty())
673  break;
674  }
675  else
676  {
677  LOG(VB_GENERAL, LOG_ERR,
678  QString("Grabbing XMLTV data using ") + xmltv_grabber +
679  " is not supported. You may need to upgrade to"
680  " the latest version of XMLTV.");
681  }
682 
683  if (m_interrupted)
684  {
685  break;
686  }
687 
688  query.prepare("SELECT MAX(endtime) FROM program p "
689  "LEFT JOIN channel c ON p.chanid=c.chanid "
690  "WHERE c.deleted IS NULL AND c.sourceid= :SRCID "
691  "AND manualid = 0 AND c.xmltvid != '';");
692  query.bindValue(":SRCID", (*it).id);
693 
694  if (query.exec() && query.next())
695  {
696  if (!query.isNull(0))
697  GuideDataAfter = MythDate::fromString(query.value(0).toString());
698  }
699 
700  if (GuideDataAfter == GuideDataBefore)
701  {
702  nonewdata++;
703  }
704  }
705 
706  if (!m_fatalErrors.empty())
707  {
708  for (const QString& error : std::as_const(m_fatalErrors))
709  {
710  LOG(VB_GENERAL, LOG_CRIT, LOC + "Encountered Fatal Error: " + error);
711  }
712  return false;
713  }
714 
716  return true;
717 
718  if (failures == 0)
719  {
720  if (nonewdata > 0 &&
721  (total_sources != externally_handled))
722  {
723  status = QObject::tr(
724  "mythfilldatabase ran, but did not insert "
725  "any new data into the Guide for %1 of %2 sources. "
726  "This can indicate a potential grabber failure.")
727  .arg(nonewdata)
728  .arg(total_sources);
729  }
730  else
731  {
732  status = QObject::tr("Successful.");
733  }
734 
735  updateLastRunStatus(status);
736  }
737 
738  return (failures == 0);
739 }
740 
741 /* vim: set expandtab tabstop=4 shiftwidth=4: */
kMSStdErr
@ kMSStdErr
allow access to stderr
Definition: mythsystem.h:42
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MythSystemLegacy::ReadAllErr
QByteArray & ReadAllErr()
Definition: mythsystemlegacy.cpp:407
FillData::m_fatalErrors
QStringList m_fatalErrors
Definition: filldata.h:80
MSqlQuery::isNull
bool isNull(int field) const
Definition: mythdbcon.h:219
error
static void error(const char *str,...)
Definition: vbi.cpp:37
DataSource::xmltvgrabber
QString xmltvgrabber
Definition: filldata.h:29
mythdb.h
MythSystemLegacy
Definition: mythsystemlegacy.h:67
updateLastRunStart
bool updateLastRunStart(void)
Definition: filldata.cpp:46
ChannelData::handleChannels
void handleChannels(int id, ChannelInfoList *chanlist) const
Definition: channeldata.cpp:187
DataSourceList
std::vector< DataSource > DataSourceList
Definition: filldata.h:40
DataSource::name
QString name
Definition: filldata.h:28
FillData::m_refreshAll
bool m_refreshAll
Definition: filldata.h:79
VERBOSE_LEVEL_CHECK
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
Definition: mythlogging.h:29
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
mythdbcon.h
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythSystemLegacy::ReadAll
QByteArray & ReadAll()
Definition: mythsystemlegacy.cpp:402
mythdirs.h
filldata.h
DataSource
Definition: filldata.h:25
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
FillData::kRefreshAll
@ kRefreshAll
Definition: filldata.h:59
DataSource::xmltvgrabber_apiconfig
bool xmltvgrabber_apiconfig
Definition: filldata.h:36
mythsystemlegacy.h
mythdate.h
FillData::m_grabOptions
QString m_grabOptions
Definition: filldata.h:66
mythlogging.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:256
updateLastRunEnd
bool updateLastRunEnd(void)
Definition: filldata.cpp:38
LOC
#define LOC
Definition: filldata.cpp:34
FillData::kRefreshClear
@ kRefreshClear
Definition: filldata.h:58
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
compat.h
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
FillData::Run
bool Run(DataSourceList &sourcelist)
Goes through the sourcelist and updates its channels with program info grabbed with the associated gr...
Definition: filldata.cpp:246
REFRESH_MAX
static constexpr int8_t REFRESH_MAX
Definition: filldata.h:17
createTempFile
QString createTempFile(QString name_template, bool dir)
Definition: mythmiscutil.cpp:323
MythSystemLegacy::Wait
uint Wait(std::chrono::seconds timeout=0s)
Definition: mythsystemlegacy.cpp:243
is_grabber_external
static bool is_grabber_external(const QString &grabber)
Definition: videosource.h:29
GENERIC_EXIT_KILLED
@ GENERIC_EXIT_KILLED
Process killed or stopped.
Definition: exitcodes.h:26
FillData::m_chanData
ChannelData m_chanData
Definition: filldata.h:63
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
FillData::GrabData
bool GrabData(const DataSource &source, int offset)
Definition: filldata.cpp:119
kMSRunShell
@ kMSRunShell
run process through shell
Definition: mythsystem.h:43
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:39
FillData::GrabDataFromFile
bool GrabDataFromFile(int id, const QString &filename)
Definition: filldata.cpp:88
DataSource::xmltvgrabber_prefmethod
QString xmltvgrabber_prefmethod
Definition: filldata.h:38
mythmiscutil.h
FillData::m_onlyUpdateChannels
bool m_onlyUpdateChannels
Definition: filldata.h:73
mythcorecontext.h
FillData::m_endOfData
bool m_endOfData
Definition: filldata.h:70
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
FillData::SetRefresh
void SetRefresh(int day, bool set)
Definition: filldata.cpp:70
FillData::m_interrupted
bool m_interrupted
Definition: filldata.h:69
MythSystemLegacy::Run
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
Definition: mythsystemlegacy.cpp:213
ProgramData::HandlePrograms
static void HandlePrograms(uint sourceid, QMap< QString, QList< ProgInfo > > &proglist)
Called from mythfilldatabase to bulk insert data into the program database.
Definition: programdata.cpp:1548
FillData::m_noAllAtOnce
bool m_noAllAtOnce
Definition: filldata.h:75
FillData::m_channelUpdateRun
bool m_channelUpdateRun
Definition: filldata.h:74
updateLastRunStatus
bool updateLastRunStatus(QString &status)
Definition: filldata.cpp:55
exitcodes.h
DataSource::id
int id
Definition: filldata.h:27
build_compdb.filename
filename
Definition: build_compdb.py:21
FillData::m_needPostGrabProc
bool m_needPostGrabProc
Definition: filldata.h:72
FillData::m_xmltvParser
XMLTVParser m_xmltvParser
Definition: filldata.h:64
FillData::m_maxDays
uint m_maxDays
Definition: filldata.h:67
kMSStdOut
@ kMSStdOut
allow access to stdout
Definition: mythsystem.h:41
MythCoreContext::SaveSettingOnHost
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Definition: mythcorecontext.cpp:895
FillData::m_refreshDay
QMap< uint, bool > m_refreshDay
Definition: filldata.h:78
XMLTVParser::parseFile
bool parseFile(const QString &filename, ChannelInfoList *chanlist, QMap< QString, QList< ProgInfo > > *proglist)
Definition: xmltvparser.cpp:194
updateNextScheduledRun
bool updateNextScheduledRun()
Definition: filldata.cpp:62
videosource.h
uint
unsigned int uint
Definition: freesurround.h:24
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
ChannelInfoList
std::vector< ChannelInfo > ChannelInfoList
Definition: channelinfo.h:131