aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Rector <rmrector@gmail.com>2024-07-13 13:31:02 -0600
committerRyan Rector <rmrector@gmail.com>2024-07-14 10:30:35 -0600
commitfca2711f66a27d16f088f69f3cb05bff4b1bd249 (patch)
tree7001979423dc2039e66223e1f5c86606e209be4f
parent6e31bd7c959bde02d0606828e351096a3e32ba7c (diff)
add manual action to clean all unused images
-rw-r--r--addons/resource.language.en_gb/resources/strings.po21
-rwxr-xr-xsystem/settings/settings.xml6
-rw-r--r--xbmc/TextureCache.cpp80
-rw-r--r--xbmc/TextureCache.h6
-rw-r--r--xbmc/settings/MediaSettings.cpp5
-rw-r--r--xbmc/settings/Settings.cpp1
-rw-r--r--xbmc/settings/Settings.h1
7 files changed, 118 insertions, 2 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index bc5d2f735b..d0064af1b9 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -1508,6 +1508,7 @@ msgid "(0=auto)"
msgstr ""
#. generic "cleaning database" label used in different places
+#: xbmc/TextureCache.cpp
#: xbmc/music/MusicDatabase.cpp
#: xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
#: xbmc/settings/MediaSettings.cpp
@@ -8772,7 +8773,25 @@ msgctxt "#14277"
msgid "Allow remote control from applications on other systems"
msgstr ""
-#empty strings from id 14278 to 14300
+#empty strings from id 14278 to 14279
+
+#: system/settings/settings.xml
+msgctxt "#14280"
+msgid "Maintenance"
+msgstr ""
+
+#: system/settings/settings.xml
+#: xbmc/TextureCache.cpp
+msgctxt "#14281"
+msgid "Clean image cache"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#14282"
+msgid "Immediately remove unused images from the cache - images not associated with an item in the media library nor viewed recently. Kodi does this over time in the background."
+msgstr ""
+
+#empty strings from id 14283 to 14300
#. pvr "channels" settings group label
#: system/settings/settings.xml
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
index ff748c2584..1c54a059c6 100755
--- a/system/settings/settings.xml
+++ b/system/settings/settings.xml
@@ -1018,6 +1018,12 @@
<control type="button" format="action" />
</setting>
</group>
+ <group id="4" label="14280">
+ <setting id="maintenance.cleanimagecache" type="action" label="14281" help="14282">
+ <level>3</level>
+ <control type="button" format="action" />
+ </setting>
+ </group>
</category>
<category id="filelists" label="16000" help="36121">
<group id="1" label="593">
diff --git a/xbmc/TextureCache.cpp b/xbmc/TextureCache.cpp
index 4d8fb2c047..89705ae06c 100644
--- a/xbmc/TextureCache.cpp
+++ b/xbmc/TextureCache.cpp
@@ -12,8 +12,11 @@
#include "TextureCacheJob.h"
#include "URL.h"
#include "commons/ilog.h"
+#include "dialogs/GUIDialogProgress.h"
#include "filesystem/File.h"
#include "filesystem/IFileTypes.h"
+#include "guilib/GUIComponent.h"
+#include "guilib/GUIWindowManager.h"
#include "guilib/Texture.h"
#include "imagefiles/ImageCacheCleaner.h"
#include "imagefiles/ImageFileURL.h"
@@ -350,12 +353,87 @@ bool CTextureCache::Export(const std::string &image, const std::string &destinat
return false;
}
+bool CTextureCache::CleanAllUnusedImages()
+{
+ if (m_cleaningInProgress.test_and_set())
+ return false;
+
+ auto progress = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogProgress>(
+ WINDOW_DIALOG_PROGRESS);
+ if (progress)
+ {
+ progress->SetHeading(CVariant{14281}); //"Clean image cache"
+ progress->SetText(CVariant{313}); //"Cleaning database"
+ progress->SetPercentage(0);
+ progress->Open();
+ progress->ShowProgressBar(true);
+ }
+
+ bool failure = false;
+ CServiceBroker::GetJobManager()->Submit([this, progress, &failure]()
+ { failure = CleanAllUnusedImagesJob(progress); });
+
+ // Wait for clean to complete or be canceled, but render every 10ms so that the
+ // pointer movements work on dialog even when clean is reporting progress infrequently
+ if (progress)
+ progress->Wait();
+
+ m_cleaningInProgress.clear();
+ return !failure;
+}
+
+bool CTextureCache::CleanAllUnusedImagesJob(CGUIDialogProgress* progress)
+{
+ auto cleaner = IMAGE_FILES::CImageCacheCleaner::Create();
+ if (!cleaner)
+ {
+ if (progress)
+ progress->Close();
+ return false;
+ }
+
+ const unsigned int cleanAmount = 1000000;
+ const auto result = cleaner->ScanOldestCache(cleanAmount);
+ if (progress && progress->IsCanceled())
+ {
+ progress->Close();
+ return false;
+ }
+
+ const auto total = result.imagesToClean.size();
+ unsigned int current = 0;
+ for (const auto& image : result.imagesToClean)
+ {
+ ClearCachedImage(image);
+ if (progress)
+ {
+ if (progress->IsCanceled())
+ {
+ progress->Close();
+ return false;
+ }
+ int percentage = static_cast<unsigned long long>(current) * 100 / total;
+ if (progress->GetPercentage() != percentage)
+ {
+ progress->SetPercentage(percentage);
+ progress->Progress();
+ }
+ current++;
+ }
+ }
+
+ if (progress)
+ progress->Close();
+ return true;
+}
+
void CTextureCache::CleanTimer()
{
CServiceBroker::GetJobManager()->Submit(
[this]()
{
- auto next = ScanOldestCache();
+ auto next = m_cleaningInProgress.test_and_set() ? std::chrono::hours(1) : ScanOldestCache();
+ m_cleaningInProgress.clear();
m_cleanTimer.Start(next);
},
CJob::PRIORITY_LOW_PAUSABLE);
diff --git a/xbmc/TextureCache.h b/xbmc/TextureCache.h
index 6b0bf44d21..3d77f2c6ab 100644
--- a/xbmc/TextureCache.h
+++ b/xbmc/TextureCache.h
@@ -15,12 +15,14 @@
#include "threads/Timer.h"
#include "utils/JobManager.h"
+#include <atomic>
#include <chrono>
#include <memory>
#include <set>
#include <string>
#include <vector>
+class CGUIDialogProgress;
class CJob;
class CURL;
class CTexture;
@@ -155,6 +157,8 @@ public:
bool Export(const std::string &image, const std::string &destination, bool overwrite);
bool Export(const std::string &image, const std::string &destination); //! @todo BACKWARD COMPATIBILITY FOR MUSIC THUMBS
+ bool CleanAllUnusedImages();
+
private:
// private construction, and no assignments; use the provided singleton methods
CTextureCache(const CTextureCache&) = delete;
@@ -218,7 +222,9 @@ private:
void CleanTimer();
std::chrono::milliseconds ScanOldestCache();
+ bool CleanAllUnusedImagesJob(CGUIDialogProgress* progress);
+ std::atomic_flag m_cleaningInProgress;
CTimer m_cleanTimer;
CCriticalSection m_databaseSection;
CTextureDatabase m_database;
diff --git a/xbmc/settings/MediaSettings.cpp b/xbmc/settings/MediaSettings.cpp
index 097a9c11f0..76c97b3289 100644
--- a/xbmc/settings/MediaSettings.cpp
+++ b/xbmc/settings/MediaSettings.cpp
@@ -10,6 +10,7 @@
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
+#include "TextureCache.h"
#include "cores/RetroPlayer/RetroPlayerUtils.h"
#include "dialogs/GUIDialogFileBrowser.h"
#include "guilib/LocalizeStrings.h"
@@ -367,6 +368,10 @@ void CMediaSettings::OnSettingAction(const std::shared_ptr<const CSetting>& sett
videodatabase.Close();
}
}
+ else if (settingId == CSettings::SETTING_MAINTENANCE_CLEANIMAGECACHE)
+ {
+ CServiceBroker::GetTextureCache()->CleanAllUnusedImages();
+ }
}
void CMediaSettings::OnSettingChanged(const std::shared_ptr<const CSetting>& setting)
diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp
index a32f5f17bc..d80354679a 100644
--- a/xbmc/settings/Settings.cpp
+++ b/xbmc/settings/Settings.cpp
@@ -560,6 +560,7 @@ void CSettings::InitializeISettingCallbacks()
settingSet.insert(CSettings::SETTING_VIDEOLIBRARY_IMPORT);
settingSet.insert(CSettings::SETTING_VIDEOLIBRARY_EXPORT);
settingSet.insert(CSettings::SETTING_VIDEOLIBRARY_SHOWUNWATCHEDPLOTS);
+ settingSet.insert(CSettings::SETTING_MAINTENANCE_CLEANIMAGECACHE);
GetSettingsManager()->RegisterCallback(&CMediaSettings::GetInstance(), settingSet);
settingSet.clear();
diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h
index 354756d133..dfc87db9f2 100644
--- a/xbmc/settings/Settings.h
+++ b/xbmc/settings/Settings.h
@@ -282,6 +282,7 @@ public:
static constexpr auto SETTING_MUSICLIBRARY_EXPORT_ARTWORK = "musiclibrary.exportartwork";
static constexpr auto SETTING_MUSICLIBRARY_EXPORT_SKIPNFO = "musiclibrary.exportskipnfo";
static constexpr auto SETTING_MUSICLIBRARY_IMPORT = "musiclibrary.import";
+ static constexpr auto SETTING_MAINTENANCE_CLEANIMAGECACHE = "maintenance.cleanimagecache";
static constexpr auto SETTING_MUSICPLAYER_AUTOPLAYNEXTITEM = "musicplayer.autoplaynextitem";
static constexpr auto SETTING_MUSICPLAYER_QUEUEBYDEFAULT = "musicplayer.queuebydefault";
static constexpr auto SETTING_MUSICPLAYER_SEEKSTEPS = "musicplayer.seeksteps";