-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFirefoxCleaner.cs
More file actions
173 lines (149 loc) · 5.61 KB
/
Copy pathFirefoxCleaner.cs
File metadata and controls
173 lines (149 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace TempFileCleaner
{
#region [Testing]
public static class Test
{
public static async Task Run(bool dryRun = true)
{
var engine = new CleanupEngine();
var result = await engine.SweepAsync(Targets.All, dryRun);
Debug.WriteLine($"[INFO] Total deleted: {result.TotalDeletedFiles}, Total failed: {result.TotalFailedFiles}");
Debug.WriteLine($"[INFO] Folder Results:");
foreach (var folder in result.FolderResults)
Debug.WriteLine($" - {folder}");
}
}
#endregion
#region [Models]
public enum CleanupPolicy
{
SafeToDelete,
Conditional,
DoNotTouch
}
public class CleanupTarget
{
public string Name { get; set; }
public string[] Paths { get; set; }
public CleanupPolicy Policy { get; set; }
}
public class CleanupResult
{
public List<FolderCleanupResult> FolderResults { get; } = new();
public int TotalDeletedFiles => FolderResults.Sum(f => f.DeletedFiles);
public int TotalFailedFiles => FolderResults.Sum(f => f.FailedFiles);
public int TotalSkippedFolders => FolderResults.Count(f => f.Skipped);
}
public class FolderCleanupResult
{
public string Folder { get; set; }
public int DeletedFiles { get; set; }
public int FailedFiles { get; set; }
public bool Skipped { get; set; }
public override string ToString() => $"{Folder} | Deleted: {DeletedFiles}, Failed: {FailedFiles}, Skipped: {Skipped}";
}
#endregion
#region [Cleaner Methods]
public static class Targets
{
public static List<CleanupTarget> All = new()
{
// TODO: Add existing Windows 11 temp locations here.
// Firefox Classic
new CleanupTarget
{
Name = "Firefox Cache (Classic Version)",
Paths = new[]
{
@"%LOCALAPPDATA%\Mozilla\Firefox\Profiles\*\cache2",
@"%LOCALAPPDATA%\Mozilla\Firefox\Profiles\*\cache2\entries"
},
Policy = CleanupPolicy.SafeToDelete
},
// Firefox Store Version (UWP/WinUI)
new CleanupTarget
{
Name = "Firefox Cache (AppStore Version)",
Paths = new[]
{
@"%LOCALAPPDATA%\Packages\Mozilla.Firefox_*\LocalCache\Local\Mozilla\Firefox\Profiles\*\cache2",
@"%LOCALAPPDATA%\Packages\Mozilla.Firefox_*\LocalCache\Local\Mozilla\Firefox\Profiles\*\cache2\entries"
},
Policy = CleanupPolicy.SafeToDelete
}
};
}
public static class PathExpander
{
public static IEnumerable<string> Expand(string pattern)
{
var expanded = Environment.ExpandEnvironmentVariables(pattern);
// If no wildcard, return directly
if (!expanded.Contains("*"))
return Directory.Exists(expanded) ? new[] { expanded } : Enumerable.Empty<string>();
// Split into root + wildcard segment
var root = expanded.Substring(0, expanded.IndexOf('*')).TrimEnd('\\');
if (!Directory.Exists(root))
return Enumerable.Empty<string>();
var wildcardPart = expanded.Substring(root.Length).TrimStart('\\');
return Directory.GetDirectories(root, wildcardPart.Split('\\')[0])
.Select(d => Path.Combine(d, wildcardPart.Substring(wildcardPart.IndexOf('\\') + 1)))
.Where(Directory.Exists);
}
}
public class CleanupEngine
{
public async Task<CleanupResult> SweepAsync(IEnumerable<CleanupTarget> targets, bool dryRun = false)
{
var result = new CleanupResult();
foreach (var target in targets)
{
foreach (var pattern in target.Paths)
{
var expanded = PathExpander.Expand(pattern);
foreach (var folder in expanded)
{
var folderResult = await CleanFolderAsync(folder, target.Policy, dryRun);
result.FolderResults.Add(folderResult);
}
}
}
return result;
}
private async Task<FolderCleanupResult> CleanFolderAsync(string folder, CleanupPolicy policy, bool dryRun)
{
var result = new FolderCleanupResult { Folder = folder };
if (policy == CleanupPolicy.DoNotTouch)
{
result.Skipped = true;
return result;
}
if (!Directory.Exists(folder))
return result;
var files = Directory.GetFiles(folder, "*", SearchOption.AllDirectories);
foreach (var file in files)
{
try
{
if (!dryRun)
File.Delete(file);
result.DeletedFiles++;
}
catch
{
result.FailedFiles++;
}
}
return result;
}
}
#endregion
}