using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Web; using Microsoft.AspNetCore.Mvc.RazorPages; namespace webmusic.Pages { public class IndexModel : PageModel { private const string Root = "music"; public List Dirs = new(); public string Displaypath = ""; public List Files = new(); public string Fullpath = ""; public string Path = ""; public string PathOneup = ""; public void OnGet() { if (Request.QueryString.HasValue) if (Request.QueryString.Value != null) Path = HttpUtility.UrlDecode(Request.QueryString.Value.TrimStart('?').Replace("+", "%2B")); if (Path.Contains("/..")) { Response.Redirect("/Error"); return; } if (Path.EndsWith(".m3u")) Path = Path.Substring(0, Path.Length - 4); if (Path.EndsWith(".lrc")) return; PathOneup = Regex.Match(Path, @".*(?=\/)").Value; Fullpath = Root + Path; Displaypath = string.IsNullOrWhiteSpace(Path) ? "/" : Path; Dirs = Directory.GetDirectories(Fullpath).Select(System.IO.Path.GetFileName).ToList(); Dirs.RemoveAll(p => p.StartsWith(".")); Dirs.Sort(); Files = Directory.GetFiles(Fullpath).Select(System.IO.Path.GetFileName).ToList(); Files.RemoveAll(p => p.EndsWith(".m3u")); Files.RemoveAll(p => p.EndsWith(".lrc")); Files.RemoveAll(p => p.StartsWith(".")); Files.Sort(new AlphanumComparatorFast()); } public static string Encode(string str) => str.Replace("\"", "%22") .Replace("'", "%27") .Replace("?", "%3F") .Replace("&", "%26") .Replace(" ", "%20"); private class AlphanumComparatorFast : IComparer { public int Compare(string x, string y) { var s1 = x; if (s1 == null) return 0; if (!(y is { } s2)) return 0; var len1 = s1.Length; var len2 = s2.Length; var marker1 = 0; var marker2 = 0; // Walk through two the strings with two markers. while (marker1 < len1 && marker2 < len2) { var ch1 = s1[marker1]; var ch2 = s2[marker2]; // Some buffers we can build up characters in for each chunk. var space1 = new char[len1]; var loc1 = 0; var space2 = new char[len2]; var loc2 = 0; // Walk through all following characters that are digits or // characters in BOTH strings starting at the appropriate marker. // Collect char arrays. do { space1[loc1++] = ch1; marker1++; if (marker1 < len1) ch1 = s1[marker1]; else break; } while (char.IsDigit(ch1) == char.IsDigit(space1[0])); do { space2[loc2++] = ch2; marker2++; if (marker2 < len2) ch2 = s2[marker2]; else break; } while (char.IsDigit(ch2) == char.IsDigit(space2[0])); // If we have collected numbers, compare them numerically. // Otherwise, if we have strings, compare them alphabetically. var str1 = new string(space1); var str2 = new string(space2); int result; if (char.IsDigit(space1[0]) && char.IsDigit(space2[0])) { var thisNumericChunk = int.Parse(str1); var thatNumericChunk = int.Parse(str2); result = thisNumericChunk.CompareTo(thatNumericChunk); } else { result = string.Compare(str1, str2, StringComparison.Ordinal); } if (result != 0) return result; } return len1 - len2; } } } }