Add experimental playback logging support

This commit is contained in:
Laura Hausmann 2022-11-20 16:47:08 +01:00
parent 269f050b1c
commit 33dbbae9a1
Signed by: zotan
GPG key ID: D044E84C5BE01605
6 changed files with 92 additions and 25 deletions

2
.gitignore vendored
View file

@ -226,3 +226,5 @@ project.lock.json
music/
webmusic.linux.run
dotnetwarp_temp
.bearer_token

View file

@ -18,6 +18,11 @@ else {
</h2>
<a class="action-muted">[..]</a>
<a href="?@IndexModel.Encode(Model.PathOneup)" id="back" class="entry-muted cfont"> Go back</a>
@if (Model.LogConditionsMet) {
<br/>
<a class="action-muted">[--]</a>
<a href="/log?artist=@Model.LogArtist&album=@Model.LogAlbum&url=@Model.LogUrl" target="_blank" class="entry-muted cfont"> Log playback</a>
}
<br/>
<a class="action-muted">[--]</a>
<a href="/playlist/@(Request.QueryString).m3u" class="entry-muted cfont"> Download playlist</a>
@ -25,26 +30,24 @@ else {
<br/>
@foreach (var dir in Model.Dirs) {
<li>
<a class="action" href="#">[--]</a>
<a class="dir" href="?@IndexModel.Encode(Model.Path + "/" + dir)"> @dir</a>
<a class="action" href="#">[--]</a>
<a class="dir" href="?@IndexModel.Encode(Model.Path + "/" + dir)"> @dir</a>
</li>
}
@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);
<li>
<a class="action" href="@Html.Raw(IndexModel.Encode(Model.Fullpath + "/" + file))" download>[DL]</a>
@if (System.IO.File.Exists(lrcpath)) {
<a class="action" href="?@Html.Raw(IndexModel.Encode(Model.Path + "/" + lrcfile))" target="_blank">[LRC]</a>
}
else if(Directory.GetFiles(@Model.Fullpath, "*.lrc").Length != 0) {
<a class="action">[---]</a>
}
<a class="file" href="@Html.Raw(IndexModel.Encode(Model.Fullpath + "/" + file))"> @file</a>
<a class="action" href="@Html.Raw(IndexModel.Encode(Model.Fullpath + "/" + file))" download>[DL]</a>
@if (System.IO.File.Exists(lrcpath)) {
<a class="action" href="?@Html.Raw(IndexModel.Encode(Model.Path + "/" + lrcfile))" target="_blank">[LRC]</a>
}
else if (Directory.GetFiles(@Model.Fullpath, "*.lrc").Length != 0) {
<a class="action">[---]</a>
}
<a class="file" href="@Html.Raw(IndexModel.Encode(Model.Fullpath + "/" + file))"> @file</a>
</li>
}
}

View file

@ -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 {
}
}
}
}
}

54
Pages/Log.cs Normal file
View file

@ -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; }
}
}

View file

@ -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"
}
}
}
}
}

View file

@ -1,2 +1,4 @@
## webmusic
This project allows users to browse and play music in a minimal web interface.
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).