Files
community/Ink Canvas/Helpers/WebDavUploader.cs
T
2026-03-03 16:04:20 +08:00

172 lines
5.9 KiB
C#

using System;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using WebDav;
namespace Ink_Canvas.Helpers
{
/// <summary>
/// WebDav上传工具类
/// </summary>
public static class WebDavUploader
{
/// <summary>
/// 上传文件到WebDav服务器
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>是否上传成功</returns>
public static async Task<bool> UploadFileAsync(string filePath, CancellationToken cancellationToken = default)
{
try
{
cancellationToken.ThrowIfCancellationRequested();
// 检查文件是否存在
if (!File.Exists(filePath))
{
return false;
}
// 获取WebDav设置
var webDavUrl = MainWindow.Settings?.Dlass?.WebDavUrl;
var username = MainWindow.Settings?.Dlass?.WebDavUsername;
var password = MainWindow.Settings?.Dlass?.WebDavPassword;
var rootDirectory = MainWindow.Settings?.Dlass?.WebDavRootDirectory;
// 验证设置
if (string.IsNullOrEmpty(webDavUrl))
{
return false;
}
// 构建完整的目标路径
var fileName = Path.GetFileName(filePath);
var targetPath = Path.Combine(rootDirectory ?? string.Empty, fileName).Replace("\\", "/");
if (targetPath.StartsWith("/"))
{
targetPath = targetPath.Substring(1);
}
// 创建WebDav客户端
var clientParams = new WebDavClientParams
{
BaseAddress = new Uri(webDavUrl),
Credentials = new NetworkCredential(username ?? string.Empty, password ?? string.Empty)
};
using (var client = new WebDavClient(clientParams))
{
cancellationToken.ThrowIfCancellationRequested();
// 先直接尝试上传文件
using (var fileStream = File.OpenRead(filePath))
{
// 检查取消令牌
cancellationToken.ThrowIfCancellationRequested();
var result = await client.PutFile(targetPath, fileStream);
if (result.IsSuccessful)
{
return true;
}
else
{
// 上传失败,尝试创建目录
var directoryPath = Path.GetDirectoryName(targetPath);
if (!string.IsNullOrEmpty(directoryPath))
{
await EnsureDirectoryExistsAsync(client, directoryPath, cancellationToken);
// 再次尝试上传文件
cancellationToken.ThrowIfCancellationRequested();
using (var retryStream = File.OpenRead(filePath))
{
var retryResult = await client.PutFile(targetPath, retryStream);
return retryResult.IsSuccessful;
}
}
else
{
// 没有目录路径,直接返回失败
return false;
}
}
}
}
}
catch (OperationCanceledException)
{
throw;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 确保WebDav目录存在
/// </summary>
/// <param name="client">WebDav客户端</param>
/// <param name="directoryPath">目录路径</param>
/// <param name="cancellationToken">取消令牌</param>
private static async Task EnsureDirectoryExistsAsync(IWebDavClient client, string directoryPath, CancellationToken cancellationToken)
{
try
{
// 分割路径并逐级创建目录
var pathParts = directoryPath.Split('/');
var currentPath = string.Empty;
foreach (var part in pathParts)
{
cancellationToken.ThrowIfCancellationRequested();
if (string.IsNullOrEmpty(part))
continue;
currentPath = Path.Combine(currentPath, part).Replace("\\", "/");
// 检查取消令牌
cancellationToken.ThrowIfCancellationRequested();
// 尝试创建目录
await client.Mkcol(currentPath);
}
}
catch (Exception)
{
// 静默处理目录创建错误
}
}
/// <summary>
/// 检查WebDAV是否已启用
/// </summary>
/// <returns>是否启用</returns>
public static bool IsWebDavEnabled()
{
// 检查WebDav设置是否有效
var webDavUrl = MainWindow.Settings?.Dlass?.WebDavUrl;
if (string.IsNullOrEmpty(webDavUrl))
{
return false;
}
// 尝试解析URL
try
{
new Uri(webDavUrl);
return true;
}
catch
{
return false;
}
}
}
}