From 71803020e7ba1b55a28f7c70bf85e4c4fa523a2b Mon Sep 17 00:00:00 2001 From: Kotesh Kumar Yelamati Date: Fri, 12 Jun 2026 18:47:53 -0400 Subject: [PATCH] feat: add Opera and Opera GX browser cache support --- src/sifty/core/junk.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/sifty/core/junk.py b/src/sifty/core/junk.py index d5004f3..8d1854f 100644 --- a/src/sifty/core/junk.py +++ b/src/sifty/core/junk.py @@ -29,6 +29,10 @@ def _local_appdata() -> Path | None: return _env_path("LOCALAPPDATA") +def _roaming_appdata() -> Path | None: + return _env_path("APPDATA") + + def _browser_cache_roots(local: Path) -> list[Path]: """Cache directories across ALL profiles of the installed browsers. @@ -60,6 +64,29 @@ def _browser_cache_roots(local: Path) -> list[Path]: if cand.is_dir(): roots.append(cand) + # Opera and Opera GX store their User Data under %APPDATA% (roaming), not %LOCALAPPDATA%. + appdata = _roaming_appdata() + if appdata: + opera_user_data = [ + appdata / "Opera Software" / "Opera Stable", + appdata / "Opera Software" / "Opera GX Stable", + ] + for user_data in opera_user_data: + if not user_data.is_dir(): + continue + try: + profiles = [ + p for p in user_data.iterdir() + if p.is_dir() and (p.name == "Default" or p.name.startswith("Profile")) + ] + except OSError: + continue + for profile in profiles: + for sub in ("Cache", "Code Cache", "GPUCache"): + cand = profile / sub + if cand.is_dir(): + roots.append(cand) + firefox_profiles = local / "Mozilla" / "Firefox" / "Profiles" if firefox_profiles.is_dir(): try: @@ -108,7 +135,7 @@ def junk_categories(config=None) -> list[JunkCategory]: cats.append( JunkCategory( "browser-cache", "Browser caches", - "On-disk caches for every Chrome/Edge/Brave/Vivaldi profile and " + "On-disk caches for every Chrome/Edge/Brave/Vivaldi/Opera profile and " "Firefox (never cookies, history, or passwords).", _browser_cache_roots(local), )