Skip to content

Commit ebdddee

Browse files
committed
New task to delete temporary files. TODO: Remove obsolete AppPath and use Core.Utilities.FileSystemHelper instead.
1 parent c127d27 commit ebdddee

9 files changed

Lines changed: 456 additions & 0 deletions

File tree

src/Libraries/SmartStore.Core/SmartStore.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@
552552
<Compile Include="Utilities\DateTimeConvert.cs" />
553553
<Compile Include="Utilities\DictionaryConverter.cs" />
554554
<Compile Include="Utilities\FileDownloadManager.cs" />
555+
<Compile Include="Utilities\FileSystemHelper.cs" />
555556
<Compile Include="Utilities\Inflector.cs" />
556557
<Compile Include="Extensions\JsonExtensions.cs" />
557558
<Compile Include="Utilities\Prettifier.cs" />
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading;
4+
using System.Web.Hosting;
5+
6+
namespace SmartStore.Utilities
7+
{
8+
public static class FileSystemHelper
9+
{
10+
/// <summary>
11+
/// Returns physical path to temp directory
12+
/// </summary>
13+
/// <param name="subDirectory">Name of a sub directory to be created and returned (optional)</param>
14+
public static string TempDir(string subDirectory = null)
15+
{
16+
string path = CommonHelper.GetAppSetting<string>("sm:TempDirectory", "~/App_Data/_temp");
17+
path = HostingEnvironment.MapPath(path);
18+
19+
if (!Directory.Exists(path))
20+
Directory.CreateDirectory(path);
21+
22+
if (subDirectory.HasValue())
23+
{
24+
path = Path.Combine(path, subDirectory);
25+
26+
if (!Directory.Exists(path))
27+
Directory.CreateDirectory(path);
28+
}
29+
30+
return path;
31+
}
32+
33+
/// <summary>
34+
/// Safe way to cleanup the temp directory. Should be called via scheduled task.
35+
/// </summary>
36+
public static void TempCleanup()
37+
{
38+
try
39+
{
40+
string dir = FileSystemHelper.TempDir();
41+
42+
if (Directory.Exists(dir))
43+
{
44+
FileInfo fi;
45+
var oldestDate = DateTime.Now.Subtract(new TimeSpan(0, 5, 0, 0));
46+
var files = Directory.EnumerateFiles(dir);
47+
48+
foreach (string file in files)
49+
{
50+
fi = new FileInfo(file);
51+
52+
if (fi != null && fi.LastWriteTime < oldestDate)
53+
FileSystemHelper.Delete(file);
54+
}
55+
}
56+
}
57+
catch (Exception exc)
58+
{
59+
exc.Dump();
60+
}
61+
}
62+
63+
/// <summary>
64+
/// Safe way to delete a file.
65+
/// </summary>
66+
public static bool Delete(string path)
67+
{
68+
if (path.IsEmpty())
69+
return true;
70+
71+
bool result = true;
72+
try
73+
{
74+
if (Directory.Exists(path))
75+
{
76+
throw new MemberAccessException("Deleting folders cause of security reasons not possible: {0}".FormatWith(path));
77+
}
78+
79+
File.Delete(path); // no exception, if file doesn't exists
80+
}
81+
catch (Exception exc)
82+
{
83+
result = false;
84+
exc.Dump();
85+
}
86+
return result;
87+
}
88+
89+
/// <summary>
90+
/// Safe way to copy a file.
91+
/// </summary>
92+
public static bool Copy(string sourcePath, string destinationPath, bool overwrite = true, bool deleteSource = false)
93+
{
94+
bool result = true;
95+
try
96+
{
97+
File.Copy(sourcePath, destinationPath, overwrite);
98+
99+
if (deleteSource)
100+
Delete(sourcePath);
101+
}
102+
catch (Exception exc)
103+
{
104+
result = false;
105+
exc.Dump();
106+
}
107+
return result;
108+
}
109+
110+
/// <summary>
111+
/// Safe way to copy a directory and all content.
112+
/// </summary>
113+
/// <param name="source">Source directory</param>
114+
/// <param name="target">Target directory</param>
115+
/// <param name="overwrite">Whether to override existing files</param>
116+
public static void CopyDirectory(DirectoryInfo source, DirectoryInfo target, bool overwrite = true)
117+
{
118+
foreach (FileInfo fi in source.GetFiles())
119+
{
120+
try
121+
{
122+
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), overwrite);
123+
}
124+
catch (Exception exc)
125+
{
126+
exc.Dump();
127+
}
128+
}
129+
130+
foreach (DirectoryInfo sourceSubDir in source.GetDirectories())
131+
{
132+
try
133+
{
134+
DirectoryInfo targetSubDir = target.CreateSubdirectory(sourceSubDir.Name);
135+
CopyDirectory(sourceSubDir, targetSubDir, overwrite);
136+
}
137+
catch (Exception exc)
138+
{
139+
exc.Dump();
140+
}
141+
}
142+
}
143+
144+
/// <summary>
145+
/// Safe way to delete all directory content
146+
/// </summary>
147+
/// <param name="directoryPath">A directory path</param>
148+
public static void ClearDirectory(string directoryPath, bool selfToo)
149+
{
150+
if (directoryPath.IsEmpty())
151+
return;
152+
153+
try
154+
{
155+
var dir = new DirectoryInfo(directoryPath);
156+
157+
foreach (var fi in dir.GetFiles())
158+
{
159+
try
160+
{
161+
fi.IsReadOnly = false;
162+
fi.Delete();
163+
}
164+
catch (Exception)
165+
{
166+
try
167+
{
168+
Thread.Sleep(0);
169+
fi.Delete();
170+
}
171+
catch (Exception) { }
172+
}
173+
}
174+
175+
foreach (var di in dir.GetDirectories())
176+
{
177+
ClearDirectory(di.FullName, false);
178+
179+
try
180+
{
181+
di.Delete();
182+
}
183+
catch (Exception)
184+
{
185+
try
186+
{
187+
Thread.Sleep(0);
188+
di.Delete();
189+
}
190+
catch (Exception) { }
191+
}
192+
}
193+
}
194+
catch (Exception) { }
195+
196+
if (selfToo)
197+
{
198+
try
199+
{
200+
Directory.Delete(directoryPath, true); // just deletes the (now empty) directory
201+
}
202+
catch (Exception) { }
203+
}
204+
}
205+
206+
/// <summary>
207+
/// Safe way to count files in a directory
208+
/// </summary>
209+
/// <param name="directoryPath">A directory path</param>
210+
/// <returns>File count</returns>
211+
public static int CountFiles(string directoryPath)
212+
{
213+
try
214+
{
215+
return Directory.GetFiles(directoryPath).Length;
216+
}
217+
catch (Exception) { }
218+
219+
return 0;
220+
}
221+
222+
/// <summary>
223+
/// Safe way to empty a file
224+
/// </summary>
225+
/// <param name="path">File path</param>
226+
public static void ClearFile(string path)
227+
{
228+
try
229+
{
230+
if (path.HasValue())
231+
File.WriteAllText(path, "");
232+
}
233+
catch (Exception) { }
234+
}
235+
}
236+
}

src/Libraries/SmartStore.Data/Migrations/201504270946381_TempFileCleanupTask.Designer.cs

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace SmartStore.Data.Migrations
2+
{
3+
using System;
4+
using System.Data.Entity.Migrations;
5+
using SmartStore.Core.Domain.Tasks;
6+
using SmartStore.Data.Setup;
7+
8+
public partial class TempFileCleanupTask : DbMigration, IDataSeeder<SmartObjectContext>
9+
{
10+
public override void Up()
11+
{
12+
}
13+
14+
public override void Down()
15+
{
16+
}
17+
18+
public bool RollbackOnFailure
19+
{
20+
get { return false; }
21+
}
22+
23+
public void Seed(SmartObjectContext context)
24+
{
25+
context.Set<ScheduleTask>().AddOrUpdate(x => x.Type,
26+
new ScheduleTask
27+
{
28+
Name = "Cleanup temporary files",
29+
Seconds = 86400,
30+
Type = "SmartStore.Services.Common.TempFileCleanupTask, SmartStore.Services",
31+
Enabled = true,
32+
StopOnError = false
33+
}
34+
);
35+
36+
context.SaveChanges();
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)