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  int tableIndex = 0;
192  // tables[tableIndex][0] is the table name
193  // tables[tableIndex][1] is the name of the column on which the join is
194  // performed
195  QString tables[][2] = {
196  { "recordedprogram", "progstart" },
197  { "recordedrating", "progstart" },
198  { "recordedcredits", "progstart" },
199  { "recordedmarkup", "starttime" },
200  { "recordedseek", "starttime" },
201  { "", "" } }; // This blank entry must exist, do not remove.
202  QString table = tables[tableIndex][0];
203  QString column = tables[tableIndex][1];
204 
205  // Because recordedseek can have millions of rows, we don't want to JOIN it
206  // with recorded. Instead, pull out DISTINCT chanid and starttime into a
207  // temporary table (resulting in tens, hundreds, or--at most--a few
208  // thousand rows) for the JOIN
209  QString querystr;
210  querystr = "CREATE TEMPORARY TABLE IF NOT EXISTS temprecordedcleanup ( "
211  "chanid int(10) unsigned NOT NULL default '0', "
212  "starttime datetime NOT NULL default '0000-00-00 00:00:00' "
213  ");";
214 
215  if (!query.exec(querystr))
216  {
217  MythDB::DBError("CleanupTask::CleanupRecordedTables"
218  "(creating temporary table)", query);
219  return;
220  }
221 
222  while (!table.isEmpty())
223  {
224  query.prepare(QString("TRUNCATE TABLE temprecordedcleanup;"));
225  if (!query.exec() || !query.isActive())
226  {
227  MythDB::DBError("CleanupTask::CleanupRecordedTables"
228  "(truncating temporary table)", query);
229  return;
230  }
231 
232  query.prepare(QString("INSERT INTO temprecordedcleanup "
233  "( chanid, starttime ) "
234  "SELECT DISTINCT chanid, starttime "
235  "FROM %1;")
236  .arg(table));
237 
238  if (!query.exec() || !query.isActive())
239  {
240  MythDB::DBError("CleanupTask::CleanupRecordedTables"
241  "(cleaning recorded tables)", query);
242  return;
243  }
244 
245  query.prepare(QString("SELECT DISTINCT p.chanid, p.starttime "
246  "FROM temprecordedcleanup p "
247  "LEFT JOIN recorded r "
248  "ON p.chanid = r.chanid "
249  "AND p.starttime = r.%1 "
250  "WHERE r.chanid IS NULL;").arg(column));
251  if (!query.exec() || !query.isActive())
252  {
253  MythDB::DBError("CleanupTask::CleanupRecordedTables"
254  "(cleaning recorded tables)", query);
255  return;
256  }
257 
258  deleteQuery.prepare(QString("DELETE FROM %1 "
259  "WHERE chanid = :CHANID "
260  "AND starttime = :STARTTIME;")
261  .arg(table));
262  while (query.next())
263  {
264  deleteQuery.bindValue(":CHANID", query.value(0).toString());
265  deleteQuery.bindValue(":STARTTIME", query.value(1));
266  if (!deleteQuery.exec())
267  {
268  MythDB::DBError("CleanupTask::CleanupRecordedTables"
269  "(cleaning recorded tables)", deleteQuery);
270  return;
271  }
272  }
273 
274  tableIndex++;
275  table = tables[tableIndex][0];
276  column = tables[tableIndex][1];
277  }
278 
279  if (!query.exec("DROP TABLE temprecordedcleanup;"))
280  MythDB::DBError("CleanupTask::CleanupRecordedTables"
281  "(deleting temporary table)", query);
282 }
283 
285 {
287  MSqlQuery deleteQuery(MSqlQuery::InitCon());
288 
289  query.prepare(QString("DELETE channel "
290  "FROM channel "
291  "LEFT JOIN recorded r "
292  " ON r.chanid = channel.chanid "
293  "LEFT JOIN oldrecorded o "
294  " ON o.chanid = channel.chanid "
295  "WHERE channel.deleted IS NOT NULL "
296  " AND channel.deleted < "
297  " DATE_SUB(NOW(), INTERVAL 1 DAY) "
298  " AND r.chanid IS NULL "
299  " AND o.chanid IS NULL"));
300  if (!query.exec())
301  MythDB::DBError("CleanupTask::CleanupChannelTables "
302  "(channel table)", query);
303 
304  query.prepare(QString("DELETE dtv_multiplex "
305  "FROM dtv_multiplex "
306  "LEFT JOIN channel c "
307  " ON c.mplexid = dtv_multiplex.mplexid "
308  "WHERE c.chanid IS NULL"));
309  if (!query.exec())
310  MythDB::DBError("CleanupTask::CleanupChannelTables "
311  "(dtv_multiplex table)", query);
312 }
313 
315 {
317  QString querystr;
318  // Keep as many days of listings data as we keep matching, non-recorded
319  // oldrecorded entries to allow for easier post-mortem analysis
320  int offset = gCoreContext->GetNumSetting( "CleanOldRecorded", 10);
321  // Also make sure to keep enough data so that we can flag the original
322  // airdate, for when that isn't included in guide data
323  int newEpiWindow = gCoreContext->GetNumSetting( "NewEpisodeWindow", 14);
324  if (newEpiWindow > offset)
325  offset = newEpiWindow;
326 
327  query.prepare("DELETE FROM oldprogram WHERE airdate < "
328  "DATE_SUB(CURRENT_DATE, INTERVAL 320 DAY);");
329  if (!query.exec())
330  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
331 
332  query.prepare("REPLACE INTO oldprogram (oldtitle,airdate) "
333  "SELECT title,starttime FROM program "
334  "WHERE starttime < NOW() AND manualid = 0 "
335  "GROUP BY title;");
336  if (!query.exec())
337  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
338 
339  query.prepare("DELETE FROM program WHERE starttime <= "
340  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
341  query.bindValue(":OFFSET", offset);
342  if (!query.exec())
343  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
344 
345  query.prepare("DELETE FROM programrating WHERE starttime <= "
346  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
347  query.bindValue(":OFFSET", offset);
348  if (!query.exec())
349  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
350 
351  query.prepare("DELETE FROM programgenres WHERE starttime <= "
352  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
353  query.bindValue(":OFFSET", offset);
354  if (!query.exec())
355  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
356 
357  query.prepare("DELETE FROM credits WHERE starttime <= "
358  "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
359  query.bindValue(":OFFSET", offset);
360  if (!query.exec())
361  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
362 
363  query.prepare("DELETE FROM record WHERE (type = :SINGLE "
364  "OR type = :OVERRIDE OR type = :DONTRECORD) "
365  "AND enddate < CURDATE();");
366  query.bindValue(":SINGLE", kSingleRecord);
367  query.bindValue(":OVERRIDE", kOverrideRecord);
368  query.bindValue(":DONTRECORD", kDontRecord);
369  if (!query.exec())
370  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
371 
372  MSqlQuery findq(MSqlQuery::InitCon());
373  findq.prepare("SELECT record.recordid FROM record "
374  "LEFT JOIN oldfind ON oldfind.recordid = record.recordid "
375  "WHERE type = :FINDONE AND oldfind.findid IS NOT NULL;");
376  findq.bindValue(":FINDONE", kOneRecord);
377 
378  if (findq.exec())
379  {
380  query.prepare("DELETE FROM record WHERE recordid = :RECORDID;");
381  while (findq.next())
382  {
383  query.bindValue(":RECORDID", findq.value(0).toInt());
384  if (!query.exec())
385  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
386  }
387  }
388  query.prepare("DELETE FROM oldfind WHERE findid < TO_DAYS(NOW()) - 14;");
389  if (!query.exec())
390  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
391 
392  query.prepare("DELETE FROM oldrecorded WHERE "
393  "recstatus <> :RECORDED AND duplicate = 0 AND "
394  "endtime < DATE_SUB(CURRENT_DATE, INTERVAL :CLEAN DAY);");
395  query.bindValue(":RECORDED", RecStatus::Recorded);
396  query.bindValue(":CLEAN", offset);
397  if (!query.exec())
398  MythDB::DBError("HouseKeeper Cleaning Program Listings", query);
399 }
400 
401 bool ThemeUpdateTask::DoCheckRun(const QDateTime& now)
402 {
403  return gCoreContext->GetBoolSetting("ThemeUpdateNofications", true) &&
405 }
406 
408 {
409  bool result = false;
410  QString MythVersion = MYTH_SOURCE_PATH;
411 
412  // Treat devel branches as master
413  if (!MythVersion.isEmpty() && !MythVersion.startsWith("fixes/"))
414  {
415  // FIXME: For now, treat git master the same as svn trunk
416  MythVersion = "trunk";
417 
418  result |= LoadVersion(MythVersion, LOG_ERR);
419  LOG(VB_GENERAL, LOG_INFO,
420  QString("Loading themes for %1").arg(MythVersion));
421  }
422  else
423  {
424 
425  MythVersion = MYTH_BINARY_VERSION; // Example: 29.20161017-1
426  MythVersion.replace(QRegExp("\\.[0-9]{8,}.*"), "");
427  LOG(VB_GENERAL, LOG_INFO,
428  QString("Loading themes for %1").arg(MythVersion));
429  result |= LoadVersion(MythVersion, LOG_ERR);
430 
431  // If a version of the theme for this tag exists, use it...
432  QRegExp subexp("v[0-9]+\\.([0-9]+)-*");
433  int pos = subexp.indexIn(MYTH_SOURCE_VERSION);
434  if (pos > -1)
435  {
436  QString subversion;
437  int idx = subexp.cap(1).toInt();
438  for ( ; idx > 0; --idx)
439  {
440  subversion = MythVersion + "." + QString::number(idx);
441  LOG(VB_GENERAL, LOG_INFO,
442  QString("Loading themes for %1").arg(subversion));
443  result |= LoadVersion(subversion, LOG_INFO);
444  }
445  }
446  }
447  return result;
448 }
449 
450 bool ThemeUpdateTask::LoadVersion(const QString &version, int download_log_level)
451 {
452  QString remoteThemesDir = GetConfDir();
453  remoteThemesDir.append("/tmp/remotethemes");
454 
455  QDir dir(remoteThemesDir);
456  if (!dir.exists() && !dir.mkpath(remoteThemesDir))
457  {
458  LOG(VB_GENERAL, LOG_ERR,
459  QString("HouseKeeper: Error creating %1 "
460  "directory for remote themes info cache.")
461  .arg(remoteThemesDir));
462  return false;
463  }
464 
465  QString remoteThemesFile = remoteThemesDir;
466  remoteThemesFile.append("/themes.zip");
467 
468  m_url = QString("%1/%2/themes.zip")
469  .arg(gCoreContext->GetSetting("ThemeRepositoryURL",
470  "http://themes.mythtv.org/themes/repository"))
471  .arg(version);
472 
473  m_running = true;
474  bool result = GetMythDownloadManager()->download(m_url, remoteThemesFile);
475  m_running = false;
476 
477  if (!result)
478  {
479  LOG(VB_GENERAL, (LogLevel_t)download_log_level,
480  QString("HouseKeeper: Failed to download %1 "
481  "remote themes info package.").arg(m_url));
482  return false;
483  }
484 
485  if (!extractZIP(remoteThemesFile, remoteThemesDir))
486  {
487  LOG(VB_GENERAL, LOG_ERR,
488  QString("HouseKeeper: Error extracting %1 "
489  "remote themes info package.").arg(remoteThemesFile));
490  QFile::remove(remoteThemesFile);
491  return false;
492  }
493 
494  return true;
495 }
496 
498 {
499  if (m_running)
501  m_running = false;
502 }
503 
505  : DailyHouseKeeperTask("UpdateRadioStreams", kHKGlobal, kHKRunOnStartup)
506 {
507 }
508 
510 {
511  if (m_msMU)
512  {
513  // this should never be defined, but terminate it anyway
515  m_msMU->Term(true);
516  delete m_msMU;
517  m_msMU = nullptr;
518  }
519 
520  QString command = GetAppBinDir() + "mythutil";
521  QStringList args;
522  args << "--updateradiostreams";
524 
525  LOG(VB_GENERAL, LOG_INFO, QString("Performing Radio Streams Update: %1 %2")
526  .arg(command).arg(args.join(" ")));
527 
529 
530  m_msMU->Run();
531  uint result = m_msMU->Wait();
532 
533  delete m_msMU;
534  m_msMU = nullptr;
535 
536  if (result != GENERIC_EXIT_OK)
537  {
538  LOG(VB_GENERAL, LOG_ERR, QString("Update Radio Streams command '%1' failed")
539  .arg(command));
540  return false;
541  }
542 
543  LOG(VB_GENERAL, LOG_INFO, QString("Radio Stream Update Complete"));
544  return true;
545 }
546 
548 {
549  delete m_msMU;
550  m_msMU = nullptr;
551 }
552 
553 bool RadioStreamUpdateTask::DoCheckRun(const QDateTime& now)
554 {
555  // we are only interested in the global setting so remove any local host setting just in case
556  GetMythDB()->ClearSetting("MusicStreamListModified");
557 
558  // check we are not already running a radio stream update
559  return gCoreContext->GetSetting("MusicStreamListModified") == "Updating" &&
561 }
562 
564 {
566  // just kill it, the runner thread will handle any necessary cleanup
567  m_msMU->Term(true);
568 }
569 
571  : DailyHouseKeeperTask("RecordedArtworkUpdate", kHKGlobal, kHKRunOnStartup)
572 {
573 }
574 
576 {
577  if (m_msMML)
578  {
579  // this should never be defined, but terminate it anyway
581  m_msMML->Term(true);
582  delete m_msMML;
583  m_msMML = nullptr;
584  }
585 
586  QString command = GetAppBinDir() + "mythmetadatalookup";
587  QStringList args;
588  args << "--refresh-all-artwork";
590 
591  LOG(VB_GENERAL, LOG_INFO, QString("Performing Artwork Refresh: %1 %2")
592  .arg(command).arg(args.join(" ")));
593 
595 
596  m_msMML->Run();
597  uint result = m_msMML->Wait();
598 
599  delete m_msMML;
600  m_msMML = nullptr;
601 
602  if (result != GENERIC_EXIT_OK)
603  {
604  LOG(VB_GENERAL, LOG_ERR, QString("Artwork command '%1' failed")
605  .arg(command));
606  return false;
607  }
608  LOG(VB_GENERAL, LOG_INFO, QString("Artwork Refresh Complete"));
609  return true;
610 }
611 
613 {
614  delete m_msMML;
615  m_msMML = nullptr;
616 }
617 
618 bool ArtworkTask::DoCheckRun(const QDateTime& now)
619 {
620  return gCoreContext->GetBoolSetting("DailyArtworkUpdates", false) &&
622 }
623 
625 {
627  // just kill it, the runner thread will handle any necessary cleanup
628  m_msMML->Term(true);
629 }
630 
632 {
634  return true;
635 }
636 
638  DailyHouseKeeperTask("MythFillDB")
639 {
641 }
642 
644 {
645  // we need to set the time window from database settings, so we cannot
646  // initialize these values in. grab them and set them afterwards
647  int min = gCoreContext->GetNumSetting("MythFillMinHour", -1);
648  int max = gCoreContext->GetNumSetting("MythFillMaxHour", 23);
649 
650  if (min == -1)
651  {
652  min = 0;
653  max = 23;
654  }
655  else
656  {
657  // make sure they fall within the range of 0-23
658  min %= 24;
659  max %= 24;
660  }
661 
663 }
664 
666 {
667 // if (!gCoreContext->GetBoolSetting("MythFillGrabberSuggestsTime", true))
668 // // this feature is disabled, so don't bother with a deeper check
669 // return false;
670 //
671 // MSqlQuery result(MSqlQuery::InitCon());
672 // if (result.isConnected())
673 // {
674 // // check to see if we have any of a list of supported grabbers in use
675 // // TODO: this is really cludgy. there has to be a better way to test
676 // result.prepare("SELECT COUNT(*) FROM videosource"
677 // " WHERE xmltvgrabber IN"
678 // " ( 'technovera' );");
679 // if ((result.exec()) &&
680 // (result.next()) &&
681 // (result.value(0).toInt() > 0))
682 // return true;
683 // }
684 
685  return gCoreContext->GetBoolSetting("MythFillGrabberSuggestsTime", true);
686 }
687 
688 bool MythFillDatabaseTask::DoCheckRun(const QDateTime& now)
689 {
690  if (!gCoreContext->GetBoolSetting("MythFillEnabled", true))
691  {
692  // we don't want to run this manually, so abort early
693  LOG(VB_GENERAL, LOG_DEBUG, "MythFillDatabase is disabled. Cannot run.");
694  return false;
695  }
696 
697 // if (m_running)
698 // // we're still running from the previous pass, so abort early
699 // return false;
700 
701  if (UseSuggestedTime())
702  {
703  QDateTime nextRun = MythDate::fromString(
704  gCoreContext->GetSetting("MythFillSuggestedRunTime",
705  "1970-01-01T00:00:00"));
706  LOG(VB_GENERAL, LOG_DEBUG,
707  QString("MythFillDatabase scheduled to run at %1.")
708  .arg(nextRun.toString()));
709  // is it yet time
710  return nextRun <= now;
711  }
712  if (InWindow(now))
713  // we're inside our permitted window
714  return true;
715 
716  // just let DailyHouseKeeperTask handle things
717  LOG(VB_GENERAL, LOG_DEBUG, "Performing daily run check.");
719 }
720 
722 {
723  if (m_msMFD)
724  {
725  // this should never be defined, but terminate it anyway
727  m_msMFD->Term(true);
728  delete m_msMFD;
729  m_msMFD = nullptr;
730  }
731 
732  QString mfpath = gCoreContext->GetSetting("MythFillDatabasePath",
733  "mythfilldatabase");
734  QString mfarg = gCoreContext->GetSetting("MythFillDatabaseArgs", "");
735 
737  if (mfpath == "mythfilldatabase")
738  {
740  mfpath = GetAppBinDir() + "mythfilldatabase";
741  }
742 
743  QString cmd = QString("%1 %2").arg(mfpath).arg(mfarg);
744 
745  m_msMFD = new MythSystemLegacy(cmd, opts);
746 
747  m_msMFD->Run();
748  uint result = m_msMFD->Wait();
749 
750  delete m_msMFD;
751  m_msMFD = nullptr;
752 
753  if (result != GENERIC_EXIT_OK)
754  {
755  LOG(VB_GENERAL, LOG_ERR, QString("MythFillDatabase command '%1' failed")
756  .arg(cmd));
757  return false;
758  }
759 
760  return true;
761 }
762 
764 {
765  delete m_msMFD;
766  m_msMFD = nullptr;
767 }
768 
770 {
772  // just kill it, the runner thread will handle any necessary cleanup
773  m_msMFD->Term(true);
774 }
ArtworkTask::ArtworkTask
ArtworkTask(void)
Definition: backendhousekeeper.cpp:570
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:125
build_compdb.args
args
Definition: build_compdb.py:11
JobQueueRecoverTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:631
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:721
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:643
MythSystemLegacy::GetStatus
uint GetStatus(void) const
Definition: mythsystemlegacy.h:123
CleanupTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:111
RadioStreamUpdateTask::Terminate
void Terminate(void) override
Definition: backendhousekeeper.cpp:563
ThemeUpdateTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: backendhousekeeper.cpp:401
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:618
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:547
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:497
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:18
ArtworkTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:575
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
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:16
RadioStreamUpdateTask::RadioStreamUpdateTask
RadioStreamUpdateTask(void)
Definition: backendhousekeeper.cpp:504
MythFillDatabaseTask::MythFillDatabaseTask
MythFillDatabaseTask(void)
Definition: backendhousekeeper.cpp:637
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:612
MythFillDatabaseTask::~MythFillDatabaseTask
~MythFillDatabaseTask(void) override
Definition: backendhousekeeper.cpp:763
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:179
MythFillDatabaseTask::Terminate
void Terminate(void) override
Definition: backendhousekeeper.cpp:769
JobQueue::CleanupOldJobsInQueue
static void CleanupOldJobsInQueue()
Definition: jobqueue.cpp:1633
ThemeUpdateTask::LoadVersion
bool LoadVersion(const QString &version, int download_log_level)
Definition: backendhousekeeper.cpp:450
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:446
jobqueue.h
MythDownloadManager::cancelDownload
void cancelDownload(const QString &url, bool block=true)
Cancel a queued or current download.
Definition: mythdownloadmanager.cpp:1027
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:314
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:930
kOneRecord
@ kOneRecord
Definition: recordingtypes.h:27
ThemeUpdateTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:407
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:924
ArtworkTask::Terminate
void Terminate(void) override
Definition: backendhousekeeper.cpp:624
MYTH_BINARY_VERSION
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:16
ArtworkTask::m_msMML
MythSystemLegacy * m_msMML
Definition: backendhousekeeper.h:66
backendhousekeeper.h
mythcorecontext.h
MythFillDatabaseTask::UseSuggestedTime
static bool UseSuggestedTime(void)
Definition: backendhousekeeper.cpp:665
dir
QDir dir
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1171
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:284
GetAppBinDir
QString GetAppBinDir(void)
Definition: mythdirs.cpp:221
kHKRunOnStartup
@ kHKRunOnStartup
task is queued when HouseKeeper is started
Definition: housekeeper.h:35
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:856
extractZIP
bool extractZIP(const QString &zipFile, const QString &outDir)
Definition: mythcoreutil.cpp:71
logPropagateArgs
QString logPropagateArgs
Definition: logging.cpp:89
RadioStreamUpdateTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: backendhousekeeper.cpp:553
GENERIC_EXIT_RUNNING
#define GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:25
RadioStreamUpdateTask::DoRun
bool DoRun(void) override
Definition: backendhousekeeper.cpp:509
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:107
JobQueue::RecoverOldJobsInQueue
static void RecoverOldJobsInQueue()
Definition: jobqueue.h:209
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:916
GetMythDownloadManager
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
Definition: mythdownloadmanager.cpp:161
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:688