Skip to content

Commit

Permalink
Merge branch 'release/3.0.0' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
SKProCH committed Feb 3, 2021
2 parents f410e08 + 01cddaa commit 952ec70
Show file tree
Hide file tree
Showing 51 changed files with 812 additions and 922 deletions.
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ Add [nuget package](https://www.nuget.org/packages/YandexMusicResolver/) to your
```
dotnet add package YandexMusicResolver
```
or
```
Install-Package YandexMusicResolver -Version 2.0.0
```
</li>

<li>
Expand Down Expand Up @@ -57,7 +53,7 @@ Example code for getting direct track download url:
var fileYandexConfig = new FileYandexConfig("yandex.config");
fileYandexConfig.Load();
var yandexMusicMainResolver = new YandexMusicMainResolver(fileYandexConfig);
var directUrl = await yandexMusicMainResolver.DirectUrlLoader.GetDirectUrl("55561798", "mp3");
var directUrl = await yandexMusicMainResolver.DirectUrlLoader.GetDirectUrl("55561798");
Console.WriteLine(directUrl);
```
**Warn:** Yandex will return a link to a 30-seconds track if you do not log in (do not use a config with a valid token).
Expand Down
6 changes: 6 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# v3.0.0
- ***BREAKING CHANGES***: `LoadPlaylist` -> `LoadAlbum`, remove `almubId` from `LoadTrack`, remove track `Metadata` `IsStream`, rework `YandexMusicMainResolver` and `YandexMusicSearchResultLoader` ctors, new `YandexMusicAuth` method names, ***`Load` in config now called by loaders and can be called multiple times***
- Global type system rework: playlist now differs from album, no more meta classes as public API, new load on demand system for tracks in playlists and albums, remove `AudioTrackInfo`, now `YandexMusicTrack` are standalone, remove `IAudioItem` - `ResolveQueue` now return `YandexMusicSearchResult` and other changes
- Extend MainResolver `ResolveQuery` functionality


# v2.2.1
- Add some missing xml docs

Expand Down
4 changes: 4 additions & 0 deletions YandexMusicResolver.Tests/EnvironmentConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

namespace YandexMusicResolver.Tests {
public class EnvironmentConfig : IYandexConfig {
private bool isLoaded;
public void Load() {
if (isLoaded) return;
YandexLogin = Environment.GetEnvironmentVariable("YandexLogin");
YandexPassword = Environment.GetEnvironmentVariable("YandexPassword");
YandexToken = Environment.GetEnvironmentVariable("YandexToken");
Expand All @@ -14,6 +16,8 @@ public void Load() {
if (proxyUrl != null) {
YandexProxy = new WebProxy(proxyUrl);
}

isLoaded = true;
}

public void Save() { }
Expand Down
40 changes: 33 additions & 7 deletions YandexMusicResolver.Tests/YandexMusicMainResolverTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,58 @@ public class YandexMusicMainResolverTest : YandexTestBase{
public void GetTrack(string url) {
var audioItem = MainResolver.ResolveQuery(url).GetAwaiter().GetResult();
Assert.NotNull(audioItem);
Assert.IsType<YandexMusicTrack>(audioItem);
Assert.False(audioItem.IsSearchResult);
Assert.NotNull(audioItem.Tracks);
Assert.Null(audioItem.Playlists);
Assert.Null(audioItem.Albums);
Assert.NotEmpty(audioItem.Tracks);
Assert.Equal(YandexSearchType.Track, YandexSearchType.Track);
}

[Theory]
[InlineData("https://music.yandex.ru/album/9425747")]
public void GetAlbum(string url) {
var audioItem = MainResolver.ResolveQuery(url).GetAwaiter().GetResult();
Assert.NotNull(audioItem);
Assert.IsType<YandexMusicPlaylist>(audioItem);
Assert.False(audioItem.IsSearchResult);
Assert.NotNull(audioItem.Albums);
Assert.Null(audioItem.Tracks);
Assert.Null(audioItem.Playlists);
Assert.NotEmpty(audioItem.Albums);
Assert.Equal(YandexSearchType.Album, audioItem.Type);
}

[Theory]
[InlineData("https://music.yandex.ru/users/enlivenbot/playlists/1000")]
public void GetPlaylist(string url) {
var audioItem = MainResolver.ResolveQuery(url).GetAwaiter().GetResult();
Assert.NotNull(audioItem);
Assert.IsType<YandexMusicPlaylist>(audioItem);
Assert.False(audioItem.IsSearchResult);
Assert.NotNull(audioItem.Playlists);
Assert.Null(audioItem.Tracks);
Assert.Null(audioItem.Albums);
Assert.NotEmpty(audioItem.Playlists);
Assert.Equal(YandexSearchType.Playlist, audioItem.Type);
}

[Fact]
public void TestDisabledSearch() {
var yandexMusicMainResolver = new YandexMusicMainResolver(Config, false);
var audioItem = yandexMusicMainResolver.ResolveQuery("Take Over").GetAwaiter().GetResult();
[Theory]
[InlineData("Take over")]
[InlineData("ymsearch:Track:10:Take over")]
public void TestDisabledSearch(string query) {
var yandexMusicMainResolver = new YandexMusicMainResolver(Config) {AllowSearch = false};
var audioItem = yandexMusicMainResolver.ResolveQuery(query).GetAwaiter().GetResult();
Assert.Null(audioItem);
}

[Theory]
[InlineData("Take over", true)]
[InlineData("ymsearch:Track:10:Take over", false)]
public void TestDisabledPlainTextSearch(string query, bool isPlainText) {
var yandexMusicMainResolver = new YandexMusicMainResolver(Config) {PlainTextIsSearchQuery = false};
var audioItem = yandexMusicMainResolver.ResolveQuery(query).GetAwaiter().GetResult();
Assert.Equal(isPlainText, audioItem == null);
}

[Theory]
[InlineData("Take Over")]
public void TestSearch(string url) {
Expand Down
13 changes: 6 additions & 7 deletions YandexMusicResolver.Tests/YandexMusicPlaylistLoaderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,20 @@ public class YandexMusicPlaylistLoaderTest : YandexTestBase {
[InlineData("9425747", "Renovatio", 12)]
[InlineData("12033669", "Take Over", 1)]
public void LoadAlbum(string albumId, string expectedName, int trackCount) {
TrackFactory = info => new YandexMusicTrack(info, MainResolver);
var playlist = MainResolver.PlaylistLoader.LoadPlaylist(albumId, TrackFactory).GetAwaiter().GetResult();
Assert.NotNull(playlist);
Assert.Equal(expectedName, playlist.Title);
Assert.Equal(trackCount, playlist.Tracks.Count);
var album = MainResolver.PlaylistLoader.LoadAlbum(albumId).GetAwaiter().GetResult();
Assert.NotNull(album);
Assert.Equal(expectedName, album.Title);
Assert.Equal(trackCount, album.Data.Count);
}

[Theory]
[InlineData("enlivenbot", "1000", "Test1", 60)]
[InlineData("enlivenbot", "1001", "Test2", 36)]
public void LoadPlaylist(string userId, string playlistId, string expectedName, int trackCount) {
var playlist = MainResolver.PlaylistLoader.LoadPlaylist(userId, playlistId, TrackFactory).GetAwaiter().GetResult();
var playlist = MainResolver.PlaylistLoader.LoadPlaylist(userId, playlistId).GetAwaiter().GetResult();
Assert.NotNull(playlist);
Assert.Equal(expectedName, playlist.Title);
Assert.Equal(trackCount, playlist.Tracks.Count);
Assert.Equal(trackCount, playlist.Data.Count);
}
}
}
16 changes: 7 additions & 9 deletions YandexMusicResolver.Tests/YandexMusicSearchResultLoaderTest.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
#nullable enable
using Xunit;
using YandexMusicResolver.Config;
using YandexMusicResolver.Loaders;

namespace YandexMusicResolver.Tests {
public class YandexMusicSearchResultLoaderTest : YandexTestBase {
[Fact]
public void DoTrackSearch() {
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.Track, "Take Over",
MainResolver.PlaylistLoader, TrackFactory).GetAwaiter().GetResult();
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.Track, "Take Over").GetAwaiter().GetResult();
Assert.NotNull(trackSearchResult);
Assert.NotNull(trackSearchResult?.Tracks);
}

[Fact]
public void DoAlbumSearch() {
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.Album, "Take Over",
MainResolver.PlaylistLoader, TrackFactory).GetAwaiter().GetResult();
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.Album, "Take Over").GetAwaiter().GetResult();
Assert.NotNull(trackSearchResult);
Assert.NotNull(trackSearchResult?.Albums);
}

[Fact]
public void DoAllSearch() {
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.All, "Take Over",
MainResolver.PlaylistLoader, TrackFactory).GetAwaiter().GetResult();
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.All, "Take Over").GetAwaiter().GetResult();
Assert.NotNull(trackSearchResult);
Assert.NotNull(trackSearchResult?.Albums);
Assert.NotNull(trackSearchResult?.Playlists);
Expand All @@ -32,8 +30,7 @@ public void DoAllSearch() {

[Fact]
public void DoPlaylistSearch() {
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.Playlist, "Take Over",
MainResolver.PlaylistLoader, TrackFactory).GetAwaiter().GetResult();
var trackSearchResult = MainResolver.SearchResultLoader.LoadSearchResult(YandexSearchType.Playlist, "Take Over").GetAwaiter().GetResult();
Assert.NotNull(trackSearchResult);
Assert.NotNull(trackSearchResult?.Playlists);
}
Expand All @@ -44,7 +41,8 @@ public void DoPlaylistSearch() {
[InlineData("myprefix")]
public void TestPrefixes(string? prefix) {
#pragma warning disable 8625
var yandexMusicSearchResultLoader = new YandexMusicSearchResultLoader(null, prefix);
var yandexMusicSearchResultLoader = new YandexMusicSearchResultLoader(new EmptyYandexConfig(), null);
yandexMusicSearchResultLoader.SetSearchPrefix(prefix);
#pragma warning restore 8625
prefix ??= "ymsearch";
var correctQuery = $"{prefix}:playlist:25:take over";
Expand Down
2 changes: 1 addition & 1 deletion YandexMusicResolver.Tests/YandexMusicTrackLoaderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class YandexMusicTrackLoaderTest : YandexTestBase {
[InlineData("12033669", "70937156")]
public void GetTracksInfo(string albumId, string trackId) {
var yandexMusicTrackLoader = new YandexMusicTrackLoader(Config);
var trackInfo = yandexMusicTrackLoader.LoadTrackInfo(albumId, trackId).GetAwaiter().GetResult();
var trackInfo = yandexMusicTrackLoader.LoadTrack(trackId).GetAwaiter().GetResult();
Assert.NotNull(trackInfo);
Assert.Equal($"https://music.yandex.ru/album/{albumId}/track/{trackId}", trackInfo.Uri);
}
Expand Down
5 changes: 1 addition & 4 deletions YandexMusicResolver.Tests/YandexTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace YandexMusicResolver.Tests {
public class YandexTestBase {
public IYandexConfig Config;
public YandexMusicMainResolver MainResolver;
public Func<AudioTrackInfo, YandexMusicTrack> TrackFactory;

public YandexTestBase() {
if (File.Exists("TestData.json")) {
Expand All @@ -17,9 +16,7 @@ public YandexTestBase() {
Config = new EnvironmentConfig();
}

Config.Load();
MainResolver = new YandexMusicMainResolver(Config, true);
TrackFactory = info => new YandexMusicTrack(info, MainResolver);
MainResolver = new YandexMusicMainResolver(Config);
}
}
}
2 changes: 1 addition & 1 deletion YandexMusicResolver/ApiResponceError.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using YandexMusicResolver.Responces;
using YandexMusicResolver.Responses;

namespace YandexMusicResolver {
/// <summary>
Expand Down
6 changes: 0 additions & 6 deletions YandexMusicResolver/AudioItems/IAudioItem.cs

This file was deleted.

67 changes: 67 additions & 0 deletions YandexMusicResolver/AudioItems/YandexMusicAlbum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YandexMusicResolver.Loaders;

namespace YandexMusicResolver.AudioItems {
public class YandexMusicAlbum : YandexMusicDataContainer<List<YandexMusicTrack>> {
internal YandexMusicAlbum(long id, long year, List<YandexMusicArtist> artists, string? artworkUrl, long trackCount, string genre, string title,
YandexMusicPlaylistLoader loader) : base(async () => (await loader.LoadAlbum(id.ToString()))!.Data.ToList()) {
Id = id;
Year = year;
Artists = artists;
ArtworkUrl = artworkUrl;
TrackCount = trackCount;
Genre = genre;
Title = title;
}

internal YandexMusicAlbum(long id, long year, List<YandexMusicArtist> artists, string? artworkUrl, long trackCount, string genre, string title,
List<YandexMusicTrack> tracks) : base(tracks) {
Id = id;
Year = year;
Artists = artists;
ArtworkUrl = artworkUrl;
TrackCount = trackCount;
Genre = genre;
Title = title;
}


/// <summary>
/// Album id
/// </summary>
public long Id { get; }

/// <summary>
/// Album release year
/// </summary>
public long Year { get; }

/// <summary>
/// Album artists
/// </summary>
public List<YandexMusicArtist> Artists { get; }

/// <summary>
/// Track image uri
/// </summary>
public string? ArtworkUrl { get; }

/// <summary>
/// Album tracks count
/// </summary>
public long TrackCount { get; }

/// <summary>
/// Album genre
/// </summary>
public string Genre { get; }

/// <summary>
/// Track title
/// </summary>
public string Title { get; }
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Newtonsoft.Json;

namespace YandexMusicResolver.Responces {
namespace YandexMusicResolver.AudioItems {
/// <summary>
/// Represent a artist in Yandex Music
/// </summary>
public class MetaArtist {
public class YandexMusicArtist {
/// <summary>
/// Artist ID
/// </summary>
Expand Down
51 changes: 51 additions & 0 deletions YandexMusicResolver/AudioItems/YandexMusicDataContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Threading.Tasks;

namespace YandexMusicResolver.AudioItems {
/// <summary>
/// Represents class that contains data which could be loaded
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class YandexMusicDataContainer<T> {
private Func<Task<T>> loadDataFactory;
private Task<T>? _loadDataTask;

/// <summary>
/// Create instance of <see cref="YandexMusicDataContainer{T}"/>
/// </summary>
/// <param name="loadDataFactory">Data creation factory</param>
public YandexMusicDataContainer(Func<Task<T>> loadDataFactory) {
this.loadDataFactory = loadDataFactory;
}

/// <summary>
/// Create instance of <see cref="YandexMusicDataContainer{T}"/>
/// </summary>
/// <param name="data">Target data</param>
public YandexMusicDataContainer(T data) {
var task = Task.FromResult(data);
loadDataFactory = () => task;
_loadDataTask = task;
}

private Task<T> LoadDataTask => _loadDataTask ??= loadDataFactory();

/// <summary>
/// Load target data
/// </summary>
/// <returns>Task</returns>
public Task<T> LoadDataAsync() {
return LoadDataTask;
}

/// <summary>
/// Return true if data already loaded
/// </summary>
public bool IsDataLoaded => _loadDataTask?.IsCompleted ?? false;

/// <summary>
/// Synchronously wait for data loading
/// </summary>
public T Data => LoadDataAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Newtonsoft.Json;

namespace YandexMusicResolver.Responces {
namespace YandexMusicResolver.AudioItems {
/// <summary>
/// Represent playlist owner
/// </summary>
public class MetaOwner {
public class YandexMusicOwner {
/// <summary>
/// Owner ID
/// </summary>
Expand Down
Loading

0 comments on commit 952ec70

Please sign in to comment.