MythTV  master
backendhousekeeper.cpp
Go to the documentation of this file.
1 // POSIX headers
2 #include <unistd.h>
3 #include <sys/types.h>
4 
5 // ANSI C headers
6 #include <cstdlib>
7 
8 // Qt headers
9 #include <QStringList>
10 #include <QDateTime>
11 #include <QDir>
12 #include <QFileInfo>
13 
14 // MythTV headers
15 #include "backendhousekeeper.h"
16 #include "mythdb.h"
17 #include "mythdirs.h"
18 #include "jobqueue.h"
19 #include "exitcodes.h"
20 #include "mythsystemlegacy.h"
21 #include "mythversion.h"
22 #include "mythcoreutil.h"
23 #include "programtypes.h"
24 #include "recordingtypes.h"
25 #include "mythcorecontext.h"
26 #include "mythdownloadmanager.h"
27 #include "musicmetadata.h"
28 
29 #include "enums/recStatus.h"
30 
32 {
33  int numdays = 14;
34  uint64_t maxrows = 10000 * numdays; // likely high enough to keep numdays
35  bool res = true;
36 
38  if (query.isConnected())
39  {
40  // Remove less-important logging after 1/2 * numdays days
41  QDateTime days = MythDate::current();
42  days = days.addDays(0 - (numdays / 2));
43  QString sql = "DELETE FROM logging "
44  " WHERE application NOT IN (:MYTHBACKEND, :MYTHFRONTEND) "
45  " AND msgtime < :DAYS ;";
46  query.prepare(sql);
47  query.bindValue(":MYTHBACKEND", MYTH_APPNAME_MYTHBACKEND);
48  query.bindValue(":MYTHFRONTEND", MYTH_APPNAME_MYTHFRONTEND);
49  query.bindValue(":DAYS", days);
50  LOG(VB_GENERAL, LOG_DEBUG,
51  QString("Deleting helper application database log entries "
52  "from before %1.") .arg(days.toString(Qt::ISODate)));
53  if (!query.exec())
54  {
55  MythDB::DBError("Delete helper application log entries", query);
56  res = false;
57  }
58 
59  // Remove backend/frontend logging after numdays days
60  days = MythDate::current();
61  days = days.addDays(0 - numdays);
62  sql = "DELETE FROM logging WHERE msgtime < :DAYS ;";
63  query.prepare(sql);
64  query.bindValue(":DAYS", days);
65  LOG(VB_GENERAL, LOG_DEBUG,
66  QString("Deleting database log entries from before %1.")
67  .arg(days.toString(Qt::ISODate)));
68  if (!query.exec())
69  {
70  MythDB::DBError("Delete old log entries", query);
71  res = false;
72  }
73 
74  sql = "SELECT COUNT(id) FROM logging;";
75  query.prepare(sql);
76  if (query.exec())
77  {
78  uint64_t totalrows = 0;
79  while (query.next())
80  {
81  totalrows = query.value(0).toLongLong();
82  LOG(VB_GENERAL, LOG_DEBUG,
83  QString("Database has %1 log entries.").arg(totalrows));
84  }
85  if (totalrows > maxrows)
86  {
87  sql = "DELETE FROM logging ORDER BY msgtime LIMIT :ROWS;";
88  query.prepare(sql);
89  quint64 extrarows = totalrows - maxrows;
90  query.bindValue(":ROWS", extrarows);
91  LOG(VB_GENERAL, LOG_DEBUG,
92  QString("Deleting oldest %1 database log entries.")
93  .arg(extrarows));
94  if (!query.exec())
95  {
96  MythDB::DBError("Delete excess log entries", query);
97  res = false;
98  }
99  }
100  }
101  else
102  {
103  MythDB::DBError("Query logging table size", query);
104  res = false;
105  }
106  }
107 
108  return res;
109 }
110 
112 {
120  return true;
121 }
122 
124 {
126 
127  query.prepare("DELETE FROM inuseprograms "
128  "WHERE hostname = :HOSTNAME AND "
129  "( recusage = 'recorder' OR recusage LIKE 'Unknown %' );");
130  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
131  if (!query.exec())
132  MythDB::DBError("CleanupTask::CleanupOldRecordings", query);
133 }
134 
136 {
137  QDateTime fourHoursAgo = MythDate::current().addSecs(-4 * 60 * 60);
139 
140  query.prepare("DELETE FROM inuseprograms "
141  "WHERE lastupdatetime < :FOURHOURSAGO ;");
142  query.bindValue(":FOURHOURSAGO", fourHoursAgo);
143  if (!query.exec())
144  MythDB::DBError("CleanupTask::CleanupInUsePrograms", query);
145 }
146 
148 {
149  QDateTime fourHoursAgo = MythDate::current().addSecs(-4 * 60 * 60);
151  MSqlQuery deleteQuery(MSqlQuery::InitCon());
152 
153  // Keep these tvchains, they may be in use.
154  query.prepare("SELECT DISTINCT chainid FROM tvchain "
155  "WHERE endtime > :FOURHOURSAGO ;");
156  query.bindValue(":FOURHOURSAGO", fourHoursAgo);
157 
158  if (!query.exec() || !query.isActive())
159  {
160  MythDB::DBError("HouseKeeper Cleaning TVChain Table", query);
161  return;
162  }
163 
164  QString msg;
165  QString keepChains;
166  while (query.next())
167  {
168  if (keepChains.isEmpty())
169  keepChains = "'" + query.value(0).toString() + "'";
170  else
171  keepChains += ", '" + query.value(0).toString() + "'";
172  }
173 
174  if (keepChains.isEmpty())
175  msg = "DELETE FROM tvchain WHERE endtime < now();";
176  else
177  {
178  msg = QString("DELETE FROM tvchain "
179  "WHERE chainid NOT IN ( %1 ) AND endtime < now();")
180  .arg(keepChains);
181  }
182  deleteQuery.prepare(msg);
183  if (!deleteQuery.exec())
184  MythDB::DBError("CleanupTask::CleanupOrphanedLiveTV", deleteQuery);
185 }
186 
188 {
190  MSqlQuery deleteQuery(MSqlQuery::InitCon());
191  // tables[tableIndex][0] is the table name
192  // tables[tableIndex][1] is the name of the column on which the join is
193  // performed
194  std::array<std::array<QString,2>,5> tables {{
195  { "recordedprogram", "progstart" },
196  { "recordedrating", "progstart" },
197  { "recordedcredits", "progstart" },
198  { "recordedmarkup", "starttime" },
199  { "recordedseek", "starttime" },
200  }};
201 
202  // Because recordedseek can have millions of rows, we don't want to JOIN it
203  // with recorded. Instead, pull out DISTINCT chanid and starttime into a
204  // temporary table (resulting in tens, hundreds, or--at most--a few
205  // thousand rows) for the JOIN
206  QString querystr;
207  querystr = "CREATE TEMPORARY TABLE IF NOT EXISTS temprecordedcleanup ( "
208  "chanid int(10) unsigned NOT NULL default '0', "
209  "starttime datetime NOT NULL default '0000-00-00 00:00:00' "
210  ");";
211 
212  if (!query.exec(querystr))
213  {
214  MythDB::DBError("CleanupTask::CleanupRecordedTables"
215  "(creating temporary table)", query);
216  return;
217  }
218 
219  for (const auto & [table,column] : tables)
220  {
221  query.prepare(QString("TRUNCATE TABLE temprecordedcleanup;"));
222  if (!query.exec() || !query.isActive())
223  {
224  MythDB::DBError("CleanupTask::CleanupRecordedTables"
225  "(truncating temporary table)", query);
226  return;
227  }
228 
229  query.prepare(QString("INSERT INTO temprecordedcleanup "
230  "( chanid, starttime ) "
231  "SELECT DISTINCT chanid, starttime "
232  "FROM %1;")
233  .arg(table));
234 
235  if (!query.exec() || !query.isActive())
236  {
237  MythDB::DBError("CleanupTask::CleanupRecordedTables"
238  "(cleaning recorded tables)", query);
239  return;
240  }
241 
242  query.prepare(QString("SELECT DISTINCT p.chanid, p.starttime "
243  "FROM temprecordedcleanup p "
244  "LEFT JOIN recorded r "
245  "ON p.chanid = r.chanid "
246  "AND p.starttime = r.%1 "
247  "WHERE r.chanid IS NULL;").arg(column));
248  if (!query.exec() || !query.isActive())
249  {
250  MythDB::DBError("CleanupTask::CleanupRecordedTables"
251  "(cleaning recorded tables)", query);
252  return;
253  }
254 
255  deleteQuery.prepare(QString("DELETE FROM %1 "
256  "WHERE chanid = :CHANID "
257  "AND starttime = :STARTTIME;")
258  .arg(table));
259  while (query.next())
260  {
261  deleteQuery.bindValue(":CHANID", query.value(0).toString());
262  deleteQuery.bindValue(":STARTTIME", query.value(1));
263  if (!deleteQuery.exec())
264  {
265  MythDB::DBError("CleanupTask::CleanupRecordedTables"
266  "(cleaning recorded tables)", deleteQuery);
267  return;
268  }
269  }
270  }
271 
272  if (!query.exec("DROP TABLE temprecordedcleanup;"))
273  MythDB::DBError("CleanupTask::CleanupRecordedTables"
274  "(deleting temporary table)", query);
275 }
276 
278 {
280  MSqlQuery deleteQuery(MSqlQuery::InitCon());
281 
282  query.prepare(QString("DELETE channel "
283  "FROM channel "
284  "LEFT JOIN recorded r "
285  " ON r.chanid = channel.chanid "
286  "LEFT JOIN oldrecorded o "
287  " ON o.chanid = channel.chanid "
288  "WHERE channel.deleted IS NOT NULL "
289  " AND channel.deleted < "
290  " DATE_SUB(NOW(), INTERVAL 1 DAY) "
291  " AND r.chanid IS NULL "
292  " AND o.chanid IS NULL"));
293  if (!query.exec())
294  MythDB::DBError("CleanupTask::CleanupChannelTables "
295  "(channel table)", query);
296 
297  query.prepare(QString("DELETE dtv_multiplex "
298  "FROM dtv_multiplex "
299  "LEFT JOIN channel c "
300  " ON c.mplexid = dtv_multiplex.mplexid "
301  "WHERE c.chanid IS NULL"));
302  if (!query.exec())
303  MythDB::DBError("CleanupTask::CleanupChannelTables "
304  "(dtv_multiplex table)", query);
305 }
306 
308 {
310  // Keep as many days of listings data as we keep matching, non-recorded
311  // oldrecorded entries to allow for easier post-mortem analysis
312  int offset = gCoreContext->GetNumSetting( "CleanOldRecorded", 10);
313  // Also make sure to keep enough data so that we can flag the original
314  // airdate, for when that isn't included in guide data
315  int newEpiWindow = gCoreContext->GetNumSetting( "NewEpisodeWindow", 14);
316  if (newEpiWindow > offset)
317  offset = newEpiWindow;
318 
319  query.prepare("DELETE FROM oldprogram WHERE airdate < "
320  "DATE_SUB(CURRENT_DATE, INTERVAL 320 DAY);");
321  if (!query.exec())
322  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
323 
324  query.prepare("REPLACE INTO oldprogram (oldtitle,airdate) "
325  "SELECT title,starttime FROM program "
326  "WHERE starttime < NOW() AND manualid = 0 "
327  "GROUP BY title;");
328  if (!query.exec())
329  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
330 
331  query.prepare("DELETE FROM program WHERE starttime <= "
332  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
333  query.bindValue(":OFFSET", offset);
334  if (!query.exec())
335  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
336 
337  query.prepare("DELETE FROM programrating WHERE starttime <= "
338  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
339  query.bindValue(":OFFSET", offset);
340  if (!query.exec())
341  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
342 
343  query.prepare("DELETE FROM programgenres WHERE starttime <= "
344  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
345  query.bindValue(":OFFSET", offset);
346  if (!query.exec())
347  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
348 
349  query.prepare("DELETE FROM credits WHERE starttime <= "
350  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
351  query.bindValue(":OFFSET", offset);
352  if (!query.exec())
353  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
354 
355  query.prepare("DELETE FROM record WHERE (type = :SINGLE "
356  "OR type = :OVERRIDE OR type = :DONTRECORD) "
357  "AND enddate < CURDATE();");
358  query.bindValue(":SINGLE", kSingleRecord);
359  query.bindValue(":OVERRIDE", kOverrideRecord);
360  query.bindValue(":DONTRECORD", kDontRecord);
361  if (!query.exec())
362  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
363 
364  MSqlQuery findq(MSqlQuery::InitCon());
365  findq.prepare("SELECT record.recordid FROM record "
366  "LEFT JOIN oldfind ON oldfind.recordid = record.recordid "
367  "WHERE type = :FINDONE AND oldfind.findid IS NOT NULL;");
368  findq.bindValue(":FINDONE", kOneRecord);
369 
370  if (findq.exec())
371  {
372  query.prepare("DELETE FROM record WHERE recordid = :RECORDID;");
373  while (findq.next())
374  {
375  query.bindValue(":RECORDID", findq.value(0).toInt());
376  if (!query.exec())
377  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
378  }
379  }
380  query.prepare("DELETE FROM oldfind WHERE findid < TO_DAYS(NOW()) - 14;");
381  if (!query.exec())
382  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
383 
384  query.prepare("DELETE FROM oldrecorded WHERE "
385  "recstatus <> :RECORDED AND duplicate = 0 AND "
386  "endtime < DATE_SUB(CURRENT_DATE, INTERVAL :CLEAN DAY);");
387  query.bindValue(":RECORDED", RecStatus::Recorded);
388  query.bindValue(":CLEAN", offset);
389  if (!query.exec())
390  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
391 }
392 
393 bool ThemeUpdateTask::DoCheckRun(const QDateTime& now)
394 {
395  return gCoreContext->GetBoolSetting("ThemeUpdateNofications", true) &&
397 }
398 
400 {
401  bool result = false;
402  QString MythVersion = GetMythSourcePath();
403 
404  // Treat devel branches as master
405  if (!MythVersion.isEmpty() && !MythVersion.startsWith("fixes/"))
406  {
407  // FIXME: For now, treat git master the same as svn trunk
408  MythVersion = "trunk";
409 
410  result |= LoadVersion(MythVersion, LOG_ERR);
411  LOG(VB_GENERAL, LOG_INFO,
412  QString("Loading themes for %1").arg(MythVersion));
413  }
414  else
415  {
416 
417  MythVersion = MYTH_BINARY_VERSION; // Example: 29.20161017-1
418  MythVersion.replace(QRegExp("\\.[0-9]{8,}.*"), "");
419  LOG(VB_GENERAL, LOG_INFO,
420  QString("Loading themes for %1").arg(MythVersion));
421  result |= LoadVersion(MythVersion, LOG_ERR);
422 
423  // If a version of the theme for this tag exists, use it...
424  QRegExp subexp("v[0-9]+\\.([0-9]+)-*");
425  int pos = subexp.indexIn(GetMythSourceVersion());
426  if (pos > -1)
427  {
428  QString subversion;
429  int idx = subexp.cap(1).toInt();
430  for ( ; idx > 0; --idx)
431  {
432  subversion = MythVersion + "." + QString::number(idx);
433  LOG(VB_GENERAL, LOG_INFO,
434  QString("Loading themes for %1").arg(subversion));
435  result |= LoadVersion(subversion, LOG_INFO);
436  }
437  }
438  }
439  return result;
440 }
441 
442 bool ThemeUpdateTask::LoadVersion(const QString &version, int download_log_level)
443 {
444  QString remoteThemesDir = GetConfDir();
445  remoteThemesDir.append("/tmp/remotethemes");
446 
447  QDir dir(remoteThemesDir);
448  if (!dir.exists() && !dir.mkpath(remoteThemesDir))
449  {
450  LOG(VB_GENERAL, LOG_ERR,
451  QString("HouseKeeper: Error creating %1 "
452  "directory for remote themes info cache.")
453  .arg(remoteThemesDir));
454  return false;
455  }
456 
457  QString remoteThemesFile = remoteThemesDir;
458  remoteThemesFile.append("/themes.zip");
459 
460  m_url = QString("%1/%2/themes.zip")
461  .arg(gCoreContext->GetSetting("ThemeRepositoryURL",
462  "http://themes.mythtv.org/themes/repository"))
463  .arg(version);
464 
465  m_running = true;
466  bool result = GetMythDownloadManager()->download(m_url, remoteThemesFile);
467  m_running = false;
468 
469  if (!result)
470  {
471  LOG(VB_GENERAL, (LogLevel_t)download_log_level,
472  QString("HouseKeeper: Failed to download %1 "
473  "remote themes info package.").arg(m_url));
474  return false;
475  }
476 
477  if (!extractZIP(remoteThemesFile, remoteThemesDir))
478  {
479  LOG(VB_GENERAL, LOG_ERR,
480  QString("HouseKeeper: Error extracting %1 "
481  "remote themes info package.").arg(remoteThemesFile));
482  QFile::remove(remoteThemesFile);
483  return false;
484  }
485 
486  return true;
487 }
488 
490 {
491  if (m_running)
493  m_running = false;
494 }
495 
497  : DailyHouseKeeperTask("UpdateRadioStreams", kHKGlobal, kHKRunOnStartup)
498 {
499 }
500 
502 {
503  if (m_msMU)
504  {
505  // this should never be defined, but terminate it anyway
507  m_msMU->Term(true);
508  delete m_msMU;
509  m_msMU = nullptr;
510  }
511 
512  QString command = GetAppBinDir() + "mythutil";
513  QStringList args;
514  args << "--updateradiostreams";
516 
517  LOG(VB_GENERAL, LOG_INFO, QString("Performing Radio Streams Update: %1 %2")
518  .arg(command).arg(args.join(" ")));
519 
521 
522  m_msMU->Run();
523  uint result = m_msMU->Wait();
524 
525  delete m_msMU;
526  m_msMU = nullptr;
527 
528  if (result != GENERIC_EXIT_OK)
529  {
530  LOG(VB_GENERAL, LOG_ERR, QString("Update Radio Streams command '%1' failed")
531  .arg(command));
532  return false;
533  }
534 
535  LOG(VB_GENERAL, LOG_INFO, QString("Radio Stream Update Complete"));
536  return true;
537 }
538 
540 {
541  delete m_msMU;
542  m_msMU = nullptr;
543 }
544 
545 bool RadioStreamUpdateTask::DoCheckRun(const QDateTime& now)
546 {
547  // we are only interested in the global setting so remove any local host setting just in case
548  GetMythDB()->ClearSetting("MusicStreamListModified");
549 
550  // check we are not already running a radio stream update
551  return gCoreContext->GetSetting("MusicStreamListModified") == "Updating" &&
553 }
554 
556 {
558  // just kill it, the runner thread will handle any necessary cleanup
559  m_msMU->Term(true);
560 }
561 
563  : DailyHouseKeeperTask("RecordedArtworkUpdate", kHKGlobal, kHKRunOnStartup)
564 {
565 }
566 
568 {
569  if (m_msMML)
570  {
571  // this should never be defined, but terminate it anyway
573  m_msMML->Term(true);
574  delete m_msMML;
575  m_msMML = nullptr;
576  }
577 
578  QString command = GetAppBinDir() + "mythmetadatalookup";
579  QStringList args;
580  args << "--refresh-all-artwork";
582 
583  LOG(VB_GENERAL, LOG_INFO, QString("Performing Artwork Refresh: %1 %2")
584  .arg(command).arg(args.join(" ")));
585 
587 
588  m_msMML->Run();
589  uint result = m_msMML->Wait();
590 
591  delete m_msMML;
592  m_msMML = nullptr;
593 
594  if (result != GENERIC_EXIT_OK)
595  {
596  LOG(VB_GENERAL, LOG_ERR, QString("Artwork command '%1' failed")
597  .arg(command));
598  return false;
599  }
600  LOG(VB_GENERAL, LOG_INFO, QString("Artwork Refresh Complete"));
601  return true;
602 }
603 
605 {
606  delete m_msMML;
607  m_msMML = nullptr;
608 }
609 
610 bool ArtworkTask::DoCheckRun(const QDateTime& now)
611 {
612  return gCoreContext->GetBoolSetting("DailyArtworkUpdates", false) &&
614 }
615 
617 {
619  // just kill it, the runner thread will handle any necessary cleanup
620  m_msMML->Term(true);
621 }
622 
624 {
626  return true;
627 }
628 
630  DailyHouseKeeperTask("MythFillDB")
631 {
633 }
634 
636 {
637  // we need to set the time window from database settings, so we cannot
638  // initialize these values in. grab them and set them afterwards
639  int min = gCoreContext->GetNumSetting("MythFillMinHour", -1);
640  int max = gCoreContext->GetNumSetting("MythFillMaxHour", 23);
641 
642  if (min == -1)
643  {
644  min = 0;
645  max = 23;
646  }
647  else
648  {
649  // make sure they fall within the range of 0-23
650  min %= 24;
651  max %= 24;
652  }
653 
655 }
656 
658 {
659 // if (!gCoreContext->GetBoolSetting("MythFillGrabberSuggestsTime", true))
660 // // this feature is disabled, so don't bother with a deeper check
661 // return false;
662 //
663 // MSqlQuery result(MSqlQuery::InitCon());
664 // if (result.isConnected())
665 // {
666 // // check to see if we have any of a list of supported grabbers in use
667 // // TODO: this is really cludgy. there has to be a better way to test
668 // result.prepare("SELECT COUNT(*) FROM videosource"
669 // " WHERE xmltvgrabber IN"
670 // " ( 'technovera' );");
671 // if ((result.exec()) &&
672 // (result.next()) &&
673 // (result.value(0).toInt() > 0))
674 // return true;
675 // }
676 
677  return gCoreContext->GetBoolSetting("MythFillGrabberSuggestsTime", true);
678 }
679 
680 bool MythFillDatabaseTask::DoCheckRun(const QDateTime& now)
681 {
682  if (!gCoreContext->GetBoolSetting("MythFillEnabled", true))
683  {
684  // we don't want to run this manually, so abort early
685  LOG(VB_GENERAL, LOG_DEBUG, "MythFillDatabase is disabled. Cannot run.");
686  return false;
687  }
688 
689 // if (m_running)
690 // // we're still running from the previous pass, so abort early
691 // return false;
692 
693  if (UseSuggestedTime())
694  {
695  QDateTime nextRun = MythDate::fromString(
696  gCoreContext->GetSetting("MythFillSuggestedRunTime",
697  "1970-01-01T00:00:00"));
698  LOG(VB_GENERAL, LOG_DEBUG,
699  QString("MythFillDatabase scheduled to run at %1.")
700  .arg(nextRun.toString()));
701  // is it yet time
702  return nextRun <= now;
703  }
704  if (InWindow(now))
705  // we're inside our permitted window
706  return true;
707 
708  // just let DailyHouseKeeperTask handle things
709  LOG(VB_GENERAL, LOG_DEBUG, "Performing daily run check.");
711 }
712 
714 {
715  if (m_msMFD)
716  {
717  // this should never be defined, but terminate it anyway
719  m_msMFD->Term(true);
720  delete m_msMFD;
721  m_msMFD = nullptr;
722  }
723 
724  QString mfpath = gCoreContext->GetSetting("MythFillDatabasePath",
725  "mythfilldatabase");
726  QString mfarg = gCoreContext->GetSetting("MythFillDatabaseArgs", "");
727 
729  if (mfpath == "mythfilldatabase")
730  {
732  mfpath = GetAppBinDir() + "mythfilldatabase";
733  }
734 
735  QString cmd = QString("%1 %2").arg(mfpath).arg(mfarg);
736 
737  m_msMFD = new MythSystemLegacy(cmd, opts);
738 
739  m_msMFD->Run();
740  uint result = m_msMFD->Wait();
741 
742  delete m_msMFD;
743  m_msMFD = nullptr;
744 
745  if (result != GENERIC_EXIT_OK)
746  {
747  LOG(VB_GENERAL, LOG_ERR, QString("MythFillDatabase command '%1' failed")
748  .arg(cmd));
749  return false;
750  }
751 
752  return true;
753 }
754 
756 {
757  delete m_msMFD;
758  m_msMFD = nullptr;
759 }
760 
762 {
764  // just kill it, the runner thread will handle any necessary cleanup
765  m_msMFD->Term(true);
766 }
ArtworkTask::ArtworkTask
ArtworkTask(void)
Definition: backendhousekeeper.cpp:562
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
build_compdb.args
args
Definition: build_compdb.py:11
JobQueueRecoverTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:623
GENERIC_EXIT_OK
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
ThemeUpdateTask::m_running
bool m_running
Definition: backendhousekeeper.h:53
MythFillDatabaseTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:713
MythSystemLegacy::Term
void Term(bool force=false)
Definition: mythsystemlegacy.cpp:283
mythdb.h
MythSystemLegacy
Definition: mythsystemlegacy.h:68
MythFillDatabaseTask::SetHourWindowFromDB
void SetHourWindowFromDB(void)
Definition: backendhousekeeper.cpp:635
MythSystemLegacy::GetStatus
uint GetStatus(void) const
Definition: mythsystemlegacy.h:122
CleanupTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:111
RadioStreamUpdateTask::Terminate
void Terminate(void) override
Definition: backendhousekeeper.cpp:555
ThemeUpdateTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: backendhousekeeper.cpp:393
CleanupTask::CleanupInUsePrograms
static void CleanupInUsePrograms(void)
Definition: backendhousekeeper.cpp:135
MythFillDatabaseTask::m_msMFD
MythSystemLegacy * m_msMFD
Definition: backendhousekeeper.h:94
mythcoreutil.h
ArtworkTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: backendhousekeeper.cpp:610
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
arg
arg(title).arg(filename).arg(doDelete))
RadioStreamUpdateTask::~RadioStreamUpdateTask
~RadioStreamUpdateTask(void) override
Definition: backendhousekeeper.cpp:539
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
ThemeUpdateTask::Terminate
void Terminate(void) override
Definition: backendhousekeeper.cpp:489
PeriodicHouseKeeperTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: housekeeper.cpp:373
RecStatus::Recorded
@ Recorded
Definition: recStatus.h:29
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MYTH_APPNAME_MYTHFRONTEND
#define MYTH_APPNAME_MYTHFRONTEND
Definition: mythcorecontext.h:20
ArtworkTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:567
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:45
CleanupTask::CleanupOldRecordings
static void CleanupOldRecordings(void)
Definition: backendhousekeeper.cpp:123
MythSystemLegacy::Run
void Run(time_t timeout=0)
Runs a command inside the /bin/sh shell. Returns immediately.
Definition: mythsystemlegacy.cpp:212
mythdirs.h
recordingtypes.h
ThemeUpdateTask::m_url
QString m_url
Definition: backendhousekeeper.h:54
RadioStreamUpdateTask::m_msMU
MythSystemLegacy * m_msMU
Definition: backendhousekeeper.h:39
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
DailyHouseKeeperTask::InWindow
bool InWindow(const QDateTime &now) override
Definition: housekeeper.cpp:489
mythversion.h
mythsystemlegacy.h
programtypes.h
MYTH_APPNAME_MYTHBACKEND
#define MYTH_APPNAME_MYTHBACKEND
Definition: mythcorecontext.h:18
MythDB::ClearSetting
bool ClearSetting(const QString &key)
Definition: mythdb.cpp:359
RadioStreamUpdateTask::RadioStreamUpdateTask
RadioStreamUpdateTask(void)
Definition: backendhousekeeper.cpp:496
MythFillDatabaseTask::MythFillDatabaseTask
MythFillDatabaseTask(void)
Definition: backendhousekeeper.cpp:629
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:224
DailyHouseKeeperTask::SetHourWindow
virtual void SetHourWindow(int min, int max)
Definition: housekeeper.cpp:482
CleanupTask::CleanupRecordedTables
static void CleanupRecordedTables(void)
Definition: backendhousekeeper.cpp:187
ArtworkTask::~ArtworkTask
~ArtworkTask(void) override
Definition: backendhousekeeper.cpp:604
MythFillDatabaseTask::~MythFillDatabaseTask
~MythFillDatabaseTask(void) override
Definition: backendhousekeeper.cpp:755
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
MythFillDatabaseTask::Terminate
void Terminate(void) override
Definition: backendhousekeeper.cpp:761
JobQueue::CleanupOldJobsInQueue
static void CleanupOldJobsInQueue()
Definition: jobqueue.cpp:1631
ThemeUpdateTask::LoadVersion
bool LoadVersion(const QString &version, int download_log_level)
Definition: backendhousekeeper.cpp:442
CleanupTask::CleanupOrphanedLiveTV
static void CleanupOrphanedLiveTV(void)
Definition: backendhousekeeper.cpp:147
MythDownloadManager::download
bool download(const QString &url, const QString &dest, bool reload=false)
Downloads a URL to a file in blocking mode.
Definition: mythdownloadmanager.cpp:430
jobqueue.h
MythDownloadManager::cancelDownload
void cancelDownload(const QString &url, bool block=true)
Cancel a queued or current download.
Definition: mythdownloadmanager.cpp:1013
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:135
kMSPropagateLogs
@ kMSPropagateLogs
add arguments for MythTV log propagation
Definition: mythsystem.h:50
uint
unsigned int uint
Definition: compat.h:140
CleanupTask::CleanupProgramListings
static void CleanupProgramListings(void)
Definition: backendhousekeeper.cpp:307
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:56
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:929
GetMythSourcePath
const char * GetMythSourcePath()
Definition: mythcoreutil.cpp:318
kOneRecord
@ kOneRecord
Definition: recordingtypes.h:27
ThemeUpdateTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:399
kMSRunShell
@ kMSRunShell
run process through shell
Definition: mythsystem.h:41
kMSAutoCleanup
@ kMSAutoCleanup
automatically delete if backgrounded
Definition: mythsystem.h:43
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:30
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:923
ArtworkTask::Terminate
void Terminate(void) override
Definition: backendhousekeeper.cpp:616
MYTH_BINARY_VERSION
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:15
ArtworkTask::m_msMML
MythSystemLegacy * m_msMML
Definition: backendhousekeeper.h:66
backendhousekeeper.h
mythcorecontext.h
MythFillDatabaseTask::UseSuggestedTime
static bool UseSuggestedTime(void)
Definition: backendhousekeeper.cpp:657
dir
QDir dir
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1174
kOverrideRecord
@ kOverrideRecord
Definition: recordingtypes.h:28
LogCleanerTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:31
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
kSingleRecord
@ kSingleRecord
Definition: recordingtypes.h:22
CleanupTask::CleanupChannelTables
static void CleanupChannelTables(void)
Definition: backendhousekeeper.cpp:277
GetAppBinDir
QString GetAppBinDir(void)
Definition: mythdirs.cpp:221
GetMythSourceVersion
const char * GetMythSourceVersion()
Definition: mythcoreutil.cpp:313
kHKRunOnStartup
@ kHKRunOnStartup
task is queued when HouseKeeper is started
Definition: housekeeper.h:35
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:855
extractZIP
bool extractZIP(const QString &zipFile, const QString &outDir)
Definition: mythcoreutil.cpp:74
logPropagateArgs
QString logPropagateArgs
Definition: logging.cpp:87
RadioStreamUpdateTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: backendhousekeeper.cpp:545
GENERIC_EXIT_RUNNING
#define GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:25
RadioStreamUpdateTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:501
exitcodes.h
mythdownloadmanager.h
query
MSqlQuery query(MSqlQuery::InitCon())
nv_python_libs.bbciplayer.bbciplayer_api.version
string version
Definition: bbciplayer_api.py:81
DailyHouseKeeperTask
Modified PeriodicHouseKeeperTask for tasks to be run once daily.
Definition: housekeeper.h:108
JobQueue::RecoverOldJobsInQueue
static void RecoverOldJobsInQueue()
Definition: jobqueue.h:207
kDontRecord
@ kDontRecord
Definition: recordingtypes.h:29
musicmetadata.h
recStatus.h
kHKGlobal
@ kHKGlobal
task should only run once per cluster e.g.
Definition: housekeeper.h:25
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:915
GetMythDownloadManager
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
Definition: mythdownloadmanager.cpp:145
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
MythFillDatabaseTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: backendhousekeeper.cpp:680