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