mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-12 19:24:55 +08:00
fix
This commit is contained in:
@@ -15,7 +15,7 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
private SMB2Client? _client;
|
||||
private ISMBFileStore? _fileStore;
|
||||
|
||||
// 保存配置对象的引用,它是我们的“真理来源”
|
||||
// 保存配置对象的引用
|
||||
private readonly MediaFolder _config;
|
||||
|
||||
// 缓存解析出来的 Share 名称,因为 TreeConnect 要用
|
||||
@@ -26,8 +26,6 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
|
||||
// 在构造时就解析好 Share 名称,避免后续重复解析
|
||||
// 假设 URI 是 smb://host/ShareName/Folder/Sub
|
||||
// 我们需要提取 "ShareName"
|
||||
var uri = _config.GetStandardUri();
|
||||
|
||||
// Segments[0] 是 "/", Segments[1] 是 "ShareName/"
|
||||
@@ -48,16 +46,16 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
{
|
||||
_client = new SMB2Client();
|
||||
|
||||
// 1. 连接主机
|
||||
// 连接主机
|
||||
bool connected = _client.Connect(_config.UriHost, SMBTransportType.DirectTCPTransport);
|
||||
if (!connected) return false;
|
||||
|
||||
// 2. 登录
|
||||
// 登录
|
||||
var status = _client.Login(string.Empty, _config.UserName, _config.Password);
|
||||
if (status != NTStatus.STATUS_SUCCESS) return false;
|
||||
|
||||
// 3. 连接共享目录 (TreeConnect)
|
||||
// 注意:SMBLibrary 必须先连接到 Share,后续所有文件操作都是基于这个 Share 的相对路径
|
||||
// 连接共享目录 (TreeConnect)
|
||||
// SMBLibrary 必须先连接到 Share,后续所有文件操作都是基于这个 Share 的相对路径
|
||||
if (string.IsNullOrEmpty(_shareName)) return false;
|
||||
|
||||
_fileStore = _client.TreeConnect(_shareName, out status);
|
||||
@@ -161,7 +159,6 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
{
|
||||
if (_fileStore == null || file == null) return null;
|
||||
|
||||
// ★ 核心简化:直接把对象扔进去,获取路径
|
||||
string smbPath = GetPathRelativeToShare(file);
|
||||
|
||||
var ret = _fileStore.CreateFile(out object handle, out FileStatus status, smbPath,
|
||||
@@ -184,9 +181,6 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
_client?.Disconnect();
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// ★ 私有魔法方法:处理所有令人头大的路径逻辑
|
||||
// =========================================================
|
||||
private string GetPathRelativeToShare(FileCacheEntity? entity)
|
||||
{
|
||||
Uri targetUri;
|
||||
@@ -200,29 +194,17 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
targetUri = new Uri(entity.Uri);
|
||||
}
|
||||
|
||||
// 1. 获取绝对路径
|
||||
// ★★★ 关键修正:必须解码!把 %20 变回空格 ★★★
|
||||
// targetUri.AbsolutePath -> "/Share/My%20Music/Song.mp3"
|
||||
// Uri.UnescapeDataString -> "/Share/My Music/Song.mp3"
|
||||
string absolutePath = Uri.UnescapeDataString(targetUri.AbsolutePath);
|
||||
|
||||
// 2. 移除 ShareName 部分
|
||||
// 确保移除开头的 /
|
||||
string cleanPath = absolutePath.TrimStart('/');
|
||||
|
||||
// 找到 ShareName 后的第一个斜杠
|
||||
int slashIndex = cleanPath.IndexOf('/');
|
||||
|
||||
if (slashIndex == -1)
|
||||
{
|
||||
// 如果没有斜杠,说明就是 Share 根目录
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// 截取 Share 之后的部分
|
||||
string relativePath = cleanPath.Substring(slashIndex + 1);
|
||||
|
||||
// 3. 转换为 Windows 风格的反斜杠 (SMB 协议要求)
|
||||
return relativePath.Replace("/", "\\");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -18,9 +19,9 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
{
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
|
||||
// 1. 构建 BaseAddress (只包含 http://host:port/)
|
||||
// 构建 BaseAddress (只包含 http://host:port/)
|
||||
// MediaFolder.GetStandardUri() 返回的是带路径的完整 URI (http://host:port/path)
|
||||
// 我们需要提取出根用于初始化 WebDavClient
|
||||
// 提取出根用于初始化 WebDavClient
|
||||
var fullUri = _config.GetStandardUri();
|
||||
|
||||
// 提取 "http://host:port"
|
||||
@@ -52,7 +53,6 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
{
|
||||
var list = new List<FileCacheEntity>();
|
||||
|
||||
// 1. 确定目标 URI
|
||||
Uri targetUri;
|
||||
if (parentFolder == null)
|
||||
{
|
||||
@@ -63,60 +63,54 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService.Providers
|
||||
targetUri = new Uri(parentFolder.Uri);
|
||||
}
|
||||
|
||||
// 2. 发送请求 (使用绝对 URI)
|
||||
// WebDavClient 允许传入绝对路径,它会自动处理
|
||||
var result = await _client.Propfind(targetUri.AbsoluteUri);
|
||||
|
||||
if (result.IsSuccessful)
|
||||
{
|
||||
// 3. 准备父级 URI 字符串 (用于填充 Entity)
|
||||
// 确保以 / 结尾,方便后续逻辑判断或数据库查询
|
||||
string parentUriString = targetUri.AbsoluteUri;
|
||||
if (!parentUriString.EndsWith("/")) parentUriString += "/";
|
||||
|
||||
// WebDAV 可能会把文件夹自己作为结果返回,我们需要过滤它
|
||||
// 比较时忽略末尾斜杠
|
||||
string targetPathClean = targetUri.AbsolutePath.TrimEnd('/');
|
||||
|
||||
foreach (var res in result.Resources)
|
||||
{
|
||||
// res.Uri 通常是相对路径,例如 "/dav/music/file.mp3"
|
||||
// 我们需要将其转换为绝对 URI
|
||||
var itemUri = new Uri(_baseAddress, res.Uri);
|
||||
|
||||
// ★ 过滤掉文件夹自身
|
||||
// 比较 AbsolutePath (例如 /dav/music vs /dav/music)
|
||||
// 过滤掉文件夹自身
|
||||
if (itemUri.AbsolutePath.TrimEnd('/') == targetPathClean) continue;
|
||||
|
||||
// 获取文件名 (解码)
|
||||
// res.DisplayName 有时候是空的,这时候需要从 Uri 解析
|
||||
string name = res.DisplayName;
|
||||
string? name = res.DisplayName;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
// 取最后一段,忽略末尾斜杠
|
||||
name = itemUri.AbsolutePath.TrimEnd('/').Split('/').Last();
|
||||
name = System.Net.WebUtility.UrlDecode(name);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(name)) continue;
|
||||
|
||||
if (name.StartsWith(".")) continue;
|
||||
|
||||
bool isDir = res.IsCollection;
|
||||
if (!isDir)
|
||||
{
|
||||
string extension = System.IO.Path.GetExtension(name);
|
||||
// 如果后缀为空或不在白名单,跳过
|
||||
if (string.IsNullOrEmpty(extension) || !FileHelper.AllSupportedExtensions.Contains(extension)) continue;
|
||||
}
|
||||
|
||||
list.Add(new FileCacheEntity
|
||||
{
|
||||
MediaFolderId = _config.Id,
|
||||
|
||||
// 记录父级 URI (保持传入时的形式,或者统一标准)
|
||||
// 注意:对于 WebDAV,ParentUri 最好不带末尾斜杠,除非是根
|
||||
ParentUri = parentFolder?.Uri ?? _config.GetStandardUri().AbsoluteUri,
|
||||
|
||||
// ★ 存储完整的 http://... 标准 URI
|
||||
Uri = itemUri.AbsoluteUri,
|
||||
|
||||
FileName = name,
|
||||
IsDirectory = res.IsCollection,
|
||||
|
||||
// WebDAV 通常能提供这些信息
|
||||
FileSize = res.ContentLength ?? 0,
|
||||
LastModified = res.LastModifiedDate
|
||||
LastModified = res.LastModifiedDate ?? DateTime.MinValue,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user