diff --git a/src/TED/TED.Utils/FileUtilities.cs b/src/TED/TED.Utils/FileUtilities.cs
index d9acb99..9a16e18 100644
--- a/src/TED/TED.Utils/FileUtilities.cs
+++ b/src/TED/TED.Utils/FileUtilities.cs
@@ -12,49 +12,96 @@ namespace TED.Utils
internal class FileUtilities
{
///
- /// Downloads a file from a specified URL and saves it to a cache.
+ /// Downloads a file from a specified URL and saves it to a local cache.
/// If the file already exists in the cache, the function returns the path to the cached file.
/// If the file does not exist in the cache, the function downloads the file, saves it to the cache, and then returns the path to the cached file.
+ /// In the event of an error with file retrieval, the most recently used file will be returned, if it exists.
///
/// The URL of the file to download.
/// A task that represents the asynchronous operation. The task result is the path to the downloaded (or cached) file.
public static async Task DownloadAndCacheFileAsync(string url)
{
- using (var client = new HttpClient()
+ var tedDirectory = Path.Combine(Path.GetTempPath(), "TED");
+ var recentPath = Path.Combine(tedDirectory, "recent.png");
+
+ try
{
- Timeout = TimeSpan.FromSeconds(10)
- })
- {
- var response = await client.GetAsync(url);
- response.EnsureSuccessStatusCode();
-
- var etag = response.Headers.ETag?.Tag.Replace("\"", string.Empty) ?? "untagged";
- if (!Directory.Exists(Path.Combine(Path.GetTempPath(), "TED")))
+ using (var client = new HttpClient()
{
- Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "TED"));
- }
- var path = Path.Combine(Path.GetTempPath(), "TED", $"{etag}.png");
-
- if (File.Exists(path))
+ Timeout = TimeSpan.FromSeconds(10)
+ })
{
- return path;
- }
+ var response = await client.GetAsync(url);
- var filesToDelete = Directory.GetFiles(Path.Combine(Path.GetTempPath(), "TED"), "*.png")
- .Where(filePath => Path.GetFileNameWithoutExtension(filePath) != etag);
- foreach (var fileToDelete in filesToDelete)
- {
- File.Delete(fileToDelete);
- }
-
- using (var stream = await response.Content.ReadAsStreamAsync())
- {
- using (var fileStream = new FileStream(path, FileMode.CreateNew))
+ try
{
- await stream.CopyToAsync(fileStream);
- return path;
+ response.EnsureSuccessStatusCode();
+ }
+ catch (HttpRequestException e)
+ {
+ // If we catch here, it's a URL error or server-side issue.
+ if (File.Exists(recentPath))
+ {
+ return recentPath;
+ }
+
+ return string.Empty;
+ }
+
+ var fileName = "ted.png";
+
+ if (response.Headers.ETag != null)
+ {
+ fileName = $"{response.Headers.ETag?.Tag.Replace("\"", string.Empty)}.png";
+ }
+ else if (response.Content.Headers.ContentDisposition != null)
+ {
+ fileName = $"{response.Content.Headers.ContentDisposition.FileName}";
+ }
+
+ if (!Directory.Exists(tedDirectory))
+ {
+ Directory.CreateDirectory(tedDirectory);
+ }
+
+ var downloadPath = Path.Combine(tedDirectory, fileName);
+
+
+ if (File.Exists(downloadPath))
+ {
+ return downloadPath;
+ }
+
+ var filesToDelete = Directory.GetFiles(tedDirectory)
+ .Where(filePath => Path.GetFileNameWithoutExtension(filePath) != fileName && Path.GetFileNameWithoutExtension(filePath) != "recent");
+ foreach (var fileToDelete in filesToDelete)
+ {
+ File.Delete(fileToDelete);
+ }
+
+ using (var stream = await response.Content.ReadAsStreamAsync())
+ {
+ using (var fileStream = new FileStream(downloadPath, FileMode.CreateNew))
+ {
+ await stream.CopyToAsync(fileStream);
+ if(File.Exists(recentPath))
+ {
+ File.Delete(recentPath);
+ }
+ File.Copy(downloadPath, recentPath);
+ return downloadPath;
+ }
}
}
+ } catch(HttpRequestException e)
+ {
+ // If we catch here, we're offline.
+ if (File.Exists(recentPath))
+ {
+ return recentPath;
+ }
+
+ return string.Empty;
}
}