mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
feat: playlist implementation
This commit is contained in:
@@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using System.Xml.Linq;
|
||||
using System.Text.Json;
|
||||
using octo_fiesta.Models.Domain;
|
||||
using octo_fiesta.Models.Subsonic;
|
||||
|
||||
namespace octo_fiesta.Services.Subsonic;
|
||||
|
||||
@@ -137,6 +138,81 @@ public class SubsonicResponseBuilder
|
||||
);
|
||||
return new ContentResult { Content = doc.ToString(), ContentType = "application/xml" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Subsonic response for a playlist represented as an album.
|
||||
/// Playlists appear as albums with genre "Playlist".
|
||||
/// </summary>
|
||||
public IActionResult CreatePlaylistAsAlbumResponse(string format, ExternalPlaylist playlist, List<Song> tracks)
|
||||
{
|
||||
var totalDuration = tracks.Sum(s => s.Duration ?? 0);
|
||||
|
||||
// Build artist name with emoji and curator
|
||||
var artistName = $"🎵 {char.ToUpper(playlist.Provider[0])}{playlist.Provider.Substring(1)}";
|
||||
if (!string.IsNullOrEmpty(playlist.CuratorName))
|
||||
{
|
||||
artistName += $" {playlist.CuratorName}";
|
||||
}
|
||||
|
||||
var artistId = $"curator-{playlist.Provider}-{playlist.CuratorName?.ToLowerInvariant().Replace(" ", "-") ?? "unknown"}";
|
||||
|
||||
if (format == "json")
|
||||
{
|
||||
return CreateJsonResponse(new
|
||||
{
|
||||
status = "ok",
|
||||
version = SubsonicVersion,
|
||||
album = new
|
||||
{
|
||||
id = playlist.Id,
|
||||
name = playlist.Name,
|
||||
artist = artistName,
|
||||
artistId = artistId,
|
||||
coverArt = playlist.Id,
|
||||
songCount = tracks.Count,
|
||||
duration = totalDuration,
|
||||
year = playlist.CreatedDate?.Year ?? 0,
|
||||
genre = "Playlist",
|
||||
isCompilation = false,
|
||||
created = playlist.CreatedDate?.ToString("yyyy-MM-ddTHH:mm:ss"),
|
||||
song = tracks.Select(s => ConvertSongToJson(s)).ToList()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var ns = XNamespace.Get(SubsonicNamespace);
|
||||
var albumElement = new XElement(ns + "album",
|
||||
new XAttribute("id", playlist.Id),
|
||||
new XAttribute("name", playlist.Name),
|
||||
new XAttribute("artist", artistName),
|
||||
new XAttribute("artistId", artistId),
|
||||
new XAttribute("songCount", tracks.Count),
|
||||
new XAttribute("duration", totalDuration),
|
||||
new XAttribute("genre", "Playlist"),
|
||||
new XAttribute("coverArt", playlist.Id)
|
||||
);
|
||||
|
||||
if (playlist.CreatedDate.HasValue)
|
||||
{
|
||||
albumElement.Add(new XAttribute("year", playlist.CreatedDate.Value.Year));
|
||||
albumElement.Add(new XAttribute("created", playlist.CreatedDate.Value.ToString("yyyy-MM-ddTHH:mm:ss")));
|
||||
}
|
||||
|
||||
// Add songs
|
||||
foreach (var song in tracks)
|
||||
{
|
||||
albumElement.Add(ConvertSongToXml(song, ns));
|
||||
}
|
||||
|
||||
var doc = new XDocument(
|
||||
new XElement(ns + "subsonic-response",
|
||||
new XAttribute("status", "ok"),
|
||||
new XAttribute("version", SubsonicVersion),
|
||||
albumElement
|
||||
)
|
||||
);
|
||||
return new ContentResult { Content = doc.ToString(), ContentType = "application/xml" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Subsonic response containing an artist with albums.
|
||||
|
||||
Reference in New Issue
Block a user