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