Обнновлено до .net10

This commit is contained in:
FrigaT
2026-04-10 15:05:32 +03:00
parent 11d0b0d72f
commit 8444fc5f8e
386 changed files with 6361 additions and 7164 deletions

View File

@@ -1,10 +1,9 @@
using YandexMusic.API.Models.Artist;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YArtistsFromHistory
{
public class YArtistsFromHistory
{
public YArtist Artist { get; set; }
public List<YArtist> ArtistsFromHistory { get; set; }
}
public YArtist Artist { get; set; }
public List<YArtist> ArtistsFromHistory { get; set; }
}

View File

@@ -1,104 +1,9 @@
namespace YandexMusic.API.Models.Feed.Event
using YandexMusic.API.Models.Feed.Event;
namespace YandexMusic.API.Models.Feed;
public class YFeedEvent
{
public sealed class YFeedEventConverter : JsonConverter
{
private YFeedEventTitled GetEvent(JToken jObject)
{
YFeedEventTitled feedEvent;
YFeedEventType type = jObject[jObject["typeForFrom"] != null ? "typeForFrom" : "type"]
.ToObject<YFeedEventType>();
switch (type)
{
case YFeedEventType.GenreTop:
feedEvent = jObject.ToObject<YFeedEventGenreTracksTop>();
break;
case YFeedEventType.NewAlbums:
feedEvent = jObject.ToObject<YFeedEventAlbums>();
break;
case YFeedEventType.NewAlbumsOfFavoriteGenre:
feedEvent = jObject.ToObject<YFeedEventGenreAlbums>();
break;
case YFeedEventType.Notification:
feedEvent = jObject.ToObject<YFeedEventNotification>();
break;
case YFeedEventType.Promotion:
feedEvent = jObject.ToObject<YFeedEventPromotion>();
break;
case YFeedEventType.RecentTrackLikeToTracks:
feedEvent = jObject.ToObject<YFeedEventLikeTrack>();
break;
case YFeedEventType.RecommendedArtistsWithArtistsFromHistory:
feedEvent = jObject.ToObject<YFeedEventArtistWithArtists>();
break;
case YFeedEventType.RecommendedSimilarArtists:
feedEvent = jObject.ToObject<YFeedEventSimilarArtists>();
break;
case YFeedEventType.RecommendedSimilarGenre:
feedEvent = jObject.ToObject<YFeedEventSimilarGenre>();
break;
case YFeedEventType.MissedTracksByArtist:
case YFeedEventType.RareArtist:
case YFeedEventType.RecommendedTracksByArtistFromHistory:
feedEvent = jObject.ToObject<YFeedEventArtist>();
break;
case YFeedEventType.NewTracksOfFavoriteGenre:
case YFeedEventType.TracksByGenre:
feedEvent = jObject.ToObject<YFeedEventGenreTracks>();
break;
case YFeedEventType.WellForgottenOldArtists:
feedEvent = jObject.ToObject<YFeedEventArtists>();
break;
case YFeedEventType.NeverHeardFromLibrary:
case YFeedEventType.WellForgottenOldTracks:
feedEvent = jObject.ToObject<YFeedEventTracks>();
break;
default:
feedEvent = jObject.ToObject<YFeedEventTitled>();
break;
}
return feedEvent;
}
public override bool CanConvert(Type objectType)
{
return typeof(YFeedEventTitled).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
return JArray.Load(reader)
.Select(GetEvent)
.ToList();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class YFeedEvent
{
public string Id { get; set; }
public YFeedEventType Type { get; set; }
}
public string Id { get; set; }
public YFeedEventType Type { get; set; }
}

View File

@@ -1,9 +1,8 @@
using YandexMusic.API.Models.Album;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventAlbums : YFeedEventTitled
{
public class YFeedEventAlbums : YFeedEventTitled
{
public List<YAlbum> Albums { get; set; }
}
public List<YAlbum> Albums { get; set; }
}

View File

@@ -1,9 +1,8 @@
using YandexMusic.API.Models.Artist;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventArtist : YFeedEventTracks
{
public class YFeedEventArtist : YFeedEventTracks
{
public YArtist Artist { get; set; }
}
public YArtist Artist { get; set; }
}

View File

@@ -1,7 +1,6 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventArtistWithArtists : YFeedEventTitled
{
public class YFeedEventArtistWithArtists : YFeedEventTitled
{
public List<YArtistsFromHistory> ArtistsWithArtistsFromHistory { get; set; }
}
public List<YArtistsFromHistory> ArtistsWithArtistsFromHistory { get; set; }
}

View File

@@ -1,9 +1,8 @@
using YandexMusic.API.Models.Artist;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventArtists : YFeedEventTitled
{
public class YFeedEventArtists : YFeedEventTitled
{
public List<YArtist> Artists { get; set; }
}
public List<YArtist> Artists { get; set; }
}

View File

@@ -0,0 +1,97 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using YandexMusic.API.Models.Feed.Event;
namespace YandexMusic.API.Models.Feed;
/// <summary>Конвертер для событий ленты (десериализация в конкретные типы на основе поля type).</summary>
public class YFeedEventConverter : JsonConverter<List<YFeedEventTitled>>
{
public override List<YFeedEventTitled> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException("Ожидается массив событий");
var events = new List<YFeedEventTitled>();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray)
break;
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException("Ожидается объект события");
using var doc = JsonDocument.ParseValue(ref reader);
var root = doc.RootElement;
// Определяем тип события: может быть в поле "typeForFrom" или "type"
var typeToken = root.TryGetProperty("typeForFrom", out var tf) ? tf :
(root.TryGetProperty("type", out var t) ? t : throw new JsonException("Не найден тип события"));
var typeStr = typeToken.GetString();
if (!Enum.TryParse<YFeedEventType>(typeStr, true, out var eventType))
throw new JsonException($"Неизвестный тип события: {typeStr}");
YFeedEventTitled? feedEvent = null;
var rawText = root.GetRawText();
switch (eventType)
{
case YFeedEventType.GenreTop:
feedEvent = JsonSerializer.Deserialize<YFeedEventGenreTracksTop>(rawText, options);
break;
case YFeedEventType.NewAlbums:
feedEvent = JsonSerializer.Deserialize<YFeedEventAlbums>(rawText, options);
break;
case YFeedEventType.NewAlbumsOfFavoriteGenre:
feedEvent = JsonSerializer.Deserialize<YFeedEventGenreAlbums>(rawText, options);
break;
case YFeedEventType.Notification:
feedEvent = JsonSerializer.Deserialize<YFeedEventNotification>(rawText, options);
break;
case YFeedEventType.Promotion:
feedEvent = JsonSerializer.Deserialize<YFeedEventPromotion>(rawText, options);
break;
case YFeedEventType.RecentTrackLikeToTracks:
feedEvent = JsonSerializer.Deserialize<YFeedEventLikeTrack>(rawText, options);
break;
case YFeedEventType.RecommendedArtistsWithArtistsFromHistory:
feedEvent = JsonSerializer.Deserialize<YFeedEventArtistWithArtists>(rawText, options);
break;
case YFeedEventType.RecommendedSimilarArtists:
feedEvent = JsonSerializer.Deserialize<YFeedEventSimilarArtists>(rawText, options);
break;
case YFeedEventType.RecommendedSimilarGenre:
feedEvent = JsonSerializer.Deserialize<YFeedEventSimilarGenre>(rawText, options);
break;
case YFeedEventType.MissedTracksByArtist:
case YFeedEventType.RareArtist:
case YFeedEventType.RecommendedTracksByArtistFromHistory:
feedEvent = JsonSerializer.Deserialize<YFeedEventArtist>(rawText, options);
break;
case YFeedEventType.NewTracksOfFavoriteGenre:
case YFeedEventType.TracksByGenre:
feedEvent = JsonSerializer.Deserialize<YFeedEventGenreTracks>(rawText, options);
break;
case YFeedEventType.WellForgottenOldArtists:
feedEvent = JsonSerializer.Deserialize<YFeedEventArtists>(rawText, options);
break;
case YFeedEventType.NeverHeardFromLibrary:
case YFeedEventType.WellForgottenOldTracks:
feedEvent = JsonSerializer.Deserialize<YFeedEventTracks>(rawText, options);
break;
default:
feedEvent = JsonSerializer.Deserialize<YFeedEventTitled>(rawText, options);
break;
}
if (feedEvent != null)
events.Add(feedEvent);
}
return events;
}
public override void Write(Utf8JsonWriter writer, List<YFeedEventTitled> value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, options);
}
}

View File

@@ -1,7 +1,6 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventGenreAlbums : YFeedEventAlbums
{
public class YFeedEventGenreAlbums : YFeedEventAlbums
{
public string Genre { get; set; }
}
public string Genre { get; set; }
}

View File

@@ -1,7 +1,6 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventGenreTracks : YFeedEventTracks
{
public class YFeedEventGenreTracks : YFeedEventTracks
{
public string Genre { get; set; }
}
public string Genre { get; set; }
}

View File

@@ -1,7 +1,6 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventGenreTracksTop : YFeedEventGenreTracks
{
public class YFeedEventGenreTracksTop : YFeedEventGenreTracks
{
public bool RadioIsAvailable { get; set; }
}
public bool RadioIsAvailable { get; set; }
}

View File

@@ -1,9 +1,8 @@
using YandexMusic.API.Models.Track;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventLikeTrack : YFeedEventTracks
{
public class YFeedEventLikeTrack : YFeedEventTracks
{
public YTrack LikedTrack { get; set; }
}
public YTrack LikedTrack { get; set; }
}

View File

@@ -1,7 +1,6 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventNotification : YFeedEventTitled
{
public class YFeedEventNotification : YFeedEventTitled
{
public string Message { get; set; }
}
public string Message { get; set; }
}

View File

@@ -1,7 +1,6 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventPromotion : YFeedEventTitled
{
public class YFeedEventPromotion : YFeedEventTitled
{
public YFeedPromotion Promo { get; set; }
}
public YFeedPromotion Promo { get; set; }
}

View File

@@ -1,8 +1,7 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public enum YFeedEventPromotionType
{
public enum YFeedEventPromotionType
{
Albums,
Tracks
}
Albums,
Tracks
}

View File

@@ -1,10 +1,9 @@
using YandexMusic.API.Models.Artist;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventSimilarArtists : YFeedEventTitled
{
public class YFeedEventSimilarArtists : YFeedEventTitled
{
public YArtist SimilarToArtist { get; set; }
public List<YArtist> SimilarArtists { get; set; }
}
public YArtist SimilarToArtist { get; set; }
public List<YArtist> SimilarArtists { get; set; }
}

View File

@@ -1,8 +1,7 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventSimilarGenre : YFeedEventTracks
{
public class YFeedEventSimilarGenre : YFeedEventTracks
{
public string SimilarToGenre { get; set; }
public string SimilarGenre { get; set; }
}
public string SimilarToGenre { get; set; }
public string SimilarGenre { get; set; }
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventTitle
{
public class YFeedEventTitle
{
public string Id { get; set; }
public YFeedEventTitleType Type { get; set; }
public string Name { get; set; }
public string Text { get; set; }
}
public string Id { get; set; }
public YFeedEventTitleType Type { get; set; }
public string Name { get; set; }
public string Text { get; set; }
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public enum YFeedEventTitleType
{
public enum YFeedEventTitleType
{
Artist,
Genre,
Text,
Track
}
Artist,
Genre,
Text,
Track
}

View File

@@ -1,8 +1,7 @@
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventTitled : YFeedEvent
{
public class YFeedEventTitled : YFeedEvent
{
public List<YFeedEventTitle> Title { get; set; }
public YFeedEventType TypeForFrom { get; set; }
}
public List<YFeedEventTitle> Title { get; set; }
public YFeedEventType TypeForFrom { get; set; }
}

View File

@@ -1,9 +1,8 @@
using YandexMusic.API.Models.Track;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public class YFeedEventTracks : YFeedEventTitled
{
public class YFeedEventTracks : YFeedEventTitled
{
public List<YTrack> Tracks { get; set; }
}
public List<YTrack> Tracks { get; set; }
}

View File

@@ -1,59 +1,58 @@
using System.Runtime.Serialization;
namespace YandexMusic.API.Models.Feed.Event
namespace YandexMusic.API.Models.Feed.Event;
public enum YFeedEventType
{
public enum YFeedEventType
{
[EnumMember(Value = "genre-top")]
GenreTop,
[EnumMember(Value = "genre-top")]
GenreTop,
[EnumMember(Value = "missed-tracks-by-artist")]
MissedTracksByArtist,
[EnumMember(Value = "missed-tracks-by-artist")]
MissedTracksByArtist,
[EnumMember(Value = "never-heard-from-library")]
NeverHeardFromLibrary,
[EnumMember(Value = "never-heard-from-library")]
NeverHeardFromLibrary,
[EnumMember(Value = "new-albums")]
NewAlbums,
[EnumMember(Value = "new-albums")]
NewAlbums,
[EnumMember(Value = "new-albums-of-favorite-genre")]
NewAlbumsOfFavoriteGenre,
[EnumMember(Value = "new-albums-of-favorite-genre")]
NewAlbumsOfFavoriteGenre,
[EnumMember(Value = "new-tracks-of-favorite-genre")]
NewTracksOfFavoriteGenre,
[EnumMember(Value = "new-tracks-of-favorite-genre")]
NewTracksOfFavoriteGenre,
Notification,
Notification,
Promotion,
Promotion,
[EnumMember(Value = "rare-artist")]
RareArtist,
[EnumMember(Value = "rare-artist")]
RareArtist,
[EnumMember(Value = "recent-track-like-to-tracks")]
RecentTrackLikeToTracks,
[EnumMember(Value = "recent-track-like-to-tracks")]
RecentTrackLikeToTracks,
[EnumMember(Value = "recommended-artists-with-artists-from-history")]
RecommendedArtistsWithArtistsFromHistory,
[EnumMember(Value = "recommended-artists-with-artists-from-history")]
RecommendedArtistsWithArtistsFromHistory,
[EnumMember(Value = "recommended-similar-artists")]
RecommendedSimilarArtists,
[EnumMember(Value = "recommended-similar-artists")]
RecommendedSimilarArtists,
[EnumMember(Value = "recommended-similar-genre")]
RecommendedSimilarGenre,
[EnumMember(Value = "recommended-similar-genre")]
RecommendedSimilarGenre,
[EnumMember(Value = "recommended-tracks-by-artist-from-history")]
RecommendedTracksByArtistFromHistory,
[EnumMember(Value = "recommended-tracks-by-artist-from-history")]
RecommendedTracksByArtistFromHistory,
[EnumMember(Value = "similar-tracks-from-history")]
SimilarTracksFromHistory,
[EnumMember(Value = "similar-tracks-from-history")]
SimilarTracksFromHistory,
[EnumMember(Value = "tracks-by-genre")]
TracksByGenre,
[EnumMember(Value = "tracks-by-genre")]
TracksByGenre,
[EnumMember(Value = "well-forgotten-old-artists")]
WellForgottenOldArtists,
[EnumMember(Value = "well-forgotten-old-artists")]
WellForgottenOldArtists,
[EnumMember(Value = "well-forgotten-old-tracks")]
WellForgottenOldTracks
}
[EnumMember(Value = "well-forgotten-old-tracks")]
WellForgottenOldTracks,
}

View File

@@ -2,23 +2,22 @@
using YandexMusic.API.Models.Common;
using YandexMusic.API.Models.Track;
namespace YandexMusic.API.Models.Feed.Event
{
public class YFeedPromotion
{
public string PromoId { get; set; }
public string Description { get; set; }
public string Background { get; set; }
public string ImagePosition { get; set; }
public YFeedEventPromotionType PromotionType { get; set; }
public DateTime StartDate { get; set; }
public string SubTitle { get; set; }
public string SubtitleUrl { get; set; }
public string Title { get; set; }
public string TitleUrl { get; set; }
public List<YTag> Tags { get; set; }
namespace YandexMusic.API.Models.Feed.Event;
public List<YAlbum> Albums { get; set; }
public List<YTrack> Tracks { get; set; }
}
public class YFeedPromotion
{
public string PromoId { get; set; }
public string Description { get; set; }
public string Background { get; set; }
public string ImagePosition { get; set; }
public YFeedEventPromotionType PromotionType { get; set; }
public DateTime StartDate { get; set; }
public string SubTitle { get; set; }
public string SubtitleUrl { get; set; }
public string Title { get; set; }
public string TitleUrl { get; set; }
public List<YTag> Tags { get; set; }
public List<YAlbum> Albums { get; set; }
public List<YTrack> Tracks { get; set; }
}