made file downloading and caching smarter
tries eTag and ContentDisposition headers for file name+format catches offline and server error/url error scenarios creates a "recent" file copy if successful, and returns that as a fallback in an error scenario, if it exists
This commit is contained in:
parent
230b7338a6
commit
ba0cbbd5c8
@ -12,13 +12,19 @@ namespace TED.Utils
|
||||
internal class FileUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL of the file to download.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result is the path to the downloaded (or cached) file.</returns>
|
||||
public static async Task<string> DownloadAndCacheFileAsync(string url)
|
||||
{
|
||||
var tedDirectory = Path.Combine(Path.GetTempPath(), "TED");
|
||||
var recentPath = Path.Combine(tedDirectory, "recent.png");
|
||||
|
||||
try
|
||||
{
|
||||
using (var client = new HttpClient()
|
||||
{
|
||||
@ -26,22 +32,48 @@ namespace TED.Utils
|
||||
})
|
||||
{
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
try
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var etag = response.Headers.ETag?.Tag.Replace("\"", string.Empty) ?? "untagged";
|
||||
if (!Directory.Exists(Path.Combine(Path.GetTempPath(), "TED")))
|
||||
{
|
||||
Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "TED"));
|
||||
}
|
||||
var path = Path.Combine(Path.GetTempPath(), "TED", $"{etag}.png");
|
||||
|
||||
if (File.Exists(path))
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
return path;
|
||||
// If we catch here, it's a URL error or server-side issue.
|
||||
if (File.Exists(recentPath))
|
||||
{
|
||||
return recentPath;
|
||||
}
|
||||
|
||||
var filesToDelete = Directory.GetFiles(Path.Combine(Path.GetTempPath(), "TED"), "*.png")
|
||||
.Where(filePath => Path.GetFileNameWithoutExtension(filePath) != etag);
|
||||
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);
|
||||
@ -49,13 +81,28 @@ namespace TED.Utils
|
||||
|
||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
||||
{
|
||||
using (var fileStream = new FileStream(path, FileMode.CreateNew))
|
||||
using (var fileStream = new FileStream(downloadPath, FileMode.CreateNew))
|
||||
{
|
||||
await stream.CopyToAsync(fileStream);
|
||||
return path;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user