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,32 +1,41 @@
|
||||
using Downloader;
|
||||
using DownloadManager.Models;
|
||||
using DownloadManager.Models.UrlGetter;
|
||||
using DownloadManager.Utilities;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace DownloadManager.DownloaderCore;
|
||||
public class DownloadWorker(DownloadItemData itemData)
|
||||
{
|
||||
IDownload? _worker;
|
||||
DownloadItemData _downloadData = itemData;
|
||||
private IDownload? _worker;
|
||||
private DownloadItemData _downloadData = itemData;
|
||||
public DownloadItemData DownloadData => _downloadData;
|
||||
|
||||
public Action<DownloadWorker> OnDownloadStarted;
|
||||
public Action<DownloadWorker> OnDownloadFileCompleted;
|
||||
public Action<DownloadWorker> OnDownloadStop;
|
||||
public Action? OnDownloadStarted;
|
||||
public Action? OnDownloadFileCompleted;
|
||||
public Action? OnDownloadStop;
|
||||
|
||||
public bool BuildDownloadRequest()
|
||||
private int retryCount = 0;
|
||||
|
||||
public async Task<bool> BuildDownloadRequestAsync()
|
||||
{
|
||||
var urlGetter = UrlGetterFactory.CreateUrlGetter(_downloadData.UrlGetterType);
|
||||
var fileUrl = await urlGetter.GetFileUrl(_downloadData.Url);
|
||||
|
||||
if (fileUrl.Url == null || fileUrl.Name == null)
|
||||
return false;
|
||||
|
||||
_downloadData.Url = fileUrl.Url;
|
||||
_downloadData.FileName = fileUrl.Name;
|
||||
_downloadData.MD5 = fileUrl.MD5;
|
||||
|
||||
retryCount = _downloadData.DownloadConfiguration.MaxTryAgainOnFailover;
|
||||
|
||||
try
|
||||
{
|
||||
_worker = new DownloadBuilder()
|
||||
.WithUrl(_downloadData.Url)
|
||||
.WithDirectory(_downloadData.FilePath)
|
||||
.WithFileName(_downloadData.FileName)
|
||||
.WithConfiguration(_downloadData.downloadConfiguration)
|
||||
.Build();
|
||||
|
||||
_worker.DownloadStarted += DownloadStarted;
|
||||
_worker.DownloadProgressChanged += DownloadProgressChanged;
|
||||
_worker.DownloadFileCompleted += DownloadFileCompleted;
|
||||
|
||||
BuildWorker();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -36,33 +45,82 @@ public class DownloadWorker(DownloadItemData itemData)
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildWorker()
|
||||
{
|
||||
_worker = new DownloadBuilder()
|
||||
.WithUrl(_downloadData.Url)
|
||||
.WithDirectory(_downloadData.FilePath)
|
||||
.WithFileName(_downloadData.FileName)
|
||||
.WithConfiguration(_downloadData.DownloadConfiguration)
|
||||
.Build();
|
||||
|
||||
_worker.DownloadStarted += DownloadStarted;
|
||||
_worker.DownloadProgressChanged += DownloadProgressChanged;
|
||||
_worker.DownloadFileCompleted += DownloadFileCompleted;
|
||||
}
|
||||
|
||||
private void DownloadStarted(object? sender, DownloadStartedEventArgs e)
|
||||
{
|
||||
_downloadData.Status = DownloadStatus.Running;
|
||||
OnDownloadStarted?.Invoke(this);
|
||||
_downloadData.FileSize = DoubleUtilities.BytesToMegaBytes(e.TotalBytesToReceive, 2);
|
||||
OnDownloadStarted?.Invoke();
|
||||
}
|
||||
|
||||
private void DownloadProgressChanged(object? sender, DownloadProgressChangedEventArgs e)
|
||||
{
|
||||
_downloadData.Progress = (int)e.ProgressPercentage;
|
||||
_downloadData.Speed = e.BytesPerSecondSpeed;
|
||||
_downloadData.Speed = DoubleUtilities.BytesToMegaBytes(e.BytesPerSecondSpeed, 2);
|
||||
}
|
||||
|
||||
private void DownloadFileCompleted(object? sender, AsyncCompletedEventArgs e)
|
||||
private async void DownloadFileCompleted(object? sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
_downloadData.Status = DownloadStatus.Failed;
|
||||
throw e.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
_downloadData.Status = DownloadStatus.Completed;
|
||||
}
|
||||
_worker!.Dispose();
|
||||
|
||||
OnDownloadFileCompleted?.Invoke(this);
|
||||
// Check md5
|
||||
if (_downloadData.MD5 != null)
|
||||
{
|
||||
var fileFullName = Path.Combine(_downloadData.FilePath, _downloadData.FileName!);
|
||||
var md5 = MD5Utilities.GetMD5HashFromFile(fileFullName);
|
||||
if (md5 != _downloadData.MD5)
|
||||
{
|
||||
await RetryDownload();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
OnDownloadFileCompleted?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartDownload()
|
||||
private async Task<bool> RetryDownload()
|
||||
{
|
||||
if (retryCount > 0)
|
||||
{
|
||||
retryCount--;
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
await BuildDownloadRequestAsync();
|
||||
StartDownloadAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_downloadData.Status = DownloadStatus.Failed;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void StartDownloadAsync()
|
||||
{
|
||||
if (_worker == null)
|
||||
return;
|
||||
@@ -72,27 +130,18 @@ public class DownloadWorker(DownloadItemData itemData)
|
||||
|
||||
public void PauseDownload()
|
||||
{
|
||||
if (_worker == null)
|
||||
return;
|
||||
|
||||
_worker.Pause();
|
||||
OnDownloadStop?.Invoke(this);
|
||||
_worker?.Pause();
|
||||
OnDownloadStop?.Invoke();
|
||||
}
|
||||
|
||||
public void ResumeDownload()
|
||||
{
|
||||
if (_worker == null)
|
||||
return;
|
||||
|
||||
_worker.Resume();
|
||||
_worker?.Resume();
|
||||
}
|
||||
|
||||
public void StopDownload()
|
||||
{
|
||||
if (_worker == null)
|
||||
return;
|
||||
|
||||
_worker.Stop();
|
||||
OnDownloadStop?.Invoke(this);
|
||||
_worker?.Stop();
|
||||
OnDownloadStop?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user