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