From f78f9992d754390fa42f109e5139b8eaf224d076 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 29 Feb 2012 11:56:24 +0000 Subject: [PATCH] Change delete behaviour so that we always use the deleted recording group allowing all recordings to be undeleted. By default we will only keep recordings for a minimum of 5 minutes (max ~20m) after their deletion, enough time to recover from a mistake but still free up space quickly. As before the user can specify to keep deleted recordings for a fixed number of days or until the space is needed for a new recording instead. Post 0.25 this change will allow us to strip out the old deletion code and simplify configuration process, the functional change is being made now to fix a couple of bugs caused by external processes such as MythPreviewGen blocking deletes from the UI. Fixes #9536 --- mythtv/bindings/python/MythTV/static.py | 2 +- mythtv/libs/libmyth/programinfo.cpp | 4 +-- mythtv/libs/libmyth/remoteutil.cpp | 7 ++--- mythtv/libs/libmythbase/mythversion.h | 7 +++-- mythtv/libs/libmythtv/dbcheck.cpp | 26 ++++++++++++++++ mythtv/programs/mythbackend/autoexpire.cpp | 30 +++++++++++++++++-- mythtv/programs/mythbackend/autoexpire.h | 4 ++- mythtv/programs/mythbackend/mainserver.cpp | 11 ++++--- .../programs/mythfrontend/globalsettings.cpp | 23 ++++++++++---- 9 files changed, 91 insertions(+), 23 deletions(-) diff --git a/mythtv/bindings/python/MythTV/static.py b/mythtv/bindings/python/MythTV/static.py index 6593a97c283..a2061d0fe0e 100644 --- a/mythtv/bindings/python/MythTV/static.py +++ b/mythtv/bindings/python/MythTV/static.py @@ -5,7 +5,7 @@ """ OWN_VERSION = (0,25,-1,3) -SCHEMA_VERSION = 1298 +SCHEMA_VERSION = 1299 NVSCHEMA_VERSION = 1007 MUSICSCHEMA_VERSION = 1018 PROTO_VERSION = '72' diff --git a/mythtv/libs/libmyth/programinfo.cpp b/mythtv/libs/libmyth/programinfo.cpp index 197d2b49706..3cf8cbf6edf 100644 --- a/mythtv/libs/libmyth/programinfo.cpp +++ b/mythtv/libs/libmyth/programinfo.cpp @@ -2782,8 +2782,8 @@ bool ProgramInfo::QueryIsDeleteCandidate(bool one_playback_allowed) const if (!IsRecording()) return false; - if (gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0) && - GetRecordingGroup() != "Deleted" && GetRecordingGroup() != "LiveTV") + // gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0) && + if (GetRecordingGroup() != "Deleted" && GetRecordingGroup() != "LiveTV") return true; bool ok = true; diff --git a/mythtv/libs/libmyth/remoteutil.cpp b/mythtv/libs/libmyth/remoteutil.cpp index 7beb7243325..a326c5ec855 100644 --- a/mythtv/libs/libmyth/remoteutil.cpp +++ b/mythtv/libs/libmyth/remoteutil.cpp @@ -139,11 +139,10 @@ bool RemoteUndeleteRecording(uint chanid, const QDateTime &recstartts) { bool result = false; - bool undelete_possible = - gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0); - - if (!undelete_possible) +#if 0 + if (!gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0)) return result; +#endif QStringList strlist(QString("UNDELETE_RECORDING")); strlist.push_back(QString::number(chanid)); diff --git a/mythtv/libs/libmythbase/mythversion.h b/mythtv/libs/libmythbase/mythversion.h index 43ace75bdbb..71295f1841e 100644 --- a/mythtv/libs/libmythbase/mythversion.h +++ b/mythtv/libs/libmythbase/mythversion.h @@ -50,11 +50,14 @@ * * MythTV Python Bindings * mythtv/bindings/python/MythTV/static.py + */ +#if 0 * * MythTV PHP Bindings * mythtv/bindings/php/MythBackend.php - */ -#define MYTH_DATABASE_VERSION "1298" +#endif + +#define MYTH_DATABASE_VERSION "1299" MBASE_PUBLIC const char *GetMythSourceVersion(); diff --git a/mythtv/libs/libmythtv/dbcheck.cpp b/mythtv/libs/libmythtv/dbcheck.cpp index 6c880031a8c..f92a7014b74 100644 --- a/mythtv/libs/libmythtv/dbcheck.cpp +++ b/mythtv/libs/libmythtv/dbcheck.cpp @@ -6258,6 +6258,32 @@ NULL return false; } + if (dbver == "1298") + { + QString queryStr; + if (gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0)) + { + queryStr = "UPDATE settings SET data='-1' WHERE " + "value='DeletedMaxAge' AND data='0'"; + } + else + { + queryStr = "UPDATE settings SET data='0' WHERE " + "value='DeletedMaxAge'"; + } + + MSqlQuery query(MSqlQuery::InitCon()); + query.prepare(queryStr); + if (!query.exec()) + { + MythDB::DBError("Could not perform update for '1299'", query); + return false; + } + + if (!UpdateDBVersionNumber("1299", dbver)) + return false; + } + return true; } diff --git a/mythtv/programs/mythbackend/autoexpire.cpp b/mythtv/programs/mythbackend/autoexpire.cpp index 3908783f2f6..41ce3f82d51 100644 --- a/mythtv/programs/mythbackend/autoexpire.cpp +++ b/mythtv/programs/mythbackend/autoexpire.cpp @@ -325,8 +325,11 @@ void AutoExpire::RunExpirer(void) ExpireLiveTV(emNormalLiveTVPrograms); - if (gCoreContext->GetNumSetting("DeletedMaxAge", 0)) + int maxAge = gCoreContext->GetNumSetting("DeletedMaxAge", 0); + if (maxAge > 0) ExpireOldDeleted(); + else if (maxAge == 0) + ExpireQuickDeleted(); ExpireEpisodesOverMax(); @@ -383,6 +386,19 @@ void AutoExpire::ExpireOldDeleted(void) ClearExpireList(expireList); } +/** + * \brief This expires deleted programs within a few minutes + */ +void AutoExpire::ExpireQuickDeleted(void) +{ + pginfolist_t expireList; + + LOG(VB_FILE, LOG_INFO, LOC + QString("ExpireQuickDeleted()")); + FillDBOrdered(expireList, emQuickDeletedPrograms); + SendDeleteMessages(expireList); + ClearExpireList(expireList); +} + /** \fn AutoExpire::ExpireRecordings() * \brief This expires normal recordings. * @@ -499,7 +515,7 @@ void AutoExpire::ExpireRecordings(void) QMap dirList; QList::iterator fsit2; - LOG(VB_FILE, LOG_INFO, + LOG(VB_FILE, LOG_INFO, QString(" Directories on filesystem ID %1:") .arg(fsit->getFSysID())); @@ -933,7 +949,7 @@ void AutoExpire::FillDBOrdered(pginfolist_t &expireList, int expMethod) orderby = "starttime ASC"; break; case emOldDeletedPrograms: - if ((maxAge = gCoreContext->GetNumSetting("DeletedMaxAge", 0)) == 0) + if ((maxAge = gCoreContext->GetNumSetting("DeletedMaxAge", 0)) <= 0) return; msg = QString("Adding programs deleted more than %1 days ago") .arg(maxAge); @@ -942,6 +958,14 @@ void AutoExpire::FillDBOrdered(pginfolist_t &expireList, int expMethod) .arg(maxAge); orderby = "starttime ASC"; break; + case emQuickDeletedPrograms: + if (gCoreContext->GetNumSetting("DeletedMaxAge", 0) != 0) + return; + msg = QString("Adding programs deleted more than 5 minutes ago"); + where = QString("recgroup = 'Deleted' " + "AND lastmodified <= DATE_ADD(NOW(), INTERVAL '-5' MINUTE) "); + orderby = "lastmodified ASC"; + break; case emNormalDeletedPrograms: if (gCoreContext->GetNumSetting("DeletedFifoOrder", 0) == 0) return; diff --git a/mythtv/programs/mythbackend/autoexpire.h b/mythtv/programs/mythbackend/autoexpire.h index 22ca2adbe86..8939f380be0 100644 --- a/mythtv/programs/mythbackend/autoexpire.h +++ b/mythtv/programs/mythbackend/autoexpire.h @@ -32,7 +32,8 @@ enum ExpireMethodType { emShortLiveTVPrograms = 10000, emNormalLiveTVPrograms = 10001, emOldDeletedPrograms = 10002, - emNormalDeletedPrograms = 10003 + emNormalDeletedPrograms = 10003, + emQuickDeletedPrograms = 10004 }; class AutoExpire; @@ -96,6 +97,7 @@ class AutoExpire : public QObject private: void ExpireLiveTV(int type); void ExpireOldDeleted(void); + void ExpireQuickDeleted(void); void ExpireRecordings(void); void ExpireEpisodesOverMax(void); diff --git a/mythtv/programs/mythbackend/mainserver.cpp b/mythtv/programs/mythbackend/mainserver.cpp index 50971dad39b..8e9d68bc3c9 100644 --- a/mythtv/programs/mythbackend/mainserver.cpp +++ b/mythtv/programs/mythbackend/mainserver.cpp @@ -2478,7 +2478,7 @@ void MainServer::DoHandleDeleteRecording( pbssock = pbs->getSocket(); bool justexpire = expirer ? false : - (gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete") && + ( //gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete") && (recinfo.GetRecordingGroup() != "Deleted") && (recinfo.GetRecordingGroup() != "LiveTV")); @@ -2628,19 +2628,22 @@ void MainServer::DoHandleUndeleteRecording( RecordingInfo &recinfo, PlaybackSock *pbs) { int ret = -1; - bool undelete_possible = - gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0); + MythSocket *pbssock = NULL; if (pbs) pbssock = pbs->getSocket(); - if (undelete_possible) +#if 0 + if (gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0)) { +#endif recinfo.ApplyRecordRecGroupChange("Default"); recinfo.UpdateLastDelete(false); recinfo.SaveAutoExpire(kDisableAutoExpire); ret = 0; +#if 0 } +#endif QStringList outputlist( QString::number(ret) ); SendResponse(pbssock, outputlist); diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp index 59928eea716..b8d042589eb 100644 --- a/mythtv/programs/mythfrontend/globalsettings.cpp +++ b/mythtv/programs/mythfrontend/globalsettings.cpp @@ -345,6 +345,7 @@ static GlobalSpinBox *AutoExpireExtraSpace() return bs; }; +#if 0 static GlobalCheckBox *AutoExpireInsteadOfDelete() { GlobalCheckBox *cb = new GlobalCheckBox("AutoExpireInsteadOfDelete"); @@ -355,14 +356,20 @@ static GlobalCheckBox *AutoExpireInsteadOfDelete() "instead of deleting immediately.")); return cb; } +#endif static GlobalSpinBox *DeletedMaxAge() { - GlobalSpinBox *bs = new GlobalSpinBox("DeletedMaxAge", 0, 365, 1); - bs->setLabel(QObject::tr("Deleted max age (days)")); - bs->setHelpText(QObject::tr("When set to a number greater than zero, " - "Auto-Expire will force expiration of Deleted recordings " - "when they are this many days old.")); + GlobalSpinBox *bs = new GlobalSpinBox("DeletedMaxAge", -1, 365, 1); + bs->setLabel(QObject::tr("Time to retain deleted recordings (days)")); + bs->setHelpText(QObject::tr("Determines the maximum number of days before " + "undeleting a recording will become impossible. " + "A value of zero means the recording will be " + "permanently deleted between 5 and 20 minutes " + "later. A value of minus one means recordings " + "will be retained until space is required. " + "A recording will always be removed before this " + "time if the space is needed for a new recording.")); bs->setValue(0); return bs; }; @@ -378,6 +385,7 @@ static GlobalCheckBox *DeletedFifoOrder() return cb; }; +#if 0 class DeletedExpireOptions : public TriggeredConfigurationGroup { public: @@ -399,6 +407,7 @@ class DeletedExpireOptions : public TriggeredConfigurationGroup addTarget("0", new HorizontalConfigurationGroup(true)); }; }; +#endif static GlobalComboBox *AutoExpireMethod() { @@ -3481,7 +3490,9 @@ GeneralSettings::GeneralSettings() expgrp->addChild(expgrp1); autoexp->addChild(expgrp); - autoexp->addChild(new DeletedExpireOptions()); +// autoexp->addChild(new DeletedExpireOptions()); + autoexp->addChild(DeletedFifoOrder()); + autoexp->addChild(DeletedMaxAge()); addChild(autoexp);