diff --git a/.gitignore b/.gitignore
index a374b8f..1764b53 100644
--- a/.gitignore
+++ b/.gitignore
@@ -226,3 +226,5 @@ project.lock.json
music/
webmusic.linux.run
dotnetwarp_temp
+
+.bearer_token
diff --git a/Pages/Index.cshtml b/Pages/Index.cshtml
index 84f047c..be19b83 100644
--- a/Pages/Index.cshtml
+++ b/Pages/Index.cshtml
@@ -18,6 +18,11 @@ else {
[..]
Go back
+ @if (Model.LogConditionsMet) {
+
+ [--]
+ Log playback
+ }
[--]
Download playlist
@@ -25,26 +30,24 @@ else {
@foreach (var dir in Model.Dirs) {
- [--]
- @dir
+ [--]
+ @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]
- @if (System.IO.File.Exists(lrcpath)) {
- [LRC]
- }
- else if(Directory.GetFiles(@Model.Fullpath, "*.lrc").Length != 0) {
- [---]
- }
- @file
+ [DL]
+ @if (System.IO.File.Exists(lrcpath)) {
+ [LRC]
+ }
+ else if (Directory.GetFiles(@Model.Fullpath, "*.lrc").Length != 0) {
+ [---]
+ }
+ @file
}
}
diff --git a/Pages/Index.cshtml.cs b/Pages/Index.cshtml.cs
index 9c75841..5f46826 100644
--- a/Pages/Index.cshtml.cs
+++ b/Pages/Index.cshtml.cs
@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
+using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace webmusic.Pages {
@@ -15,6 +16,10 @@ namespace webmusic.Pages {
public string Fullpath = "";
public string Path = "";
public string PathOneup = "";
+ public bool LogConditionsMet;
+ public string LogArtist;
+ public string LogAlbum;
+ public string LogUrl;
public void OnGet() {
if (Request.QueryString.HasValue)
@@ -26,7 +31,7 @@ namespace webmusic.Pages {
}
if (Path.EndsWith(".m3u"))
- Path = Path.Substring(0, Path.Length - 4);
+ Path = Path[..^4];
if (Path.EndsWith(".lrc"))
return;
@@ -42,6 +47,15 @@ namespace webmusic.Pages {
Files.RemoveAll(p => p.EndsWith(".lrc"));
Files.RemoveAll(p => p.StartsWith("."));
Files.Sort(new NaturalSortComparer());
+ if (Log.StatisticsEnabled && Request.Headers["Remote-User"].Equals(Log.StatisticsUser) && Files.Any()) {
+ var pathparts = Displaypath.Split(System.IO.Path.DirectorySeparatorChar);
+ if (pathparts.Length > 2) {
+ LogAlbum = Encode(pathparts[Index.FromEnd(1)]);
+ LogArtist = Encode(pathparts[Index.FromEnd(2)]);
+ LogUrl = Request.GetEncodedUrl();
+ LogConditionsMet = true;
+ }
+ }
}
public static string Encode(string str) => str.Replace("\"", "%22").Replace("'", "%27").Replace("?", "%3F").Replace("&", "%26").Replace(" ", "%20");
@@ -104,4 +118,4 @@ namespace webmusic.Pages {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Pages/Log.cs b/Pages/Log.cs
new file mode 100644
index 0000000..e033488
--- /dev/null
+++ b/Pages/Log.cs
@@ -0,0 +1,54 @@
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.Json;
+using Microsoft.AspNetCore.Mvc;
+
+namespace webmusic.Pages;
+
+[ApiController]
+[Route("/log")]
+public class Log : Controller {
+ public const bool StatisticsEnabled = true;
+ public const string StatisticsUser = "zotan";
+
+ private const string StatisticsUrl = "https://dev.zotan.pw/np/log";
+ private const string StatisticsSource = "music.zotan.services";
+ private readonly string _statisticsToken = System.IO.File.Exists(".bearer_token") ? System.IO.File.ReadAllLines(".bearer_token")[0] : "";
+
+ [HttpGet]
+ public string Get(string artist, string album, string url) {
+ if (StatisticsEnabled && Request.Headers["Remote-User"].Equals(StatisticsUser)) {
+ var res = MakeRestRequest(new LogPlaybackRequest { Artist = artist, Title = album, Link = url, Source = StatisticsSource });
+ Response.StatusCode = (int)res;
+
+ return res switch {
+ HttpStatusCode.Created => $"Logged: {artist} - {album}",
+ HttpStatusCode.Accepted => $"Skipped: {artist} - {album}",
+ HttpStatusCode.Forbidden => "Invalid token.",
+ _ => $"Error {Response.StatusCode} \"{res}\" occured."
+ };
+ }
+
+ Response.StatusCode = 403;
+ return null;
+ }
+
+ private HttpStatusCode MakeRestRequest(LogPlaybackRequest rq) {
+ using var client = new HttpClient();
+ client.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse(_statisticsToken);
+
+ var json = JsonSerializer.Serialize(rq);
+ var data = new StringContent(json, Encoding.UTF8, "application/json");
+ var response = client.PostAsync(StatisticsUrl, data).Result;
+ return response.StatusCode;
+ }
+
+ private class LogPlaybackRequest {
+ public string Artist { get; set; }
+ public string Title { get; set; }
+ public string Source { get; set; }
+ public string Link { get; set; }
+ }
+}
diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json
index 8e41e42..48d73ba 100644
--- a/Properties/launchSettings.json
+++ b/Properties/launchSettings.json
@@ -1,20 +1,12 @@
{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:63053",
- "sslPort": 44395
- }
- },
"profiles": {
"webmusic": {
"commandName": "Project",
"launchBrowser": false,
- "applicationUrl": "http://localhost:5000",
+ "applicationUrl": "http://localhost:5004",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
-}
\ No newline at end of file
+}
diff --git a/README.md b/README.md
index c6f9125..2043909 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
## webmusic
-This project allows users to browse and play music in a minimal web interface.
\ No newline at end of file
+This project allows users to browse and play music in a minimal web interface.
+
+Contains experimental support for collecting listening statistics in conjunction with [zotan.pw-web](https://git.ztn.sh/zotan/zotan.pw-web).