feat(netd): improve album search
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
d563c80bd0
commit
61dc9826b9
12 changed files with 137 additions and 36 deletions
|
@ -6,6 +6,8 @@ using NetDaemon.AppModel;
|
||||||
using NetDaemon.HassModel;
|
using NetDaemon.HassModel;
|
||||||
using NetDaemon.HassModel.Integration;
|
using NetDaemon.HassModel.Integration;
|
||||||
|
|
||||||
|
using NetDaemonConfig.Apps.Spotify.Types;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PauseUnpause
|
namespace NetDaemonConfig.Apps.Spotify.PauseUnpause
|
||||||
{
|
{
|
||||||
|
@ -25,14 +27,14 @@ namespace NetDaemonConfig.Apps.Spotify.PauseUnpause
|
||||||
if (e.pause)
|
if (e.pause)
|
||||||
{
|
{
|
||||||
services.Spotifyplus.PlayerMediaPause(
|
services.Spotifyplus.PlayerMediaPause(
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
deviceId: SpotifyTypes.DefaultDevId);
|
deviceId: Globals.DefaultDevId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
services.Spotifyplus.PlayerMediaResume(
|
services.Spotifyplus.PlayerMediaResume(
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
deviceId: SpotifyTypes.DefaultDevId);
|
deviceId: Globals.DefaultDevId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception error)
|
catch (Exception error)
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
|
using FuzzySharp;
|
||||||
|
using FuzzySharp.Extractor;
|
||||||
|
|
||||||
using HomeAssistantGenerated;
|
using HomeAssistantGenerated;
|
||||||
|
|
||||||
using NetDaemon.AppModel;
|
using NetDaemon.AppModel;
|
||||||
using NetDaemon.HassModel;
|
using NetDaemon.HassModel;
|
||||||
using NetDaemon.HassModel.Integration;
|
using NetDaemon.HassModel.Integration;
|
||||||
|
|
||||||
|
using NetDaemonConfig.Apps.Spotify.Types;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlayAlbum
|
namespace NetDaemonConfig.Apps.Spotify.PlayAlbum
|
||||||
{
|
{
|
||||||
|
@ -16,6 +23,8 @@ namespace NetDaemonConfig.Apps.Spotify.PlayAlbum
|
||||||
[NetDaemonApp]
|
[NetDaemonApp]
|
||||||
public class PlayAlbum
|
public class PlayAlbum
|
||||||
{
|
{
|
||||||
|
private readonly CultureInfo _cultureInfo = new("fr-CA", false);
|
||||||
|
|
||||||
// Snake-case json options
|
// Snake-case json options
|
||||||
private readonly JsonSerializerOptions _jsonOptions = new()
|
private readonly JsonSerializerOptions _jsonOptions = new()
|
||||||
{
|
{
|
||||||
|
@ -30,26 +39,69 @@ namespace NetDaemonConfig.Apps.Spotify.PlayAlbum
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SpotifyplusSearchAlbumsResponse? result = (
|
string uri;
|
||||||
await services.Spotifyplus.SearchAlbumsAsync(
|
|
||||||
criteria: $"{e?.artist} {e?.album}",
|
|
||||||
limitTotal: 1,
|
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
|
||||||
// My Defaults
|
|
||||||
market: "CA",
|
|
||||||
includeExternal: "audio"
|
|
||||||
)
|
|
||||||
).Value.Deserialize<SpotifyplusSearchAlbumsResponse>(_jsonOptions);
|
|
||||||
|
|
||||||
string uri = result?.Result?.Items?[0]?.Uri ??
|
if (e.artist is not null)
|
||||||
throw new TargetException(
|
{
|
||||||
$"The album {e?.album}{(e?.artist is null ? "" : $" by {e?.artist}")} could not be found."
|
SpotifyplusSearchArtistsResponse? artistResult = (
|
||||||
|
await services.Spotifyplus.SearchArtistsAsync(
|
||||||
|
criteria: e?.artist ??
|
||||||
|
throw new TargetException($"The artist {e?.artist} could not be found."),
|
||||||
|
limitTotal: 1,
|
||||||
|
entityId: Globals.DefaultEntityId,
|
||||||
|
// My Defaults
|
||||||
|
market: "CA",
|
||||||
|
includeExternal: "audio"
|
||||||
|
)
|
||||||
|
).Value.Deserialize<SpotifyplusSearchArtistsResponse>(_jsonOptions);
|
||||||
|
|
||||||
|
string artistId = artistResult?.Result?.Items?[0]?.Id ??
|
||||||
|
throw new TargetException($"The artist {e?.artist} could not be found.");
|
||||||
|
|
||||||
|
SpotifyPlusGetArtistAlbumsResponse? result = (
|
||||||
|
await services.Spotifyplus.GetArtistAlbumsAsync(
|
||||||
|
artistId: artistId,
|
||||||
|
entityId: Globals.DefaultEntityId,
|
||||||
|
market: "CA"
|
||||||
|
)
|
||||||
|
).Value.Deserialize<SpotifyPlusGetArtistAlbumsResponse>(_jsonOptions);
|
||||||
|
|
||||||
|
List<ArtistAlbumItem> albums = result?.Result?.Items ??
|
||||||
|
throw new TargetException($"No albums found for artist {e.artist}");
|
||||||
|
|
||||||
|
ExtractedResult<ArtistAlbumItem> match = Process.ExtractOne(
|
||||||
|
new ArtistAlbumItem { Name = e.album?.ToLower(_cultureInfo) },
|
||||||
|
albums,
|
||||||
|
new Func<ArtistAlbumItem, string>((item) =>
|
||||||
|
(item.Name ?? "").ToLower(_cultureInfo))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
uri = match.Value?.Uri ??
|
||||||
|
throw new TargetException($"No matches found for album {e.album}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpotifyplusSearchAlbumsResponse? result = (
|
||||||
|
await services.Spotifyplus.SearchAlbumsAsync(
|
||||||
|
criteria: $"{e?.album}",
|
||||||
|
limitTotal: 1,
|
||||||
|
entityId: Globals.DefaultEntityId,
|
||||||
|
// My Defaults
|
||||||
|
market: "CA",
|
||||||
|
includeExternal: "audio"
|
||||||
|
)
|
||||||
|
).Value.Deserialize<SpotifyplusSearchAlbumsResponse>(_jsonOptions);
|
||||||
|
|
||||||
|
uri = result?.Result?.Items?[0]?.Uri ??
|
||||||
|
throw new TargetException(
|
||||||
|
$"The album {e?.album}{(e?.artist is null ? "" : $" by {e?.artist}")} could not be found."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
services.Spotifyplus.PlayerMediaPlayContext(
|
services.Spotifyplus.PlayerMediaPlayContext(
|
||||||
contextUri: uri,
|
contextUri: uri,
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
deviceId: SpotifyTypes.DefaultDevId,
|
deviceId: Globals.DefaultDevId,
|
||||||
// My Defaults
|
// My Defaults
|
||||||
positionMs: 0,
|
positionMs: 0,
|
||||||
delay: 0.50
|
delay: 0.50
|
||||||
|
|
|
@ -8,6 +8,8 @@ using NetDaemon.AppModel;
|
||||||
using NetDaemon.HassModel;
|
using NetDaemon.HassModel;
|
||||||
using NetDaemon.HassModel.Integration;
|
using NetDaemon.HassModel.Integration;
|
||||||
|
|
||||||
|
using NetDaemonConfig.Apps.Spotify.Types;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlayArtist
|
namespace NetDaemonConfig.Apps.Spotify.PlayArtist
|
||||||
{
|
{
|
||||||
|
@ -34,7 +36,7 @@ namespace NetDaemonConfig.Apps.Spotify.PlayArtist
|
||||||
await services.Spotifyplus.SearchArtistsAsync(
|
await services.Spotifyplus.SearchArtistsAsync(
|
||||||
criteria: e?.artist ?? throw new TargetException($"The artist {e?.artist} could not be found."),
|
criteria: e?.artist ?? throw new TargetException($"The artist {e?.artist} could not be found."),
|
||||||
limitTotal: 1,
|
limitTotal: 1,
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
// My Defaults
|
// My Defaults
|
||||||
market: "CA",
|
market: "CA",
|
||||||
includeExternal: "audio"
|
includeExternal: "audio"
|
||||||
|
@ -46,8 +48,8 @@ namespace NetDaemonConfig.Apps.Spotify.PlayArtist
|
||||||
|
|
||||||
services.Spotifyplus.PlayerMediaPlayContext(
|
services.Spotifyplus.PlayerMediaPlayContext(
|
||||||
contextUri: uri,
|
contextUri: uri,
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
deviceId: SpotifyTypes.DefaultDevId,
|
deviceId: Globals.DefaultDevId,
|
||||||
// My Defaults
|
// My Defaults
|
||||||
positionMs: 0,
|
positionMs: 0,
|
||||||
delay: 0.50
|
delay: 0.50
|
||||||
|
|
|
@ -13,6 +13,8 @@ using NetDaemon.AppModel;
|
||||||
using NetDaemon.HassModel;
|
using NetDaemon.HassModel;
|
||||||
using NetDaemon.HassModel.Integration;
|
using NetDaemon.HassModel.Integration;
|
||||||
|
|
||||||
|
using NetDaemonConfig.Apps.Spotify.Types;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlayPlaylist
|
namespace NetDaemonConfig.Apps.Spotify.PlayPlaylist
|
||||||
{
|
{
|
||||||
|
@ -43,7 +45,7 @@ namespace NetDaemonConfig.Apps.Spotify.PlayPlaylist
|
||||||
await services.Spotifyplus.GetPlaylistFavoritesAsync(
|
await services.Spotifyplus.GetPlaylistFavoritesAsync(
|
||||||
limitTotal: 200,
|
limitTotal: 200,
|
||||||
sortResult: true,
|
sortResult: true,
|
||||||
entityId: SpotifyTypes.DefaultEntityId
|
entityId: Globals.DefaultEntityId
|
||||||
)
|
)
|
||||||
).Value.Deserialize<SpotifyplusPlaylistResponse>(_jsonOptions);
|
).Value.Deserialize<SpotifyplusPlaylistResponse>(_jsonOptions);
|
||||||
|
|
||||||
|
@ -65,7 +67,7 @@ namespace NetDaemonConfig.Apps.Spotify.PlayPlaylist
|
||||||
await services.Spotifyplus.SearchPlaylistsAsync(
|
await services.Spotifyplus.SearchPlaylistsAsync(
|
||||||
criteria: query,
|
criteria: query,
|
||||||
limitTotal: 1,
|
limitTotal: 1,
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
// My Defaults
|
// My Defaults
|
||||||
market: "CA",
|
market: "CA",
|
||||||
includeExternal: "audio"
|
includeExternal: "audio"
|
||||||
|
@ -80,8 +82,8 @@ namespace NetDaemonConfig.Apps.Spotify.PlayPlaylist
|
||||||
|
|
||||||
services.Spotifyplus.PlayerMediaPlayContext(
|
services.Spotifyplus.PlayerMediaPlayContext(
|
||||||
contextUri: uri,
|
contextUri: uri,
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
deviceId: SpotifyTypes.DefaultDevId,
|
deviceId: Globals.DefaultDevId,
|
||||||
// My Defaults
|
// My Defaults
|
||||||
positionMs: 0,
|
positionMs: 0,
|
||||||
delay: 0.50
|
delay: 0.50
|
||||||
|
|
|
@ -8,6 +8,8 @@ using NetDaemon.AppModel;
|
||||||
using NetDaemon.HassModel;
|
using NetDaemon.HassModel;
|
||||||
using NetDaemon.HassModel.Integration;
|
using NetDaemon.HassModel.Integration;
|
||||||
|
|
||||||
|
using NetDaemonConfig.Apps.Spotify.Types;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlaySong
|
namespace NetDaemonConfig.Apps.Spotify.PlaySong
|
||||||
{
|
{
|
||||||
|
@ -34,7 +36,7 @@ namespace NetDaemonConfig.Apps.Spotify.PlaySong
|
||||||
await services.Spotifyplus.SearchTracksAsync(
|
await services.Spotifyplus.SearchTracksAsync(
|
||||||
criteria: $"{e?.artist} {e?.song}",
|
criteria: $"{e?.artist} {e?.song}",
|
||||||
limitTotal: 1,
|
limitTotal: 1,
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
// My Defaults
|
// My Defaults
|
||||||
market: "CA",
|
market: "CA",
|
||||||
includeExternal: "audio"
|
includeExternal: "audio"
|
||||||
|
@ -47,8 +49,8 @@ namespace NetDaemonConfig.Apps.Spotify.PlaySong
|
||||||
|
|
||||||
services.Spotifyplus.PlayerMediaPlayTracks(
|
services.Spotifyplus.PlayerMediaPlayTracks(
|
||||||
uris: uri,
|
uris: uri,
|
||||||
entityId: SpotifyTypes.DefaultEntityId,
|
entityId: Globals.DefaultEntityId,
|
||||||
deviceId: SpotifyTypes.DefaultDevId,
|
deviceId: Globals.DefaultDevId,
|
||||||
// My Defaults
|
// My Defaults
|
||||||
positionMs: 0,
|
positionMs: 0,
|
||||||
delay: 0.50
|
delay: 0.50
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace NetDaemonConfig.Apps.Spotify.Types
|
||||||
|
{
|
||||||
|
public record ArtistAlbumItem
|
||||||
|
{
|
||||||
|
public string? AlbumType { get; set; }
|
||||||
|
public List<Artist>? Artists { get; set; }
|
||||||
|
public List<object>? AvailableMarkets { get; set; }
|
||||||
|
public ExternalUrls? ExternalUrls { get; set; }
|
||||||
|
public string? Href { get; set; }
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? ImageUrl { get; set; }
|
||||||
|
public List<Image>? Images { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public string? ReleaseDate { get; set; }
|
||||||
|
public string? ReleaseDatePrecision { get; set; }
|
||||||
|
public Restrictions? Restrictions { get; set; }
|
||||||
|
public int? TotalTracks { get; set; }
|
||||||
|
public string? Type { get; set; }
|
||||||
|
public string? Uri { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public record ArtistAlbumResult
|
||||||
|
{
|
||||||
|
public double? DateLastRefreshed { get; set; }
|
||||||
|
public string? Href { get; set; }
|
||||||
|
public int? Limit { get; set; }
|
||||||
|
public object? Next { get; set; }
|
||||||
|
public int? Offset { get; set; }
|
||||||
|
public object? Previous { get; set; }
|
||||||
|
public int? Total { get; set; }
|
||||||
|
public List<ArtistAlbumItem>? Items { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SpotifyPlusGetArtistAlbumsResponse
|
||||||
|
{
|
||||||
|
public UserProfile? UserProfile { get; set; }
|
||||||
|
public ArtistAlbumResult? Result { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify
|
namespace NetDaemonConfig.Apps.Spotify.Types
|
||||||
{
|
{
|
||||||
public static class SpotifyTypes
|
public static class Globals
|
||||||
{
|
{
|
||||||
public const string DefaultDevId = "homie";
|
public const string DefaultDevId = "homie";
|
||||||
public const string DefaultEntityId = "media_player.spotifyplus";
|
public const string DefaultEntityId = "media_player.spotifyplus";
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlayPlaylist
|
namespace NetDaemonConfig.Apps.Spotify.Types
|
||||||
{
|
{
|
||||||
public record PlaylistsItem
|
public record PlaylistsItem
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlayAlbum
|
namespace NetDaemonConfig.Apps.Spotify.Types
|
||||||
{
|
{
|
||||||
public record AlbumItem
|
public record AlbumItem
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlayArtist
|
namespace NetDaemonConfig.Apps.Spotify.Types
|
||||||
{
|
{
|
||||||
public record ArtistItem
|
public record ArtistItem
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
namespace NetDaemonConfig.Apps.Spotify.PlaySong
|
namespace NetDaemonConfig.Apps.Spotify.Types
|
||||||
{
|
{
|
||||||
public record SongItem
|
public record SongItem
|
||||||
{
|
{
|
|
@ -35,7 +35,6 @@ in {
|
||||||
end,
|
end,
|
||||||
});
|
});
|
||||||
|
|
||||||
-- FIXME: make editorconfig and format work
|
|
||||||
require('roslyn').setup({
|
require('roslyn').setup({
|
||||||
config = {
|
config = {
|
||||||
capabilities = require('cmp_nvim_lsp').default_capabilities(),
|
capabilities = require('cmp_nvim_lsp').default_capabilities(),
|
||||||
|
|
Loading…
Reference in a new issue