Refactor and enhance Download Manager application
- Added new services: IContentDialogService, ISnackbarService - Replaced DashboardPage and DashboardViewModel with DownloadingPage, DownloadingPageViewModel, WaitingPage, and WaitingPageViewModel - Introduced AddNewTaskPage and AddNewTaskViewModel - Replaced DownloadServiceManger with DownloadManagerService - Updated WPF-UI package to 3.0.4 and added HtmlAgilityPack 1.11.61 - Refactored DownloadWorker to use async methods and added retry logic - Converted DownloadItemData to partial class with ObservableProperty attributes - Changed initial navigation page to DownloadingPage - Updated MainWindow navigation items and title - Added new utility classes: DoubleUtilities, MD5Utilities, StringExtension - Added new XAML pages and ViewModels for task management and display - Removed obsolete DashboardPage and related files
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
using Downloader;
|
||||
using DownloadManager.Models.UrlGetter;
|
||||
|
||||
namespace DownloadManager.Models;
|
||||
public class DownloadItemData
|
||||
public partial class DownloadItemData : ObservableObject
|
||||
{
|
||||
public DownloadItemData(string fileName, string filePath, string url, DownloadConfiguration downloadConfig)
|
||||
public DownloadItemData(string filePath, string url, UrlGetterType urlGetterType, DownloadConfiguration downloadConfig)
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
FileName = fileName;
|
||||
FilePath = filePath;
|
||||
Url = url;
|
||||
downloadConfiguration = downloadConfig;
|
||||
UrlGetterType = urlGetterType;
|
||||
DownloadConfiguration = downloadConfig;
|
||||
}
|
||||
|
||||
public Guid Id
|
||||
@@ -17,38 +18,39 @@ public class DownloadItemData
|
||||
get;
|
||||
}
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get;
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? fileName;
|
||||
|
||||
public string FilePath
|
||||
{
|
||||
get;
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string filePath;
|
||||
|
||||
public string Url
|
||||
{
|
||||
get;
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string url;
|
||||
|
||||
public DownloadConfiguration downloadConfiguration
|
||||
{
|
||||
get;
|
||||
}
|
||||
[ObservableProperty]
|
||||
private double fileSize;
|
||||
|
||||
public long FileSize
|
||||
[ObservableProperty]
|
||||
private double speed;
|
||||
|
||||
[ObservableProperty]
|
||||
private int progress;
|
||||
|
||||
public string? MD5
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public double Speed
|
||||
|
||||
public UrlGetterType UrlGetterType
|
||||
{
|
||||
get; set;
|
||||
get;
|
||||
}
|
||||
public int Progress
|
||||
|
||||
public DownloadConfiguration DownloadConfiguration
|
||||
{
|
||||
get; set;
|
||||
get;
|
||||
}
|
||||
|
||||
public DownloadStatus Status
|
||||
{
|
||||
get; set;
|
||||
|
||||
13
Models/UrlGetter/DirectUrlGetter.cs
Normal file
13
Models/UrlGetter/DirectUrlGetter.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using DownloadManager.Utilities;
|
||||
|
||||
namespace DownloadManager.Models.UrlGetter
|
||||
{
|
||||
class DirectUrlGetter : IUrlGetter
|
||||
{
|
||||
public async Task<FileUrl> GetFileUrl(string taskUrl)
|
||||
{
|
||||
var fileName = System.IO.Path.GetFileName(taskUrl).ToUnescapedString();
|
||||
return new FileUrl(taskUrl, fileName, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Models/UrlGetter/IUrlGetter.cs
Normal file
12
Models/UrlGetter/IUrlGetter.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace DownloadManager.Models.UrlGetter;
|
||||
public struct FileUrl(string? url, string? name, string? md5)
|
||||
{
|
||||
public string? Url { get; } = url;
|
||||
public string? Name { get; } = name;
|
||||
public string? MD5 { get; } = md5;
|
||||
}
|
||||
|
||||
public interface IUrlGetter
|
||||
{
|
||||
public Task<FileUrl> GetFileUrl(string taskUrl);
|
||||
}
|
||||
15
Models/UrlGetter/UrlGetterFactory.cs
Normal file
15
Models/UrlGetter/UrlGetterFactory.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace DownloadManager.Models.UrlGetter
|
||||
{
|
||||
public class UrlGetterFactory
|
||||
{
|
||||
public static IUrlGetter CreateUrlGetter(UrlGetterType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
UrlGetterType.Direct => new DirectUrlGetter(),
|
||||
UrlGetterType.Yande => new YandeUrlGetter(),
|
||||
_ => throw new ArgumentException("Invalid UrlGetterType"),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Models/UrlGetter/UrlGetterType.cs
Normal file
12
Models/UrlGetter/UrlGetterType.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace DownloadManager.Models.UrlGetter
|
||||
{
|
||||
public enum UrlGetterType
|
||||
{
|
||||
[Description("Direct")]
|
||||
Direct,
|
||||
[Description("Yande post URL")]
|
||||
Yande,
|
||||
}
|
||||
}
|
||||
63
Models/UrlGetter/YandeUrlGetter.cs
Normal file
63
Models/UrlGetter/YandeUrlGetter.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using DownloadManager.Utilities;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DownloadManager.Models.UrlGetter;
|
||||
public class YandeUrlGetter : IUrlGetter
|
||||
{
|
||||
readonly HttpClient client = new ();
|
||||
const int maxRetries = 3;
|
||||
const int delayMilliseconds = 1000;
|
||||
|
||||
public async Task<FileUrl> GetFileUrl(string taskUrl)
|
||||
{
|
||||
// Get the ID of the post from the URL
|
||||
var id = taskUrl.Split("https://yande.re/post/show/").Last();
|
||||
|
||||
for (int attempt = 0; attempt < maxRetries; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await client.GetAsync($"https://yande.re/post.json?tags=id:{id}");
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var data = await response.Content.ReadFromJsonAsync<JsonElement[]>();
|
||||
if (data == null || data.Length == 0)
|
||||
{
|
||||
return new FileUrl(null, null, null);
|
||||
}
|
||||
|
||||
var firstElement = data.FirstOrDefault();
|
||||
if (firstElement.ValueKind != JsonValueKind.Object || !firstElement.TryGetProperty("file_url", out var fileUrlElement))
|
||||
{
|
||||
return new FileUrl(null, null, null);
|
||||
}
|
||||
|
||||
if (!firstElement.TryGetProperty("md5", out var md5Element))
|
||||
{
|
||||
return new FileUrl(null, null, null);
|
||||
}
|
||||
|
||||
var fileUrl = fileUrlElement.GetString();
|
||||
var fileName = Path.GetFileName(fileUrl)?.ToUnescapedString();
|
||||
var md5 = md5Element.GetString();
|
||||
|
||||
return new FileUrl(fileUrl, fileName, md5);
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
// Log the exception if needed
|
||||
}
|
||||
|
||||
// Wait before retrying
|
||||
await Task.Delay(delayMilliseconds);
|
||||
}
|
||||
|
||||
// If all retries fail, return a FileUrl with null values
|
||||
return new FileUrl(null, null, null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user