[feat] Sort query results

This commit is contained in:
acite
2025-08-27 15:16:50 +08:00
parent 69509e4b87
commit 64aa7a2fdd
4 changed files with 191 additions and 30 deletions

View File

@@ -24,7 +24,7 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
[HttpGet]
public async Task<IActionResult> GetClass(string token)
{
var r = await rs.Query(VideoFolder, token, Ip);
var r = (await rs.Query(VideoFolder, token, Ip))?.SortLikeWindows();
if(r == null)
return StatusCode(401, new { message = "Unauthorized" });
@@ -38,6 +38,7 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
var d = Helpers.SafePathCombine(VideoFolder, klass);
if (d == null) return StatusCode(403, new { message = "403 Denied" });
var r = await rs.Query(d, token, Ip);
if (r == null) return StatusCode(401, new { message = "Unauthorized" });
return Ok(r);
@@ -64,6 +65,8 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
var r = await rs.Get(d, token, Ip);
if (!r) return StatusCode(403, new { message = "403 Denied" });
_logger.LogInformation($"Cover found for {id}");
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
}

View File

@@ -117,7 +117,7 @@ public class UserService
Destroy(token);
return null;
}
_logger.LogInformation($"Validated {userAndIp}");
// _logger.LogInformation($"Validated {userAndIp}");
return userAndIp?.Split('@')[0];
}
_logger.LogWarning($"Validation failed {token}");

View File

@@ -1,4 +1,7 @@
using System.Globalization;
using System.Text.RegularExpressions;
namespace Abyss.Components.Static;
public static class Helpers
@@ -57,4 +60,121 @@ public enum PathType
Directory,
NotFound,
AccessDenied
}
public static class StringArrayExtensions
{
public static string[] SortLikeWindows(this string[] array)
{
if (array == null) return null;
if (array.Length == 0) return array;
Array.Sort(array, new WindowsFileNameComparer());
return array;
}
public static string[] SortLikeWindowsDescending(this string[] array)
{
if (array == null) return null;
if (array.Length == 0) return array;
Array.Sort(array, new WindowsFileNameComparerDescending());
return array;
}
public static void SortLikeWindowsInPlace(this string[] array)
{
if (array == null || array.Length == 0) return;
Array.Sort(array, new WindowsFileNameComparer());
}
public static void SortLikeWindowsDescendingInPlace(this string[] array)
{
if (array == null || array.Length == 0) return;
Array.Sort(array, new WindowsFileNameComparerDescending());
}
}
public class WindowsFileNameComparer : IComparer<string>
{
private static readonly Regex _regex = new Regex(@"(\d+|\D+)", RegexOptions.Compiled);
private static readonly CompareInfo _compareInfo = CultureInfo.InvariantCulture.CompareInfo;
public int Compare(string? x, string? y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
if (ReferenceEquals(x, y)) return 0;
var partsX = _regex.Matches(x);
var partsY = _regex.Matches(y);
int minLength = Math.Min(partsX.Count, partsY.Count);
for (int i = 0; i < minLength; i++)
{
string partX = partsX[i].Value;
string partY = partsY[i].Value;
if (long.TryParse(partX, out long numX) && long.TryParse(partY, out long numY))
{
int comparison = numX.CompareTo(numY);
if (comparison != 0) return comparison;
}
else
{
int comparison;
if (ContainsChinese(partX) || ContainsChinese(partY))
{
comparison = _compareInfo.Compare(partX, partY, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace);
}
else
{
comparison = string.Compare(partX, partY, StringComparison.OrdinalIgnoreCase);
}
if (comparison != 0) return comparison;
}
}
return partsX.Count.CompareTo(partsY.Count);
}
private static bool ContainsChinese(string text)
{
if (string.IsNullOrEmpty(text)) return false;
foreach (char c in text)
{
if (c >= 0x4E00 && c <= 0x9FFF)
return true;
if (c >= 0x3400 && c <= 0x4DBF)
return true;
}
return false;
}
}
public class WindowsFileNameComparerDescending : IComparer<string>
{
private static readonly WindowsFileNameComparer _ascendingComparer = new WindowsFileNameComparer();
public int Compare(string x, string y)
{
return _ascendingComparer.Compare(y, x);
}
}
public static class StringNaturalCompare
{
private static readonly WindowsFileNameComparer _comparer = new WindowsFileNameComparer();
public static int Compare(string x, string y)
{
return _comparer.Compare(x, y);
}
}