13#include <QRegularExpression>
24#include "libmythbase/mythversion.h"
53 query.
prepare(
"DELETE FROM inuseprograms "
54 "WHERE hostname = :HOSTNAME AND "
55 "( recusage = 'recorder' OR recusage LIKE 'Unknown %' );");
66 query.
prepare(
"DELETE FROM inuseprograms "
67 "WHERE lastupdatetime < :FOURHOURSAGO ;");
68 query.
bindValue(
":FOURHOURSAGO", fourHoursAgo);
80 query.
prepare(
"SELECT DISTINCT chainid FROM tvchain "
81 "WHERE endtime > :FOURHOURSAGO ;");
82 query.
bindValue(
":FOURHOURSAGO", fourHoursAgo);
94 if (keepChains.isEmpty())
95 keepChains =
"'" + query.
value(0).toString() +
"'";
97 keepChains +=
", '" + query.
value(0).toString() +
"'";
100 if (keepChains.isEmpty())
101 msg =
"DELETE FROM tvchain WHERE endtime < now();";
104 msg = QString(
"DELETE FROM tvchain "
105 "WHERE chainid NOT IN ( %1 ) AND endtime < now();")
109 if (!deleteQuery.
exec())
120 std::array<std::array<QString,2>,5> tables {{
121 {
"recordedprogram",
"progstart" },
122 {
"recordedrating",
"progstart" },
123 {
"recordedcredits",
"progstart" },
124 {
"recordedmarkup",
"starttime" },
125 {
"recordedseek",
"starttime" },
133 querystr =
"CREATE TEMPORARY TABLE IF NOT EXISTS temprecordedcleanup ( "
134 "chanid int(10) unsigned NOT NULL default '0', "
135 "starttime datetime NOT NULL default '0000-00-00 00:00:00' "
138 if (!query.
exec(querystr))
141 "(creating temporary table)", query);
145 for (
const auto & [table,column] : tables)
147 query.
prepare(QString(
"TRUNCATE TABLE temprecordedcleanup;"));
151 "(truncating temporary table)", query);
155 query.
prepare(QString(
"INSERT INTO temprecordedcleanup "
156 "( chanid, starttime ) "
157 "SELECT DISTINCT chanid, starttime "
164 "(cleaning recorded tables)", query);
168 query.
prepare(QString(
"SELECT DISTINCT p.chanid, p.starttime "
169 "FROM temprecordedcleanup p "
170 "LEFT JOIN recorded r "
171 "ON p.chanid = r.chanid "
172 "AND p.starttime = r.%1 "
173 "WHERE r.chanid IS NULL;").arg(column));
177 "(cleaning recorded tables)", query);
181 deleteQuery.
prepare(QString(
"DELETE FROM %1 "
182 "WHERE chanid = :CHANID "
183 "AND starttime = :STARTTIME;")
189 if (!deleteQuery.
exec())
192 "(cleaning recorded tables)", deleteQuery);
198 if (!query.
exec(
"DROP TABLE temprecordedcleanup;"))
200 "(deleting temporary table)", query);
211 query.
prepare(QString(
"DELETE channel "
213 "LEFT JOIN recorded r "
214 " ON r.chanid = channel.chanid "
215 "LEFT JOIN oldrecorded o "
216 " ON o.chanid = channel.chanid "
217 "WHERE channel.deleted IS NOT NULL "
218 " AND channel.deleted < "
219 " DATE_SUB(NOW(), INTERVAL 1 DAY) "
220 " AND r.chanid IS NULL "
221 " AND o.chanid IS NULL"));
224 "(channel table)", query);
228 query.
prepare(QString(
"DELETE dtv_multiplex "
229 "FROM dtv_multiplex "
230 "LEFT JOIN channel c "
231 " ON c.mplexid = dtv_multiplex.mplexid "
232 "WHERE c.chanid IS NULL"));
235 "(dtv_multiplex table)", query);
239 query.
prepare(QString(
"DELETE iptv_channel "
241 "LEFT JOIN channel c "
242 " ON c.chanid = iptv_channel.chanid "
243 "WHERE c.chanid IS NULL"));
246 "(iptv_channel table)", query);
258 offset = std::max(newEpiWindow, offset);
260 query.
prepare(
"DELETE FROM oldprogram WHERE airdate < "
261 "DATE_SUB(CURRENT_DATE, INTERVAL 320 DAY);");
265 query.
prepare(
"REPLACE INTO oldprogram (oldtitle,airdate) "
266 "SELECT title,starttime FROM program "
267 "WHERE starttime < NOW() AND manualid = 0 "
272 query.
prepare(
"DELETE FROM program WHERE starttime <= "
273 "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
278 query.
prepare(
"DELETE FROM programrating WHERE starttime <= "
279 "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
284 query.
prepare(
"DELETE FROM programgenres WHERE starttime <= "
285 "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
290 query.
prepare(
"DELETE FROM credits WHERE starttime <= "
291 "DATE_SUB(CURRENT_DATE, INTERVAL :OFFSET DAY);");
296 query.
prepare(
"DELETE FROM record WHERE (type = :SINGLE "
297 "OR type = :OVERRIDE OR type = :DONTRECORD) "
298 "AND enddate < CURDATE();");
306 findq.
prepare(
"SELECT record.recordid FROM record "
307 "LEFT JOIN oldfind ON oldfind.recordid = record.recordid "
308 "WHERE type = :FINDONE AND oldfind.findid IS NOT NULL;");
313 query.
prepare(
"DELETE FROM record WHERE recordid = :RECORDID;");
321 query.
prepare(
"DELETE FROM oldfind WHERE findid < TO_DAYS(NOW()) - 14;");
325 query.
prepare(
"DELETE FROM oldrecorded WHERE "
326 "recstatus <> :RECORDED AND duplicate = 0 AND "
327 "endtime < DATE_SUB(CURRENT_DATE, INTERVAL :CLEAN DAY);");
344 bool devel {
false };
348 if (!parsed || devel)
350 LOG(VB_GENERAL, LOG_INFO, QString(
"Loading themes for devel"));
355 LOG(VB_GENERAL, LOG_INFO, QString(
"Loading themes for %1").arg(major));
356 result |=
LoadVersion(QString::number(major), LOG_ERR);
358 for (
int i =
minor ; i > 0; i--)
360 QString majmin = QString(
"%1.%2").arg(major).arg(i);
361 LOG(VB_GENERAL, LOG_INFO,
362 QString(
"Loading themes for %1").arg(majmin));
372 remoteThemesDir.append(
"/tmp/remotethemes");
374 QDir dir(remoteThemesDir);
375 if (!dir.exists() && !dir.mkpath(remoteThemesDir))
377 LOG(VB_GENERAL, LOG_ERR,
378 QString(
"HouseKeeper: Error creating %1 "
379 "directory for remote themes info cache.")
380 .arg(remoteThemesDir));
384 QString remoteThemesFile = remoteThemesDir;
385 remoteThemesFile.append(
"/themes.zip");
387 m_url = QString(
"%1/%2/themes.zip")
389 "http://themes.mythtv.org/themes/repository"),
398 LOG(VB_GENERAL, (LogLevel_t)download_log_level,
399 QString(
"HouseKeeper: Failed to download %1 "
400 "remote themes info package.").arg(
m_url));
404 if (!
extractZIP(remoteThemesFile, remoteThemesDir))
406 LOG(VB_GENERAL, LOG_ERR,
407 QString(
"HouseKeeper: Error extracting %1 "
408 "remote themes info package.").arg(remoteThemesFile));
409 QFile::remove(remoteThemesFile);
441 args <<
"--updateradiostreams";
444 LOG(VB_GENERAL, LOG_INFO, QString(
"Performing Radio Streams Update: %1 %2")
445 .arg(command,
args.join(
" ")));
457 LOG(VB_GENERAL, LOG_ERR, QString(
"Update Radio Streams command '%1' failed")
462 LOG(VB_GENERAL, LOG_INFO, QString(
"Radio Streams Update Complete"));
476 if (!setting.isEmpty())
478 GetMythDB()->ClearSetting(
"MusicStreamListModified");
509 QString command =
GetAppBinDir() +
"mythmetadatalookup";
511 args <<
"--refresh-all-artwork";
514 LOG(VB_GENERAL, LOG_INFO, QString(
"Performing Artwork Refresh: %1 %2")
515 .arg(command,
args.join(
" ")));
527 LOG(VB_GENERAL, LOG_ERR, QString(
"Artwork command '%1' failed")
531 LOG(VB_GENERAL, LOG_INFO, QString(
"Artwork Refresh Complete"));
616 LOG(VB_GENERAL, LOG_DEBUG,
"MythFillDatabase is disabled. Cannot run.");
628 "1970-01-01T00:00:00"));
629 LOG(VB_GENERAL, LOG_DEBUG,
630 QString(
"MythFillDatabase scheduled to run at %1.")
631 .arg(nextRun.toString()));
635 GetMythDB()->ClearSettingsCache(
"MythFillSuggestedRunTime");
638 return nextRun <= now;
645 LOG(VB_GENERAL, LOG_DEBUG,
"Performing daily run check.");
665 if (mfpath ==
"mythfilldatabase")
671 QString cmd = QString(
"%1 %2").arg(mfpath, mfarg);
683 LOG(VB_GENERAL, LOG_ERR, QString(
"MythFillDatabase command '%1' failed")
static constexpr int64_t kFourHours
void Terminate(void) override
~ArtworkTask(void) override
MythSystemLegacy * m_msMML
bool DoCheckRun(const QDateTime &now) override
bool DoRun(void) override
static void CleanupChannelTables(void)
static void CleanupProgramListings(void)
static void CleanupRecordedTables(void)
static void CleanupInUsePrograms(void)
bool DoRun(void) override
static void CleanupOrphanedLiveTV(void)
static void CleanupOldRecordings(void)
Modified PeriodicHouseKeeperTask for tasks to be run once daily.
virtual void SetHourWindow(std::chrono::hours min, std::chrono::hours max)
bool InWindow(const QDateTime &now) override
bool DoRun(void) override
static void CleanupOldJobsInQueue()
static void RecoverOldJobsInQueue()
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetHostName(void)
QString GetSetting(const QString &key, const QString &defaultval="")
int GetNumSetting(const QString &key, int defaultval=0)
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
bool GetBoolSetting(const QString &key, bool defaultval=false)
static void DBError(const QString &where, const MSqlQuery &query)
void cancelDownload(const QString &url, bool block=true)
Cancel a queued or current download.
bool download(const QString &url, const QString &dest, bool reload=false)
Downloads a URL to a file in blocking mode.
bool DoRun(void) override
MythSystemLegacy * m_msMFD
~MythFillDatabaseTask(void) override
void SetHourWindowFromDB(void)
bool DoCheckRun(const QDateTime &now) override
void Terminate(void) override
static bool UseSuggestedTime(void)
MythFillDatabaseTask(void)
uint Wait(std::chrono::seconds timeout=0s)
uint GetStatus(void) const
void Term(bool force=false)
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
bool DoCheckRun(const QDateTime &now) override
bool DoCheckRun(const QDateTime &now) override
bool DoRun(void) override
RadioStreamUpdateTask(void)
~RadioStreamUpdateTask(void) override
void Terminate(void) override
MythSystemLegacy * m_msMU
bool LoadVersion(const QString &version, int download_log_level)
bool DoRun(void) override
bool DoCheckRun(const QDateTime &now) override
void Terminate(void) override
@ GENERIC_EXIT_OK
Exited with no error.
@ GENERIC_EXIT_RUNNING
Process is running.
@ kHKGlobal
task should only run once per cluster e.g.
@ kHKRunOnStartup
task is queued when HouseKeeper is started
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetAppBinDir(void)
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
@ kMSPropagateLogs
add arguments for MythTV log propagation
@ kMSRunShell
run process through shell
@ kMSAutoCleanup
automatically delete if backgrounded
bool ParseMythSourceVersion(bool &devel, uint &major, uint &minor, const char *version)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
bool extractZIP(QString zipFile, const QString &outDir)