From b9794110cdd8eee1abb2fb734c4144f07a6cfa6c Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Mon, 21 Dec 2020 20:42:29 +0100 Subject: [PATCH] lyrics support, code cleanup --- .gitlab-ci.yml | 21 ---- Pages/Error.cshtml | 23 ++-- Pages/Error.cshtml.cs | 25 ++-- Pages/Index.cshtml | 77 ++++++------- Pages/Index.cshtml.cs | 220 ++++++++++++++++-------------------- Pages/Shared/_Layout.cshtml | 58 +++++----- Pages/_ViewImports.cshtml | 2 +- Pages/_ViewStart.cshtml | 4 +- Pages/plain.cshtml | 20 ++-- Pages/playlist.cshtml | 18 ++- Program.cs | 30 ++--- Startup.cs | 87 ++++++-------- 12 files changed, 245 insertions(+), 340 deletions(-) delete mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 6c6ea66..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,21 +0,0 @@ -# http://docs.gitlab.com/ce/ci/docker/using_docker_build.html#using-the-gitlab-container-registry -# The docker tag is the first 6 letters of the Git commit id - -job_build_dotnet: - stage: build - image: archlinux/base:latest - variables: - GIT_SUBMODULE_STRATEGY: recursive - script: - - pacman-key --init - - pacman-key --recv-keys 3FABB87C7C9F7E5FF2B6CB7B11A7E7E4DB9351DE - - pacman-key --lsign-key 3FABB87C7C9F7E5FF2B6CB7B11A7E7E4DB9351DE - - bash -c "echo -e '"'[zotancc]\nServer = https://arch.prod.zotan.network/zotancc/os/$arch'"' >> /etc/pacman.conf" - - pacman -Syu --needed dotnet-sdk-bin --noconfirm - - curl -Lo warp-packer https://github.com/dgiagio/warp/releases/download/v0.3.0/linux-x64.warp-packer && chmod +x warp-packer - - dotnet publish -c Release -r linux-x64 - - ./warp-packer --arch linux-x64 --input_dir bin/Release/netcoreapp3.1/linux-x64/publish --exec webmusic --output webmusic.linux.run - - chmod +x webmusic.linux.run - artifacts: - paths: - - webmusic.linux.run diff --git a/Pages/Error.cshtml b/Pages/Error.cshtml index 6f92b95..ef1bc8e 100644 --- a/Pages/Error.cshtml +++ b/Pages/Error.cshtml @@ -1,26 +1,25 @@ @page @model ErrorModel @{ - ViewData["Title"] = "Error"; + ViewData["Title"] = "Error"; }

Error.

An error occurred while processing your request.

-@if (Model.ShowRequestId) -{ -

- Request ID: @Model.RequestId -

+@if (Model.ShowRequestId) { +

+ Request ID: @Model.RequestId +

}

Development Mode

- Swapping to the Development environment displays detailed information about the error that occurred. + Swapping to the Development environment displays detailed information about the error that occurred.

- The Development environment shouldn't be enabled for deployed applications. - It can result in displaying sensitive information from exceptions to end users. - For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development - and restarting the app. -

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

\ No newline at end of file diff --git a/Pages/Error.cshtml.cs b/Pages/Error.cshtml.cs index 912bdf1..513c26a 100644 --- a/Pages/Error.cshtml.cs +++ b/Pages/Error.cshtml.cs @@ -1,23 +1,16 @@ -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -namespace webmusic.Pages -{ - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - public class ErrorModel : PageModel - { - public string RequestId { get; set; } +namespace webmusic.Pages { + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public class ErrorModel : PageModel { + public string RequestId { get; set; } - public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - public void OnGet() - { - RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; - } - } + public void OnGet() { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; + } + } } \ No newline at end of file diff --git a/Pages/Index.cshtml b/Pages/Index.cshtml index 63ba6e5..edc5efb 100644 --- a/Pages/Index.cshtml +++ b/Pages/Index.cshtml @@ -1,47 +1,44 @@ @page -@using System.Web @model IndexModel @{ - ViewData["Title"] = $"webmusic on .NET {Environment.Version}"; - var path = HttpUtility.UrlDecode(Request.QueryString.Value.TrimStart('?')); - if (path.EndsWith(".m3u")) - { - Layout = null; - Response.ContentType = "text/plain"; - } + ViewData["Title"] = $"webmusic on .NET {Environment.Version}"; } -@if (Model.path.Contains("/..")) -{ - return; +@if (Model.Path.Contains("/..")) { + return; } -@if (path.EndsWith(".m3u")) -{ - @foreach (var file in Model.files) - { - @Html.Raw("https://" + Request.Host + "/" + Model.fullpath + "/" + file.Replace("?", "%3F") +"\n") - } +@if (Model.Path.EndsWith(".lrc")) { +

@Model.Path

+

@Html.Raw((await System.IO.File.ReadAllTextAsync("music" + Model.Path)).Replace("\n", "
"))

} -else -{ -

@Model.displaypath

- [..] - Go back
- [--] - Download playlist

- @foreach (var dir in Model.dirs) - { - [--] - @dir -
- } - @foreach (var file in Model.files) - { - var jspath = Model.Encode(Model.fullpath); - var jsfile = jspath + "/" + Model.Encode(file); - - - [DL] - @file -
- } +else { +

+ @Model.Displaypath +

+ [..] + Go back +
+ [--] + Download playlist +
+
+ @foreach (var dir in Model.Dirs) { + [--] + @dir +
+ } + @foreach (var file in Model.Files) { + var jspath = IndexModel.Encode(Model.Fullpath); + var jsfile = jspath + "/" + IndexModel.Encode(file); + var basename = System.IO.Path.GetFileNameWithoutExtension(file); + var lrcfile = basename + ".lrc"; + var lrcpath = System.IO.Path.Combine(Model.Fullpath, lrcfile); + + + [DL] + @file + @if (System.IO.File.Exists(lrcpath)) { + [LRC] + } +
+ } } \ No newline at end of file diff --git a/Pages/Index.cshtml.cs b/Pages/Index.cshtml.cs index 96ebae6..c4411aa 100644 --- a/Pages/Index.cshtml.cs +++ b/Pages/Index.cshtml.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -6,139 +6,117 @@ 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 = ""; -namespace webmusic.Pages -{ - public class IndexModel : PageModel - { - public static string root = "music"; - public string path = ""; - public string displaypath = ""; - public string path_oneup = ""; - public string fullpath = ""; - public List dirs = new List(); - public List files = new List(); - public void OnGet() - { - if (Request.QueryString.HasValue) - path = HttpUtility.UrlDecode(Request.QueryString.Value.Remove(0,1) - .Replace("+", "%2B")); - if (path.EndsWith(".m3u")) - path = path.Substring(0, path.Length - 4); - if (path.Contains("/..")) - { - Response.Redirect("/Error"); - return; - } - path_oneup = Regex.Match(path, @".*(?=\/)").Value; - fullpath = root + path; - displaypath = string.IsNullOrWhiteSpace(path) ? "/" : path; - dirs = Directory.GetDirectories(fullpath).Select(Path.GetFileName).ToList(); - dirs.RemoveAll(p => p.StartsWith(".")); - dirs.Sort(); - files = Directory.GetFiles(fullpath).Select(Path.GetFileName).ToList(); - files.RemoveAll(p => p.EndsWith(".m3u")); - files.RemoveAll(p => p.StartsWith(".")); - files.Sort(new AlphanumComparatorFast()); - } + 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; + } - public string Encode(string str) - { - return str.Replace("\"", "%22").Replace("'", "%27") - .Replace("?", "%3F").Replace("&", "%26") - .Replace(" ", "%20"); - } + if (Path.EndsWith(".lrc")) + return; - public class AlphanumComparatorFast : IComparer - { - public int Compare(string x, string y) - { - string s1 = x; - if (s1 == null) - { - return 0; - } + 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()); + } - if (!(y is string s2)) - { - return 0; - } + public static string Encode(string str) => str.Replace("\"", "%22") + .Replace("'", "%27") + .Replace("?", "%3F") + .Replace("&", "%26") + .Replace(" ", "%20"); - int len1 = s1.Length; - int len2 = s2.Length; - int marker1 = 0; - int marker2 = 0; + private class AlphanumComparatorFast : IComparer { + public int Compare(string x, string y) { + var s1 = x; + if (s1 == null) + return 0; - // Walk through two the strings with two markers. - while (marker1 < len1 && marker2 < len2) - { - char ch1 = s1[marker1]; - char ch2 = s2[marker2]; + if (!(y is { } s2)) + return 0; - // Some buffers we can build up characters in for each chunk. - char[] space1 = new char[len1]; - int loc1 = 0; - char[] space2 = new char[len2]; - int loc2 = 0; + var len1 = s1.Length; + var len2 = s2.Length; + var marker1 = 0; + var marker2 = 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++; + // Walk through two the strings with two markers. + while (marker1 < len1 && marker2 < len2) { + var ch1 = s1[marker1]; + var ch2 = s2[marker2]; - if (marker1 < len1) - { - ch1 = s1[marker1]; - } - else - { - break; - } - } while (char.IsDigit(ch1) == char.IsDigit(space1[0])); + // 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; - do - { - space2[loc2++] = ch2; - marker2++; + // 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 (marker2 < len2) - { - ch2 = s2[marker2]; - } - else - { - break; - } - } while (char.IsDigit(ch2) == char.IsDigit(space2[0])); + if (marker1 < len1) + ch1 = s1[marker1]; + else + break; + } while (char.IsDigit(ch1) == char.IsDigit(space1[0])); - // If we have collected numbers, compare them numerically. - // Otherwise, if we have strings, compare them alphabetically. - string str1 = new string(space1); - string str2 = new string(space2); + do { + space2[loc2++] = ch2; + marker2++; - int result; + if (marker2 < len2) + ch2 = s2[marker2]; + else + break; + } while (char.IsDigit(ch2) == char.IsDigit(space2[0])); - if (char.IsDigit(space1[0]) && char.IsDigit(space2[0])) - { - int thisNumericChunk = int.Parse(str1); - int thatNumericChunk = int.Parse(str2); - result = thisNumericChunk.CompareTo(thatNumericChunk); - } - else - { - result = str1.CompareTo(str2); - } + // 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); - if (result != 0) - { - return result; - } - } - return len1 - len2; - } - } - } + 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; + } + } + } } \ No newline at end of file diff --git a/Pages/Shared/_Layout.cshtml b/Pages/Shared/_Layout.cshtml index 669c73e..46eadea 100644 --- a/Pages/Shared/_Layout.cshtml +++ b/Pages/Shared/_Layout.cshtml @@ -1,37 +1,37 @@  - - - - - @ViewData["Title"] - - - - - - - - - - - - - - - - - - - - - - + + + + + @ViewData["Title"] + + + + + + + + + + + + + + + + + + + + + +
-@RenderBody() + @RenderBody()
- + \ No newline at end of file diff --git a/Pages/_ViewImports.cshtml b/Pages/_ViewImports.cshtml index 3ddae19..9796540 100644 --- a/Pages/_ViewImports.cshtml +++ b/Pages/_ViewImports.cshtml @@ -1,3 +1,3 @@ @using webmusic @namespace webmusic.Pages -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers \ No newline at end of file diff --git a/Pages/_ViewStart.cshtml b/Pages/_ViewStart.cshtml index a5f1004..817a913 100644 --- a/Pages/_ViewStart.cshtml +++ b/Pages/_ViewStart.cshtml @@ -1,3 +1,3 @@ @{ - Layout = "_Layout"; -} + Layout = "_Layout"; +} \ No newline at end of file diff --git a/Pages/plain.cshtml b/Pages/plain.cshtml index 0e75614..5d6b3e9 100644 --- a/Pages/plain.cshtml +++ b/Pages/plain.cshtml @@ -1,19 +1,15 @@ @page -@using System.Web @model IndexModel @{ - Layout = null; - Response.ContentType = "text/plain"; + Layout = null; + Response.ContentType = "text/plain"; } -@if (Model.path.Contains("..")) -{ - return; +@if (Model.Path.Contains("..")) { + return; } -@foreach (var dir in Model.dirs) -{ -@Html.Raw(dir+"\n") +@foreach (var dir in Model.Dirs) { + @Html.Raw(dir + "\n") } -@foreach (var file in Model.files) -{ -@Html.Raw(file+"\n") +@foreach (var file in Model.Files) { + @Html.Raw(file + "\n") } \ No newline at end of file diff --git a/Pages/playlist.cshtml b/Pages/playlist.cshtml index a27eac8..49932f3 100644 --- a/Pages/playlist.cshtml +++ b/Pages/playlist.cshtml @@ -2,15 +2,13 @@ @using System.Web @model IndexModel @{ - var path = HttpUtility.UrlDecode(Request.QueryString.Value.TrimStart('?')); - Layout = null; - Response.ContentType = "text/plain"; + var path = HttpUtility.UrlDecode(Request.QueryString.Value.TrimStart('?')); + Layout = null; + Response.ContentType = "text/plain"; } -@if (Model.path.Contains("..")) -{ - return; -} -@foreach (var file in Model.files) -{ - @Html.Raw("https://" + Request.Host + "/" + Model.fullpath + "/" + file.Replace("?", "%3F") +"\n") +@if (Model.Path.Contains("..")) { + return; } +@foreach (var file in Model.Files) { + @Html.Raw("https://" + Request.Host + "/" + Model.Fullpath + "/" + file.Replace("?", "%3F") + "\n") +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index b0eb753..ef62d15 100644 --- a/Program.cs +++ b/Program.cs @@ -1,25 +1,13 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; +using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -namespace webmusic -{ - public class Program - { - public static void Main(string[] args) - { - CreateWebHostBuilder(args).Build().Run(); - } +namespace webmusic { + public class Program { + public static void Main(string[] args) { + CreateWebHostBuilder(args).Build().Run(); + } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseWebRoot(".") - .UseStartup(); - } + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args).UseWebRoot(".").UseStartup(); + } } \ No newline at end of file diff --git a/Startup.cs b/Startup.cs index 39af297..41e0114 100644 --- a/Startup.cs +++ b/Startup.cs @@ -1,68 +1,45 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.StaticFiles; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; -namespace webmusic -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } +namespace webmusic { + public class Startup { + // This method gets called by the runtime. Use this method to add services to the container. + public static void ConfigureServices(IServiceCollection services) { + services.Configure(options => { + // This lambda determines whether user consent for non-essential cookies is needed for a given request. + options.CheckConsentNeeded = context => true; + options.MinimumSameSitePolicy = SameSiteMode.None; + }); - public IConfiguration Configuration { get; } + services.Configure(options => { options.EnableEndpointRouting = false; }); - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.Configure(options => - { - // This lambda determines whether user consent for non-essential cookies is needed for a given request. - options.CheckConsentNeeded = context => true; - options.MinimumSameSitePolicy = SameSiteMode.None; - }); + services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest); + } + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public static void Configure(IApplicationBuilder app, IWebHostEnvironment env) { + var provider = new FileExtensionContentTypeProvider(); + provider.Mappings[".flac"] = "audio/flac"; + provider.Mappings[".m3u"] = "audio/m3u"; + provider.Mappings[".opus"] = "audio/opus"; + if (env.IsDevelopment()) { + app.UseDeveloperExceptionPage(); + } + else { + app.UseExceptionHandler("/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } - services.Configure(options => { options.EnableEndpointRouting = false; }); + app.UseStaticFiles(new StaticFileOptions {ContentTypeProvider = provider}); + app.UseCookiePolicy(); - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - var provider = new FileExtensionContentTypeProvider(); - provider.Mappings[".flac"] = "audio/flac"; - provider.Mappings[".m3u"] = "audio/m3u"; - provider.Mappings[".opus"] = "audio/opus"; - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseStaticFiles(new StaticFileOptions() - { - ContentTypeProvider = provider - }); - app.UseCookiePolicy(); - - app.UseMvc(); - } - } + app.UseMvc(); + } + } } \ No newline at end of file