Обнновлено до .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

@@ -5,23 +5,22 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
{
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/commit_password")]
internal class YGetAuthAppPasswordBuilder : YRequestBuilder<YAuthBase, string>
{
public YGetAuthAppPasswordBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Account;
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
{ "password", tuple },
{ "retpath", "https://passport.yandex.ru/am/finish?status=ok&from=Login" }
});
}
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/commit_password")]
internal class YGetAuthAppPasswordBuilder : YRequestBuilder<YAuthBase, string>
{
public YGetAuthAppPasswordBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
{ "password", tuple },
{ "retpath", "https://passport.yandex.ru/am/finish?status=ok&from=Login" }
});
}
}

View File

@@ -5,26 +5,25 @@ using YandexMusic.API.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/textcaptcha")]
internal class YGetAuthCaptchaBuilder : YRequestBuilder<Models.Account.YAuthCaptcha, string>
{
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/textcaptcha")]
internal class YGetAuthCaptchaBuilder : YRequestBuilder<Models.Account.YAuthCaptcha, string>
public YGetAuthCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetAuthCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
});
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
});
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Requested-With", "XMLHttpRequest");
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Requested-With", "XMLHttpRequest");
}
}

View File

@@ -6,32 +6,31 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YMobileProxyRequest(WebRequestMethods.Http.Post, "1/bundle/oauth/token_by_sessionid")]
internal class YGetAuthCookiesBuilder : YRequestBuilder<YAccessToken, string>
{
[YMobileProxyRequest(WebRequestMethods.Http.Post, "1/bundle/oauth/token_by_sessionid")]
internal class YGetAuthCookiesBuilder : YRequestBuilder<YAccessToken, string>
public YGetAuthCookiesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetAuthCookiesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
CookieCollection cookieCollection = new() {
storage.Context.Cookies.GetCookies(new Uri("https://yandex.ru/")),
storage.Context.Cookies.GetCookies(new Uri("https://passport.yandex.ru/"))
};
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
CookieCollection cookieCollection = new() {
storage.Context.Cookies.GetCookies(new Uri("https://yandex.ru/")),
storage.Context.Cookies.GetCookies(new Uri("https://passport.yandex.ru/"))
};
headers.Add("Ya-Client-Cookie", string.Join(";", cookieCollection.Select(c => $"{c.Name}={c.Value}")));
headers.Add("Ya-Client-Host", "passport.yandex.ru");
}
headers.Add("Ya-Client-Cookie", string.Join(";", cookieCollection.Select(c => $"{c.Name}={c.Value}")));
headers.Add("Ya-Client-Host", "passport.yandex.ru");
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "client_id", YConstants.XClientId },
{ "client_secret", YConstants.XClientSecret }
});
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "client_id", YConstants.XClientId },
{ "client_secret", YConstants.XClientSecret }
});
}
}

View File

@@ -6,13 +6,12 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YApiRequest(WebRequestMethods.Http.Get, "account/status")]
public class YGetAuthInfoBuilder : YRequestBuilder<YResponse<YAccountResult>, object>
{
[YApiRequest(WebRequestMethods.Http.Get, "account/status")]
public class YGetAuthInfoBuilder : YRequestBuilder<YResponse<YAccountResult>, object>
public YGetAuthInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetAuthInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
}

View File

@@ -4,27 +4,26 @@ using YandexMusic.API.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/send_magic_letter")]
internal class YGetAuthLetterBuilder : YRequestBuilder<Models.Account.YAuthLetter, string>
{
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/send_magic_letter")]
internal class YGetAuthLetterBuilder : YRequestBuilder<Models.Account.YAuthLetter, string>
public YGetAuthLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetAuthLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
}
protected override HttpContent GetContent(string tuple)
{
if (storage.AuthToken == null)
{
throw new Exception("Не найдена сессия входа.");
}
protected override HttpContent GetContent(string tuple)
return new FormUrlEncodedContent(new Dictionary<string, string>
{
if (storage.AuthToken == null)
{
throw new Exception("Не найдена сессия входа.");
}
return new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
});
}
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
});
}
}

View File

@@ -6,27 +6,26 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/checkHuman")]
internal class YGetAuthLoginCaptchaBuilder : YRequestBuilder<YAuthBase, string>
{
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/checkHuman")]
internal class YGetAuthLoginCaptchaBuilder : YRequestBuilder<YAuthBase, string>
public YGetAuthLoginCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetAuthLoginCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
{ "answer", tuple }
});
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
{ "answer", tuple }
});
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Requested-With", "XMLHttpRequest");
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Requested-With", "XMLHttpRequest");
}
}

View File

@@ -5,21 +5,20 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
{
[YPassportRequest(WebRequestMethods.Http.Post, "auth/letter/status/")]
internal class YGetAuthLoginLetterBuilder : YRequestBuilder<YAuthLetterStatus, string>
{
public YGetAuthLoginLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Account;
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
});
}
[YPassportRequest(WebRequestMethods.Http.Post, "auth/letter/status/")]
internal class YGetAuthLoginLetterBuilder : YRequestBuilder<YAuthLetterStatus, string>
{
public YGetAuthLoginLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId },
});
}
}

View File

@@ -5,21 +5,20 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
{
[YPassportRequest(WebRequestMethods.Http.Post, "auth/new/magic/status/")]
internal class YGetAuthLoginQRBuilder : YRequestBuilder<YAuthQRStatus, string>
{
public YGetAuthLoginQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Account;
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId }
});
}
[YPassportRequest(WebRequestMethods.Http.Post, "auth/new/magic/status/")]
internal class YGetAuthLoginQRBuilder : YRequestBuilder<YAuthQRStatus, string>
{
public YGetAuthLoginQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "track_id", storage.AuthToken.TrackId }
});
}
}

View File

@@ -5,21 +5,20 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
{
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/start")]
internal class YGetAuthLoginUserBuilder : YRequestBuilder<YAuthTypes, (string token, string login)>
{
public YGetAuthLoginUserBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Account;
protected override HttpContent GetContent((string token, string login) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", tuple.token },
{ "login", tuple.login }
});
}
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/start")]
internal class YGetAuthLoginUserBuilder : YRequestBuilder<YAuthTypes, (string token, string login)>
{
public YGetAuthLoginUserBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent((string token, string login) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", tuple.token },
{ "login", tuple.login }
});
}
}

View File

@@ -5,20 +5,19 @@ using YandexMusic.API.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
{
[YPassportRequest(WebRequestMethods.Http.Get, "am")]
internal class YGetAuthMethodsBuilder : YRequestBuilder<HttpResponseMessage, string>
{
public YGetAuthMethodsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Account;
protected override NameValueCollection GetQueryParams(string tuple)
{
return new NameValueCollection {
{ "app_platform", "android" }
};
}
[YPassportRequest(WebRequestMethods.Http.Get, "am")]
internal class YGetAuthMethodsBuilder : YRequestBuilder<HttpResponseMessage, string>
{
public YGetAuthMethodsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override NameValueCollection GetQueryParams(string tuple)
{
return new NameValueCollection {
{ "app_platform", "android" }
};
}
}

View File

@@ -5,22 +5,21 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
{
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/password/submit")]
internal class YGetAuthQRBuilder : YRequestBuilder<YAuthQR, string>
{
public YGetAuthQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Account;
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "retpath", "https://passport.yandex.ru/profile" },
{ "with_code", "1" },
});
}
[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/password/submit")]
internal class YGetAuthQRBuilder : YRequestBuilder<YAuthQR, string>
{
public YGetAuthQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "csrf_token", storage.AuthToken.CsfrToken },
{ "retpath", "https://passport.yandex.ru/profile" },
{ "with_code", "1" },
});
}
}

View File

@@ -5,13 +5,12 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YLoginRequest(WebRequestMethods.Http.Get, "info")]
public class YGetLoginInfoBuilder : YRequestBuilder<YLoginInfo, object>
{
[YLoginRequest(WebRequestMethods.Http.Get, "info")]
public class YGetLoginInfoBuilder : YRequestBuilder<YLoginInfo, object>
public YGetLoginInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetLoginInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
}

View File

@@ -6,31 +6,30 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YOAuthMobile(WebRequestMethods.Http.Post, "/1/token")]
internal class YGetMusicTokenBuilder : YRequestBuilder<YAccessToken, string>
{
[YOAuthMobile(WebRequestMethods.Http.Post, "/1/token")]
internal class YGetMusicTokenBuilder : YRequestBuilder<YAccessToken, string>
public YGetMusicTokenBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetMusicTokenBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override HttpContent GetContent(string tuple)
protected override HttpContent GetContent(string tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string>
{
return new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "client_id", YConstants.ClientId },
{ "client_secret", YConstants.ClientSecret },
{ "grant_type", "x-token" },
{ "access_token", storage.AccessToken.AccessToken }
});
}
{ "client_id", YConstants.ClientId },
{ "client_secret", YConstants.ClientSecret },
{ "grant_type", "x-token" },
{ "access_token", storage.AccessToken.AccessToken }
});
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Remove("Authorization");
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Remove("Authorization");
base.SetCustomHeaders(headers);
}
base.SetCustomHeaders(headers);
}
}

View File

@@ -7,25 +7,24 @@ using YandexMusic.API.Models.Account;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Account
namespace YandexMusic.API.Requests.Account;
[YMobileProxyRequest(WebRequestMethods.Http.Get, "/1/bundle/account/short_info/")]
internal class YGetShortAccountInifoBuilder : YRequestBuilder<YShortAccountInfo, object>
{
[YMobileProxyRequest(WebRequestMethods.Http.Get, "/1/bundle/account/short_info/")]
internal class YGetShortAccountInifoBuilder : YRequestBuilder<YShortAccountInfo, object>
public YGetShortAccountInifoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetShortAccountInifoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override NameValueCollection GetQueryParams(object tuple)
{
return new NameValueCollection {
{ "avatar_size", "islands-300" }
};
}
protected override NameValueCollection GetQueryParams(object tuple)
{
return new NameValueCollection {
{ "avatar_size", "islands-300" }
};
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("Ya-Consumer-Authorization", $"OAuth {storage.AccessToken.AccessToken}");
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("Ya-Consumer-Authorization", $"OAuth {storage.AccessToken.AccessToken}");
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Album
{
[YApiRequest(WebRequestMethods.Http.Get, "albums/{albumId}/with-tracks")]
public class YGetAlbumBuilder : YRequestBuilder<YResponse<YAlbum>, string>
{
public YGetAlbumBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Album;
protected override Dictionary<string, string> GetSubstitutions(string albumId)
{
return new Dictionary<string, string> {
{ "albumId", albumId }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "albums/{albumId}/with-tracks")]
public class YGetAlbumBuilder : YRequestBuilder<YResponse<YAlbum>, string>
{
public YGetAlbumBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(string albumId)
{
return new Dictionary<string, string> {
{ "albumId", albumId }
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Album
{
[YApiRequest(WebRequestMethods.Http.Post, "albums")]
public class YGetAlbumsBuilder : YRequestBuilder<YResponse<List<YAlbum>>, IEnumerable<string>>
{
public YGetAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Album;
protected override HttpContent GetContent(IEnumerable<string> albumIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "album-ids", string.Join(",", albumIds) }
});
}
[YApiRequest(WebRequestMethods.Http.Post, "albums")]
public class YGetAlbumsBuilder : YRequestBuilder<YResponse<List<YAlbum>>, IEnumerable<string>>
{
public YGetAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(IEnumerable<string> albumIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "album-ids", string.Join(",", albumIds) }
});
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Artist
{
[YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/brief-info")]
public class YGetArtistBuilder : YRequestBuilder<YResponse<YArtistBriefInfo>, string>
{
public YGetArtistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Artist;
protected override Dictionary<string, string> GetSubstitutions(string artistId)
{
return new Dictionary<string, string> {
{ "artistId", artistId }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/brief-info")]
public class YGetArtistBuilder : YRequestBuilder<YResponse<YArtistBriefInfo>, string>
{
public YGetArtistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(string artistId)
{
return new Dictionary<string, string> {
{ "artistId", artistId }
};
}
}

View File

@@ -7,26 +7,25 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Artist
namespace YandexMusic.API.Requests.Artist;
[YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/tracks")]
public class YGetArtistTrackBuilder : YRequestBuilder<YResponse<YTracksPage>, (string id, int page, int pageSize)>
{
[YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/tracks")]
public class YGetArtistTrackBuilder : YRequestBuilder<YResponse<YTracksPage>, (string id, int page, int pageSize)>
public YGetArtistTrackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { }
protected override Dictionary<string, string> GetSubstitutions((string id, int page, int pageSize) tuple)
{
public YGetArtistTrackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { }
return new Dictionary<string, string> {
{ "artistId", tuple.id },
};
}
protected override Dictionary<string, string> GetSubstitutions((string id, int page, int pageSize) tuple)
{
return new Dictionary<string, string> {
{ "artistId", tuple.id },
};
}
protected override NameValueCollection GetQueryParams((string id, int page, int pageSize) tuple)
{
return new NameValueCollection {
{ "page", tuple.page.ToString() },
{ "pageSize", tuple.pageSize.ToString() },
};
}
protected override NameValueCollection GetQueryParams((string id, int page, int pageSize) tuple)
{
return new NameValueCollection {
{ "page", tuple.page.ToString() },
{ "pageSize", tuple.pageSize.ToString() },
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Artist
{
[YApiRequest(WebRequestMethods.Http.Post, "artists")]
public class YGetArtistsBuilder : YRequestBuilder<YResponse<List<YArtist>>, IEnumerable<string>>
{
public YGetArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Artist;
protected override HttpContent GetContent(IEnumerable<string> artistIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "artist-Ids", string.Join(",", artistIds) }
});
}
[YApiRequest(WebRequestMethods.Http.Post, "artists")]
public class YGetArtistsBuilder : YRequestBuilder<YResponse<List<YArtist>>, IEnumerable<string>>
{
public YGetArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(IEnumerable<string> artistIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "artist-Ids", string.Join(",", artistIds) }
});
}
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
public class YApiRequestAttribute : YBasePathRequestAttribute
{
public class YApiRequestAttribute : YBasePathRequestAttribute
public YApiRequestAttribute(string method, string url) : base(method, url)
{
public YApiRequestAttribute(string method, string url) : base(method, url)
{
basePath = "https://api.music.yandex.net";
}
basePath = "https://api.music.yandex.net";
}
}

View File

@@ -1,32 +1,31 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
/// <summary>
/// Атрибут запроса относительно базового адреса
/// </summary>
public class YBasePathRequestAttribute : YRequestAttribute
{
/// <summary>
/// Атрибут запроса относительно базового адреса
/// </summary>
public class YBasePathRequestAttribute : YRequestAttribute
#region Поля
protected string basePath;
#endregion Поля
#region Свойства
public override string Url => GetFullUrl();
#endregion Свойства
#region Вспомогательные функции
private string GetFullUrl()
{
#region Поля
return $"{basePath.TrimEnd('/')}/{path.TrimStart('/')}";
}
protected string basePath;
#endregion Вспомогательные функции
#endregion Поля
#region Свойства
public override string Url => GetFullUrl();
#endregion Свойства
#region Вспомогательные функции
private string GetFullUrl()
{
return $"{basePath.TrimEnd('/')}/{path.TrimStart('/')}";
}
#endregion Вспомогательные функции
public YBasePathRequestAttribute(string method, string url) : base(method, url)
{
}
public YBasePathRequestAttribute(string method, string url) : base(method, url)
{
}
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
public class YLoginRequestAttribute : YBasePathRequestAttribute
{
public class YLoginRequestAttribute : YBasePathRequestAttribute
public YLoginRequestAttribute(string method, string url) : base(method, url)
{
public YLoginRequestAttribute(string method, string url) : base(method, url)
{
basePath = "https://login.yandex.ru";
}
basePath = "https://login.yandex.ru";
}
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
public class YMobileProxyRequestAttribute : YBasePathRequestAttribute
{
public class YMobileProxyRequestAttribute : YBasePathRequestAttribute
public YMobileProxyRequestAttribute(string method, string url) : base(method, url)
{
public YMobileProxyRequestAttribute(string method, string url) : base(method, url)
{
basePath = "https://mobileproxy.passport.yandex.net";
}
basePath = "https://mobileproxy.passport.yandex.net";
}
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
public class YOAuthMobileAttribute : YBasePathRequestAttribute
{
public class YOAuthMobileAttribute : YBasePathRequestAttribute
public YOAuthMobileAttribute(string method, string url) : base(method, url)
{
public YOAuthMobileAttribute(string method, string url) : base(method, url)
{
basePath = "https://oauth.mobile.yandex.net";
}
basePath = "https://oauth.mobile.yandex.net";
}
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
public class YOAuthRequestAttribute : YBasePathRequestAttribute
{
public class YOAuthRequestAttribute : YBasePathRequestAttribute
public YOAuthRequestAttribute(string method, string url) : base(method, url)
{
public YOAuthRequestAttribute(string method, string url) : base(method, url)
{
basePath = "https://oauth.yandex.ru";
}
basePath = "https://oauth.yandex.ru";
}
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
public class YPassportRequestAttribute : YBasePathRequestAttribute
{
public class YPassportRequestAttribute : YBasePathRequestAttribute
public YPassportRequestAttribute(string method, string url) : base(method, url)
{
public YPassportRequestAttribute(string method, string url) : base(method, url)
{
basePath = "https://passport.yandex.ru";
}
basePath = "https://passport.yandex.ru";
}
}

View File

@@ -1,27 +1,26 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
/// <summary>
/// Атрибут запроса без привязки к базовому адресу
/// </summary>
public class YRequestAttribute : Attribute
{
/// <summary>
/// Атрибут запроса без привязки к базовому адресу
/// </summary>
public class YRequestAttribute : Attribute
#region Поля
protected string path;
#endregion Поля
#region Свойства
public string Method { get; }
public virtual string Url => path;
#endregion Свойства
public YRequestAttribute(string method, string url)
{
#region Поля
protected string path;
#endregion Поля
#region Свойства
public string Method { get; }
public virtual string Url => path;
#endregion Свойства
public YRequestAttribute(string method, string url)
{
Method = method;
path = url;
}
Method = method;
path = url;
}
}

View File

@@ -1,10 +1,9 @@
namespace YandexMusic.API.Requests.Common.Attributes
namespace YandexMusic.API.Requests.Common.Attributes;
public class YWebApiRequestAttribute : YBasePathRequestAttribute
{
public class YWebApiRequestAttribute : YBasePathRequestAttribute
public YWebApiRequestAttribute(string method, string url) : base(method, url)
{
public YWebApiRequestAttribute(string method, string url) : base(method, url)
{
basePath = "https://music.yandex.ru";
}
basePath = "https://music.yandex.ru";
}
}

View File

@@ -1,26 +1,25 @@
using System.Net;
namespace YandexMusic.API.Requests.Common
namespace YandexMusic.API.Requests.Common;
public class HttpContext
{
public class HttpContext
public CookieContainer Cookies;
public HttpContext()
{
public CookieContainer Cookies;
Cookies = new CookieContainer();
}
public HttpContext()
{
Cookies = new CookieContainer();
}
public IWebProxy WebProxy { get; set; }
public IWebProxy WebProxy { get; set; }
public long GetTimeInterval()
{
DateTime dt = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now);
DateTime dt1970 = new(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan tsInterval = dt.Subtract(dt1970);
long iMilliseconds = Convert.ToInt64(tsInterval.TotalMilliseconds);
public long GetTimeInterval()
{
DateTime dt = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now);
DateTime dt1970 = new(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan tsInterval = dt.Subtract(dt1970);
long iMilliseconds = Convert.ToInt64(tsInterval.TotalMilliseconds);
return iMilliseconds;
}
return iMilliseconds;
}
}

View File

@@ -1,11 +1,10 @@
namespace YandexMusic.API.Requests.Common
{
internal class YConstants
{
public static string ClientId = "23cabbbdc6cd418abb4b39c32c41195d";
public static string ClientSecret = "53bc75238f0c4d08a118e51fe9203300";
namespace YandexMusic.API.Requests.Common;
public const string XClientId = "c0ebe342af7d48fbbbfcf2d2eedb8f9e";
public const string XClientSecret = "ad0a908f0aa341a182a37ecd75bc319e";
}
internal class YConstants
{
public static string ClientId = "23cabbbdc6cd418abb4b39c32c41195d";
public static string ClientSecret = "53bc75238f0c4d08a118e51fe9203300";
public const string XClientId = "c0ebe342af7d48fbbbfcf2d2eedb8f9e";
public const string XClientSecret = "ad0a908f0aa341a182a37ecd75bc319e";
}

View File

@@ -1,48 +1,45 @@
using YandexMusic.API.Common;
using YandexMusic.API.Common.Providers;
namespace YandexMusic.API.Requests.Common
namespace YandexMusic.API.Requests.Common;
internal class YRequest<T>
{
internal class YRequest<T>
#region Поля
private HttpRequestMessage msg;
private IRequestProvider provider;
protected YandexMusicApi api;
#endregion Поля
public YRequest(HttpRequestMessage message, YandexMusicApi yandex, AuthStorage auth)
{
#region Поля
private HttpRequestMessage msg;
private IRequestProvider provider;
protected YandexMusicApi api;
#endregion Поля
public YRequest(HttpRequestMessage message, YandexMusicApi yandex, AuthStorage auth)
{
msg = message;
api = yandex;
provider = auth.Provider;
}
public async Task<T> GetResponseAsync()
{
if (msg == null)
return default;
HttpResponseMessage response = await provider.GetWebResponseAsync(msg);
if (typeof(T) == typeof(HttpResponseMessage))
return (T)(object)response;
try
{
return await provider.GetDataFromResponseAsync<T>(api, response);
}
finally
{
response.Dispose();
}
}
msg = message;
api = yandex;
provider = auth.Provider;
}
public async Task<T> GetResponseAsync()
{
if (msg == null)
return default;
HttpResponseMessage response = await provider.GetWebResponseAsync(msg);
if (typeof(T) == typeof(HttpResponseMessage))
return (T)(object)response;
try
{
return await provider.GetDataFromResponseAsync<T>(api, response);
}
finally
{
response.Dispose();
}
}
}

View File

@@ -3,156 +3,95 @@ using System.Net;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Web;
using YandexMusic.API.Common;
using YandexMusic.API.Extensions;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Common
namespace YandexMusic.API.Requests.Common;
/// <summary>Базовый строитель HTTP-запросов к API Яндекс.Музыки.</summary>
/// <typeparam name="TResponse">Тип ответа.</typeparam>
/// <typeparam name="TParams">Тип параметров запроса.</typeparam>
public abstract class YRequestBuilder<TResponse, TParams>
{
public class YRequestBuilder<ResponseType, ParamsTuple>
private readonly YRequestAttribute _requestInfo;
private Dictionary<string, string> _substitutions = null!;
private readonly JsonSerializerOptions _jsonOptions;
protected readonly YandexMusicApi api;
protected readonly AuthStorage storage;
protected string device;
protected YRequestBuilder(YandexMusicApi yandex, AuthStorage auth)
{
#region Поля
_requestInfo = GetType().GetCustomAttribute<YRequestAttribute>()
?? throw new NotImplementedException($"Отсутствует атрибут {nameof(YRequestAttribute)}");
api = yandex;
storage = auth;
device = $"os=CSharp; os_version=; manufacturer=K1llM@n; model=Yandex Music API; clid=; device_id={storage.DeviceId}; uuid=random";
private readonly JsonSerializerSettings jsonSettings = new()
_jsonOptions = new JsonSerializerOptions
{
Converters = new List<JsonConverter> {
new StringEnumConverter {
NamingStrategy = new CamelCaseNamingStrategy()
}
},
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }
};
private YRequestAttribute requestInfo;
private Dictionary<string, string> subs;
protected YandexMusicApi api;
protected AuthStorage storage;
protected string device;
#endregion Поля
#region Свойства
protected YandexMusicApi API => api;
protected AuthStorage Storage => storage;
#endregion Свойства
#region Вспомогательные функции
private Uri BuildUri(ParamsTuple tuple)
{
NameValueCollection queryParams = GetQueryParams(tuple);
NameValueCollection modifiedParams = HttpUtility.ParseQueryString(string.Empty);
// Подстановка в параметры
foreach (string key in queryParams.Keys)
{
modifiedParams.Set(key, ReplaceSubs(queryParams.Get(key)));
}
string endpoint = ReplaceSubs(requestInfo.Url);
UriBuilder builder = new(endpoint)
{
Query = modifiedParams.ToString() ?? string.Empty
};
return builder.Uri;
}
private HttpRequestMessage CreateMessage(ParamsTuple tuple)
{
HttpRequestMessage msg = new()
{
RequestUri = BuildUri(tuple),
Method = new HttpMethod(requestInfo.Method),
Content = GetContent(tuple)
};
msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptCharset.GetName(), Encoding.UTF8.WebName);
msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptEncoding.GetName(), "gzip");
// Добавление заголовка авторизации
if (!string.IsNullOrEmpty(storage.Token))
msg.Headers.TryAddWithoutValidation(HttpRequestHeader.Authorization.GetName(), $"OAuth {storage.Token}");
SetCustomHeaders(msg.Headers);
return msg;
}
protected string ReplaceSubs(string str)
{
string[] sub = str.GetMatches(@"\{.+?\}");
foreach (string s in sub)
{
if (!subs.TryGetValue(s.ReplaceRegex(@"[\{\}]", string.Empty), out string value))
throw new Exception($"Не найдена подстановка {s}");
str = str.Replace(s, value);
}
return str;
}
protected virtual Dictionary<string, string> GetSubstitutions(ParamsTuple tuple)
{
return new Dictionary<string, string>();
}
protected virtual NameValueCollection GetQueryParams(ParamsTuple tuple)
{
return new NameValueCollection();
}
protected virtual HttpContent GetContent(ParamsTuple tuple)
{
return null;
}
protected virtual void SetCustomHeaders(HttpRequestHeaders headers)
{
}
protected string SerializeJson(object data)
{
return JsonConvert.SerializeObject(data, jsonSettings);
}
#endregion Вспомогательные функции
public YRequestBuilder(YandexMusicApi yandex, AuthStorage auth)
{
requestInfo = GetType()
.GetCustomAttributes<YRequestAttribute>()
.FirstOrDefault();
if (requestInfo == null)
throw new NotImplementedException($"Отсутствует атрибут {nameof(YRequestAttribute)}");
api = yandex;
storage = auth;
// Устройство по умолчанию
device = $"os=CSharp; os_version=; manufacturer=K1llM@n; model=Yandex Music API; clid=; device_id={storage.DeviceId}; uuid=random";
}
internal YRequest<ResponseType> Build(ParamsTuple tuple)
{
subs = GetSubstitutions(tuple);
HttpRequestMessage msg = CreateMessage(tuple);
return new YRequest<ResponseType>(msg, api, storage);
}
}
}
private Uri BuildUri(TParams tuple)
{
var queryParams = GetQueryParams(tuple);
var modifiedParams = HttpUtility.ParseQueryString(string.Empty);
foreach (string? key in queryParams)
if (key != null)
modifiedParams[key] = ReplaceSubs(queryParams[key]!);
var endpoint = ReplaceSubs(_requestInfo.Url);
var builder = new UriBuilder(endpoint) { Query = modifiedParams.ToString() ?? string.Empty };
return builder.Uri;
}
private HttpRequestMessage CreateMessage(TParams tuple)
{
var msg = new HttpRequestMessage
{
RequestUri = BuildUri(tuple),
Method = new HttpMethod(_requestInfo.Method),
Content = GetContent(tuple)
};
msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptCharset.GetName(), Encoding.UTF8.WebName);
msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptEncoding.GetName(), "gzip");
if (!string.IsNullOrEmpty(storage.Token))
msg.Headers.TryAddWithoutValidation(HttpRequestHeader.Authorization.GetName(), $"OAuth {storage.Token}");
SetCustomHeaders(msg.Headers);
return msg;
}
protected string ReplaceSubs(string str)
{
var subs = str.GetMatches(@"\{.+?\}");
foreach (var s in subs)
{
var key = s.ReplaceRegex(@"[\{\}]", string.Empty);
if (!_substitutions.TryGetValue(key, out var value))
throw new Exception($"Не найдена подстановка {s}");
str = str.Replace(s, value);
}
return str;
}
protected virtual Dictionary<string, string> GetSubstitutions(TParams tuple) => [];
protected virtual NameValueCollection GetQueryParams(TParams tuple) => [];
protected virtual HttpContent? GetContent(TParams tuple) => null;
protected virtual void SetCustomHeaders(HttpRequestHeaders headers) { }
protected string SerializeJson(object data) => JsonSerializer.Serialize(data, _jsonOptions);
internal YRequest<TResponse> Build(TParams tuple)
{
_substitutions = GetSubstitutions(tuple);
var msg = CreateMessage(tuple);
return new YRequest<TResponse>(msg, api, storage);
}
}

View File

@@ -6,13 +6,12 @@ using YandexMusic.API.Models.Feed;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Feed
namespace YandexMusic.API.Requests.Feed;
[YApiRequest(WebRequestMethods.Http.Get, "feed")]
public class YGetFeedBuilder : YRequestBuilder<YResponse<YFeed>, object>
{
[YApiRequest(WebRequestMethods.Http.Get, "feed")]
public class YGetFeedBuilder : YRequestBuilder<YResponse<YFeed>, object>
public YGetFeedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetFeedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
}

View File

@@ -7,27 +7,26 @@ using YandexMusic.API.Models.Label;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Label
namespace YandexMusic.API.Requests.Label;
[YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/albums")]
public class YGetLabelAlbumsBuilder : YRequestBuilder<YResponse<YLabelAlbums>, (YLabel label, int pageNumber)>
{
[YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/albums")]
public class YGetLabelAlbumsBuilder : YRequestBuilder<YResponse<YLabelAlbums>, (YLabel label, int pageNumber)>
public YGetLabelAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetLabelAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple)
{
return new NameValueCollection {
{ "page", tuple.pageNumber.ToString() }
};
}
protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple)
{
return new NameValueCollection {
{ "page", tuple.pageNumber.ToString() }
};
}
protected override Dictionary<string, string> GetSubstitutions((YLabel label, int pageNumber) tuple)
{
return new Dictionary<string, string> {
{ "labelId", tuple.label.Id }
};
}
protected override Dictionary<string, string> GetSubstitutions((YLabel label, int pageNumber) tuple)
{
return new Dictionary<string, string> {
{ "labelId", tuple.label.Id }
};
}
}

View File

@@ -7,27 +7,26 @@ using YandexMusic.API.Models.Label;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Label
namespace YandexMusic.API.Requests.Label;
[YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/artists")]
public class YGetLabelArtistsBuilder : YRequestBuilder<YResponse<YLabelArtists>, (YLabel label, int pageNumber)>
{
[YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/artists")]
public class YGetLabelArtistsBuilder : YRequestBuilder<YResponse<YLabelArtists>, (YLabel label, int pageNumber)>
public YGetLabelArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetLabelArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple)
{
return new NameValueCollection {
{ "page", tuple.pageNumber.ToString() }
};
}
protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple)
{
return new NameValueCollection {
{ "page", tuple.pageNumber.ToString() }
};
}
protected override Dictionary<string, string> GetSubstitutions((YLabel label, int pageNumber) tuple)
{
return new Dictionary<string, string> {
{ "labelId", tuple.label.Id }
};
}
protected override Dictionary<string, string> GetSubstitutions((YLabel label, int pageNumber) tuple)
{
return new Dictionary<string, string> {
{ "labelId", tuple.label.Id }
};
}
}

View File

@@ -6,13 +6,12 @@ using YandexMusic.API.Models.Landing;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Landing
namespace YandexMusic.API.Requests.Landing;
[YApiRequest(WebRequestMethods.Http.Get, "children-landing/catalogue")]
public class YGetChildrenLandingBuilder : YRequestBuilder<YResponse<YChildrenLanding>, object>
{
[YApiRequest(WebRequestMethods.Http.Get, "children-landing/catalogue")]
public class YGetChildrenLandingBuilder : YRequestBuilder<YResponse<YChildrenLanding>, object>
public YGetChildrenLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetChildrenLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
}

View File

@@ -7,23 +7,22 @@ using YandexMusic.API.Models.Landing;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Landing
namespace YandexMusic.API.Requests.Landing;
[YApiRequest(WebRequestMethods.Http.Get, "landing3")]
public class YGetLandingBuilder : YRequestBuilder<YResponse<YLanding>, YLandingBlockType[]>
{
[YApiRequest(WebRequestMethods.Http.Get, "landing3")]
public class YGetLandingBuilder : YRequestBuilder<YResponse<YLanding>, YLandingBlockType[]>
public YGetLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override NameValueCollection GetQueryParams(YLandingBlockType[] tuple)
{
string blocks = string.Join(",", tuple
.Select(b => SerializeJson(b).Replace("\"", string.Empty)));
protected override NameValueCollection GetQueryParams(YLandingBlockType[] tuple)
{
string blocks = string.Join(",", tuple
.Select(b => SerializeJson(b).Replace("\"", string.Empty)));
return new NameValueCollection {
{ "blocks", blocks }
};
}
return new NameValueCollection {
{ "blocks", blocks }
};
}
}

View File

@@ -8,30 +8,29 @@ using YandexMusic.API.Models.Library;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Library
namespace YandexMusic.API.Requests.Library;
[YApiRequest(WebRequestMethods.Http.Get, "/users/{uid}/contexts")]
public class YGetLibraryRecentlyListenedBuilder : YRequestBuilder<YResponse<YRecentlyListenedContext>,
(IEnumerable<YPlayContextType> contextTypes, int trackCount, int contextCount)>
{
[YApiRequest(WebRequestMethods.Http.Get, "/users/{uid}/contexts")]
public class YGetLibraryRecentlyListenedBuilder : YRequestBuilder<YResponse<YRecentlyListenedContext>,
(IEnumerable<YPlayContextType> contextTypes, int trackCount, int contextCount)>
public YGetLibraryRecentlyListenedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetLibraryRecentlyListenedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override NameValueCollection GetQueryParams((IEnumerable<YPlayContextType> contextTypes, int trackCount, int contextCount) tuple)
{
return new NameValueCollection {
{ "trackCount", tuple.trackCount.ToString() },
{ "contextCount", tuple.contextCount.ToString() },
{ "types", string.Join(",", tuple.contextTypes.Select(x => x.ToString().ToLowerInvariant())) }
};
}
protected override NameValueCollection GetQueryParams((IEnumerable<YPlayContextType> contextTypes, int trackCount, int contextCount) tuple)
{
return new NameValueCollection {
{ "trackCount", tuple.trackCount.ToString() },
{ "contextCount", tuple.contextCount.ToString() },
{ "types", string.Join(",", tuple.contextTypes.Select(x => x.ToString().ToLowerInvariant())) }
};
}
protected override Dictionary<string, string> GetSubstitutions((IEnumerable<YPlayContextType> contextTypes, int trackCount, int contextCount) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid }
};
}
protected override Dictionary<string, string> GetSubstitutions((IEnumerable<YPlayContextType> contextTypes, int trackCount, int contextCount) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid }
};
}
}

View File

@@ -6,22 +6,21 @@ using YandexMusic.API.Models.Library;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Library
{
[YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/{type}/{section}")]
public class YGetLibrarySectionBuilder<T> : YRequestBuilder<YResponse<T>, (YLibrarySection section, YLibrarySectionType type)>
{
public YGetLibrarySectionBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Library;
protected override Dictionary<string, string> GetSubstitutions((YLibrarySection section, YLibrarySectionType type) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "type", tuple.type.ToString().ToLower() },
{ "section", tuple.section.ToString().ToLower() },
};
}
[YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/{type}/{section}")]
public class YGetLibrarySectionBuilder<T> : YRequestBuilder<YResponse<T>, (YLibrarySection section, YLibrarySectionType type)>
{
public YGetLibrarySectionBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions((YLibrarySection section, YLibrarySectionType type) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "type", tuple.type.ToString().ToLower() },
{ "section", tuple.section.ToString().ToLower() },
};
}
}

View File

@@ -6,29 +6,28 @@ using YandexMusic.API.Models.Library;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Library
namespace YandexMusic.API.Requests.Library;
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/add-multiple")]
public class YLibraryAddBuilder<T> : YRequestBuilder<YResponse<T>, (string id, YLibrarySection section, YLibrarySectionType type)>
{
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/add-multiple")]
public class YLibraryAddBuilder<T> : YRequestBuilder<YResponse<T>, (string id, YLibrarySection section, YLibrarySectionType type)>
public YLibraryAddBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YLibraryAddBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "type", tuple.type.ToString().ToLower() },
{ "section", tuple.section.ToString().ToLower() },
};
}
protected override Dictionary<string, string> GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "type", tuple.type.ToString().ToLower() },
{ "section", tuple.section.ToString().ToLower() },
};
}
protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id }
});
}
protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id }
});
}
}

View File

@@ -6,29 +6,28 @@ using YandexMusic.API.Models.Library;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Library
namespace YandexMusic.API.Requests.Library;
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/remove")]
public class YLibraryRemoveBuilder<T> : YRequestBuilder<YResponse<T>, (string id, YLibrarySection section, YLibrarySectionType type)>
{
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/remove")]
public class YLibraryRemoveBuilder<T> : YRequestBuilder<YResponse<T>, (string id, YLibrarySection section, YLibrarySectionType type)>
public YLibraryRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YLibraryRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "type", tuple.type.ToString().ToLower() },
{ "section", tuple.section.ToString().ToLower() },
};
}
protected override Dictionary<string, string> GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "type", tuple.type.ToString().ToLower() },
{ "section", tuple.section.ToString().ToLower() },
};
}
protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id }
});
}
protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id }
});
}
}

View File

@@ -6,13 +6,12 @@ using YandexMusic.API.Models.Pins;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Pins
namespace YandexMusic.API.Requests.Pins;
[YApiRequest(WebRequestMethods.Http.Get, "pins")]
public class YGetPinsBuilder : YRequestBuilder<YResponse<YPins>, object>
{
[YApiRequest(WebRequestMethods.Http.Get, "pins")]
public class YGetPinsBuilder : YRequestBuilder<YResponse<YPins>, object>
public YGetPinsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetPinsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
}

View File

@@ -6,21 +6,20 @@ using YandexMusic.API.Models.Playlist;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
{
[YApiRequest(WebRequestMethods.Http.Get, "users/{user}/playlists/{kind}")]
public class YGetPlaylistBuilder : YRequestBuilder<YResponse<YPlaylist>, (string user, string kind)>
{
public YGetPlaylistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Playlist;
protected override Dictionary<string, string> GetSubstitutions((string user, string kind) tuple)
{
return new Dictionary<string, string> {
{ "user", tuple.user },
{ "kind", tuple.kind },
};
}
[YApiRequest(WebRequestMethods.Http.Get, "users/{user}/playlists/{kind}")]
public class YGetPlaylistBuilder : YRequestBuilder<YResponse<YPlaylist>, (string user, string kind)>
{
public YGetPlaylistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions((string user, string kind) tuple)
{
return new Dictionary<string, string> {
{ "user", tuple.user },
{ "kind", tuple.kind },
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Playlist;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
{
[YApiRequest(WebRequestMethods.Http.Get, "playlist/{uuid}")]
public class YGetPlaylistByUuidBuilder : YRequestBuilder<YResponse<YPlaylist>, string>
{
public YGetPlaylistByUuidBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Playlist;
protected override Dictionary<string, string> GetSubstitutions(string uuid)
{
return new Dictionary<string, string> {
{ "uuid", uuid },
};
}
[YApiRequest(WebRequestMethods.Http.Get, "playlist/{uuid}")]
public class YGetPlaylistByUuidBuilder : YRequestBuilder<YResponse<YPlaylist>, string>
{
public YGetPlaylistByUuidBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(string uuid)
{
return new Dictionary<string, string> {
{ "uuid", uuid },
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Playlist;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
{
[YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/playlists/list")]
public class YGetPlaylistFavoritesBuilder : YRequestBuilder<YResponse<List<YPlaylist>>, object>
{
public YGetPlaylistFavoritesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Playlist;
protected override Dictionary<string, string> GetSubstitutions(object tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/playlists/list")]
public class YGetPlaylistFavoritesBuilder : YRequestBuilder<YResponse<List<YPlaylist>>, object>
{
public YGetPlaylistFavoritesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(object tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid }
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Playlist;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
{
[YApiRequest(WebRequestMethods.Http.Post, "playlists/list")]
public class YGetPlaylistsBuilder : YRequestBuilder<YResponse<List<YPlaylist>>, IEnumerable<(string User, string Kind)>>
{
public YGetPlaylistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Playlist;
protected override HttpContent GetContent(IEnumerable<(string User, string Kind)> playlistIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "playlist-Ids", string.Join(",", playlistIds.Select(t => $"{t.User}:{t.Kind}")) }
});
}
[YApiRequest(WebRequestMethods.Http.Post, "playlists/list")]
public class YGetPlaylistsBuilder : YRequestBuilder<YResponse<List<YPlaylist>>, IEnumerable<(string User, string Kind)>>
{
public YGetPlaylistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(IEnumerable<(string User, string Kind)> playlistIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "playlist-Ids", string.Join(",", playlistIds.Select(t => $"{t.User}:{t.Kind}")) }
});
}
}

View File

@@ -6,30 +6,29 @@ using YandexMusic.API.Models.Playlist;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
namespace YandexMusic.API.Requests.Playlist;
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/change")]
public class YPlaylistChangeBuilder : YRequestBuilder<YResponse<YPlaylist>, (YPlaylist playlist, IEnumerable<YPlaylistChange> changes)>
{
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/change")]
public class YPlaylistChangeBuilder : YRequestBuilder<YResponse<YPlaylist>, (YPlaylist playlist, IEnumerable<YPlaylistChange> changes)>
public YPlaylistChangeBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YPlaylistChangeBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions((YPlaylist playlist, IEnumerable<YPlaylistChange> changes) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "kind", tuple.playlist.Kind }
};
}
protected override Dictionary<string, string> GetSubstitutions((YPlaylist playlist, IEnumerable<YPlaylistChange> changes) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "kind", tuple.playlist.Kind }
};
}
protected override HttpContent GetContent((YPlaylist playlist, IEnumerable<YPlaylistChange> changes) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "kind", tuple.playlist.Kind },
{ "revision", tuple.playlist.Revision.ToString() },
{ "diff", SerializeJson(tuple.changes) }
});
}
protected override HttpContent GetContent((YPlaylist playlist, IEnumerable<YPlaylistChange> changes) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "kind", tuple.playlist.Kind },
{ "revision", tuple.playlist.Revision.ToString() },
{ "diff", SerializeJson(tuple.changes) }
});
}
}

View File

@@ -6,28 +6,27 @@ using YandexMusic.API.Models.Playlist;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
namespace YandexMusic.API.Requests.Playlist;
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/create")]
public class YPlaylistCreateBuilder : YRequestBuilder<YResponse<YPlaylist>, string>
{
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/create")]
public class YPlaylistCreateBuilder : YRequestBuilder<YResponse<YPlaylist>, string>
public YPlaylistCreateBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YPlaylistCreateBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions(string name)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid }
};
}
protected override Dictionary<string, string> GetSubstitutions(string name)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid }
};
}
protected override HttpContent GetContent(string name)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "title", name },
{ "visibility", "public" }
});
}
protected override HttpContent GetContent(string name)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "title", name },
{ "visibility", "public" }
});
}
}

View File

@@ -6,28 +6,27 @@ using YandexMusic.API.Models.Playlist;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
namespace YandexMusic.API.Requests.Playlist;
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/name")]
public class YPlaylistRenameBuilder : YRequestBuilder<YResponse<YPlaylist>, (string kind, string name)>
{
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/name")]
public class YPlaylistRenameBuilder : YRequestBuilder<YResponse<YPlaylist>, (string kind, string name)>
public YPlaylistRenameBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YPlaylistRenameBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions((string kind, string name) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "kind", tuple.kind }
};
}
protected override Dictionary<string, string> GetSubstitutions((string kind, string name) tuple)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "kind", tuple.kind }
};
}
protected override HttpContent GetContent((string kind, string name) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "value", tuple.name }
});
}
protected override HttpContent GetContent((string kind, string name) tuple)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "value", tuple.name }
});
}
}

View File

@@ -4,21 +4,20 @@ using YandexMusic.API.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Playlist
{
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/delete")]
public class YPlaylistRemoveBuilder : YRequestBuilder<HttpResponseMessage, string>
{
public YPlaylistRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Playlist;
protected override Dictionary<string, string> GetSubstitutions(string kind)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "kind", kind }
};
}
[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/delete")]
public class YPlaylistRemoveBuilder : YRequestBuilder<HttpResponseMessage, string>
{
public YPlaylistRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(string kind)
{
return new Dictionary<string, string> {
{ "uid", storage.User.Uid },
{ "kind", kind }
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Queue;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Queue
{
[YApiRequest(WebRequestMethods.Http.Get, "queues/{queueId}")]
public class YGetQueueBuilder : YRequestBuilder<YResponse<YQueue>, string>
{
public YGetQueueBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Queue;
protected override Dictionary<string, string> GetSubstitutions(string queueId)
{
return new Dictionary<string, string> {
{ "queueId", queueId }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "queues/{queueId}")]
public class YGetQueueBuilder : YRequestBuilder<YResponse<YQueue>, string>
{
public YGetQueueBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(string queueId)
{
return new Dictionary<string, string> {
{ "queueId", queueId }
};
}
}

View File

@@ -11,34 +11,33 @@ using YandexMusic.API.Models.Queue;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Queue
namespace YandexMusic.API.Requests.Queue;
[YApiRequest(WebRequestMethods.Http.Post, "queues")]
public class YQueueCreateBuilder : YRequestBuilder<YResponse<YNewQueue>, YQueue>
{
[YApiRequest(WebRequestMethods.Http.Post, "queues")]
public class YQueueCreateBuilder : YRequestBuilder<YResponse<YNewQueue>, YQueue>
public YQueueCreateBuilder(YandexMusicApi yandex, AuthStorage auth, string? device = null) : base(yandex, auth)
{
public YQueueCreateBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth)
{
if (device != null)
this.device = device;
}
if (device != null)
this.device = device;
}
protected override HttpContent GetContent(YQueue queue)
protected override HttpContent GetContent(YQueue queue)
{
JsonSerializerOptions settings = new()
{
JsonSerializerOptions settings = new()
{
Converters = {
new JsonStringEnumConverter()
},
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
Converters = {
new JsonStringEnumConverter()
},
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
return JsonContent.Create(queue, new MediaTypeHeaderValue("application/json"), settings);
}
return JsonContent.Create(queue, new MediaTypeHeaderValue("application/json"), settings);
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Yandex-Music-Device", device);
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Yandex-Music-Device", device);
}
}

View File

@@ -8,35 +8,34 @@ using YandexMusic.API.Models.Queue;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Queue
namespace YandexMusic.API.Requests.Queue;
[YApiRequest(WebRequestMethods.Http.Post, "queues/{queueId}/update-position")]
public class YQueueUpdatePositionBuilder : YRequestBuilder<YResponse<YUpdatedQueue>, (string queueId, int currentIndex, bool isInteractive)>
{
[YApiRequest(WebRequestMethods.Http.Post, "queues/{queueId}/update-position")]
public class YQueueUpdatePositionBuilder : YRequestBuilder<YResponse<YUpdatedQueue>, (string queueId, int currentIndex, bool isInteractive)>
public YQueueUpdatePositionBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth)
{
public YQueueUpdatePositionBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth)
{
if (device != null)
this.device = device;
}
if (device != null)
this.device = device;
}
protected override Dictionary<string, string> GetSubstitutions((string queueId, int currentIndex, bool isInteractive) tuple)
{
return new Dictionary<string, string> {
{ "queueId", tuple.queueId },
};
}
protected override Dictionary<string, string> GetSubstitutions((string queueId, int currentIndex, bool isInteractive) tuple)
{
return new Dictionary<string, string> {
{ "queueId", tuple.queueId },
};
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Yandex-Music-Device", device);
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Yandex-Music-Device", device);
}
protected override NameValueCollection GetQueryParams((string queueId, int currentIndex, bool isInteractive) tuple)
{
return new NameValueCollection {
{ "currentIndex", tuple.currentIndex.ToString() },
{ "isInteractive", tuple.isInteractive.ToString().ToLower() }
};
}
protected override NameValueCollection GetQueryParams((string queueId, int currentIndex, bool isInteractive) tuple)
{
return new NameValueCollection {
{ "currentIndex", tuple.currentIndex.ToString() },
{ "isInteractive", tuple.isInteractive.ToString().ToLower() }
};
}
}

View File

@@ -7,20 +7,19 @@ using YandexMusic.API.Models.Queue;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Queue
{
[YApiRequest(WebRequestMethods.Http.Get, "queues")]
public class YQueuesListBuilder : YRequestBuilder<YResponse<YQueueItemsContainer>, string>
{
public YQueuesListBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth)
{
if (device != null)
this.device = device;
}
namespace YandexMusic.API.Requests.Queue;
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Yandex-Music-Device", device);
}
[YApiRequest(WebRequestMethods.Http.Get, "queues")]
public class YQueuesListBuilder : YRequestBuilder<YResponse<YQueueItemsContainer>, string>
{
public YQueuesListBuilder(YandexMusicApi yandex, AuthStorage auth, string? device = null) : base(yandex, auth)
{
if (device != null)
this.device = device;
}
protected override void SetCustomHeaders(HttpRequestHeaders headers)
{
headers.Add("X-Yandex-Music-Device", device);
}
}

View File

@@ -6,21 +6,20 @@ using YandexMusic.API.Models.Radio;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Radio
{
[YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/info")]
public class YGetStationBuilder : YRequestBuilder<YResponse<List<YStation>>, (string type, string tag)>
{
public YGetStationBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Radio;
protected override Dictionary<string, string> GetSubstitutions((string type, string tag) tuple)
{
return new Dictionary<string, string> {
{ "type", tuple.type },
{ "tag", tuple.tag }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/info")]
public class YGetStationBuilder : YRequestBuilder<YResponse<List<YStation>>, (string type, string tag)>
{
public YGetStationBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions((string type, string tag) tuple)
{
return new Dictionary<string, string> {
{ "type", tuple.type },
{ "tag", tuple.tag }
};
}
}

View File

@@ -7,33 +7,32 @@ using YandexMusic.API.Models.Radio;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Radio
namespace YandexMusic.API.Requests.Radio;
[YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/tracks")]
public class YGetStationTracksBuilder : YRequestBuilder<YResponse<YStationSequence>, (YStationDescription station, string prevTrackId)>
{
[YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/tracks")]
public class YGetStationTracksBuilder : YRequestBuilder<YResponse<YStationSequence>, (YStationDescription station, string prevTrackId)>
public YGetStationTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetStationTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions((YStationDescription station, string prevTrackId) tuple)
{
return new Dictionary<string, string> {
{ "type", tuple.station.Id.Type },
{ "tag", tuple.station.Id.Tag },
};
}
protected override Dictionary<string, string> GetSubstitutions((YStationDescription station, string prevTrackId) tuple)
{
return new Dictionary<string, string> {
{ "type", tuple.station.Id.Type },
{ "tag", tuple.station.Id.Tag },
};
}
protected override NameValueCollection GetQueryParams((YStationDescription station, string prevTrackId) tuple)
{
NameValueCollection query = new() {
{ "settings2", "true" }
};
protected override NameValueCollection GetQueryParams((YStationDescription station, string prevTrackId) tuple)
{
NameValueCollection query = new() {
{ "settings2", "true" }
};
if (!string.IsNullOrEmpty(tuple.prevTrackId))
query.Add("queue", tuple.prevTrackId);
if (!string.IsNullOrEmpty(tuple.prevTrackId))
query.Add("queue", tuple.prevTrackId);
return base.GetQueryParams(tuple);
}
return base.GetQueryParams(tuple);
}
}

View File

@@ -6,13 +6,12 @@ using YandexMusic.API.Models.Radio;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Radio
namespace YandexMusic.API.Requests.Radio;
[YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/list")]
public class YGetStationsBuilder : YRequestBuilder<YResponse<List<YStation>>, object>
{
[YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/list")]
public class YGetStationsBuilder : YRequestBuilder<YResponse<List<YStation>>, object>
public YGetStationsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetStationsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
}

View File

@@ -6,13 +6,12 @@ using YandexMusic.API.Models.Radio;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Radio
namespace YandexMusic.API.Requests.Radio;
[YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/dashboard")]
public class YGetStationsDashboardBuilder : YRequestBuilder<YResponse<YStationsDashboard>, object>
{
[YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/dashboard")]
public class YGetStationsDashboardBuilder : YRequestBuilder<YResponse<YStationsDashboard>, object>
public YGetStationsDashboardBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YGetStationsDashboardBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
}

View File

@@ -11,36 +11,35 @@ using YandexMusic.API.Models.Radio;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Radio
namespace YandexMusic.API.Requests.Radio;
[YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/settings2")]
public class YSetSettings2Builder : YRequestBuilder<YResponse<string>, (YStationDescription station, YStationSettings2 settings2)>
{
[YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/settings2")]
public class YSetSettings2Builder : YRequestBuilder<YResponse<string>, (YStationDescription station, YStationSettings2 settings2)>
public YSetSettings2Builder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YSetSettings2Builder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions((YStationDescription station, YStationSettings2 settings2) tuple)
{
return new Dictionary<string, string> {
{ "type", tuple.station.Id.Type },
{ "tag", tuple.station.Id.Tag },
};
}
protected override Dictionary<string, string> GetSubstitutions((YStationDescription station, YStationSettings2 settings2) tuple)
{
return new Dictionary<string, string> {
{ "type", tuple.station.Id.Type },
{ "tag", tuple.station.Id.Tag },
};
}
protected override HttpContent GetContent((YStationDescription station, YStationSettings2 settings2) tuple)
protected override HttpContent GetContent((YStationDescription station, YStationSettings2 settings2) tuple)
{
JsonSerializerOptions settings = new()
{
JsonSerializerOptions settings = new()
{
Converters = {
new JsonStringEnumConverter()
},
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
Converters = {
new JsonStringEnumConverter()
},
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
return JsonContent.Create(tuple.settings2, new MediaTypeHeaderValue("application/json"), settings);
}
return JsonContent.Create(tuple.settings2, new MediaTypeHeaderValue("application/json"), settings);
}
}

View File

@@ -12,61 +12,60 @@ using YandexMusic.API.Models.Track;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Radio
namespace YandexMusic.API.Requests.Radio;
[YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/feedback")]
public class YSetStationFeedbackBuilder : YRequestBuilder<string, (YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds)>
{
[YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/feedback")]
public class YSetStationFeedbackBuilder : YRequestBuilder<string, (YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds)>
public YSetStationFeedbackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YSetStationFeedbackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
}
protected override Dictionary<string, string> GetSubstitutions((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple)
{
return new Dictionary<string, string> {
{ "type", tuple.station.Station.Id.Type },
{ "tag", tuple.station.Station.Id.Tag }
};
}
protected override HttpContent GetContent((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple)
{
long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
JsonSerializerOptions settings = new()
{
}
Converters = {
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
},
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};
protected override Dictionary<string, string> GetSubstitutions((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple)
YStationFeedback feedBack = new()
{
return new Dictionary<string, string> {
{ "type", tuple.station.Station.Id.Type },
{ "tag", tuple.station.Station.Id.Tag }
};
}
Type = tuple.type,
From = tuple.station.Station.IdForFrom,
Timestamp = timestamp
};
protected override HttpContent GetContent((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple)
{
long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
if (tuple.track != null)
feedBack.TrackId = tuple.track.Id;
JsonSerializerOptions settings = new()
{
Converters = {
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
},
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};
if (tuple.totalPlayedSeconds > 0)
feedBack.TotalPlayedSeconds = tuple.totalPlayedSeconds;
YStationFeedback feedBack = new()
{
Type = tuple.type,
From = tuple.station.Station.IdForFrom,
Timestamp = timestamp
};
return JsonContent.Create(feedBack, new MediaTypeHeaderValue("application/json"), settings); ;
}
if (tuple.track != null)
feedBack.TrackId = tuple.track.Id;
protected override NameValueCollection GetQueryParams((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple)
{
NameValueCollection query = new();
if (tuple.totalPlayedSeconds > 0)
feedBack.TotalPlayedSeconds = tuple.totalPlayedSeconds;
if (!string.IsNullOrWhiteSpace(tuple.batchId))
query.Add("batch-id", tuple.batchId);
return JsonContent.Create(feedBack, new MediaTypeHeaderValue("application/json"), settings); ;
}
protected override NameValueCollection GetQueryParams((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple)
{
NameValueCollection query = new();
if (!string.IsNullOrWhiteSpace(tuple.batchId))
query.Add("batch-id", tuple.batchId);
return query;
}
return query;
}
}

View File

@@ -7,23 +7,22 @@ using YandexMusic.API.Models.Search;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Search
{
[YApiRequest(WebRequestMethods.Http.Get, "search")]
public class YSearchBuilder : YRequestBuilder<YResponse<YSearch>, (string searchText, YSearchType searchType, int page, int pageSize)>
{
public YSearchBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Search;
protected override NameValueCollection GetQueryParams((string searchText, YSearchType searchType, int page, int pageSize) tuple)
{
return new NameValueCollection {
{ "text", tuple.searchText },
{ "type", tuple.searchType.ToString() },
{ "page", tuple.page.ToString() },
{ "pageSize", tuple.pageSize.ToString() }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "search")]
public class YSearchBuilder : YRequestBuilder<YResponse<YSearch>, (string searchText, YSearchType searchType, int page, int pageSize)>
{
public YSearchBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override NameValueCollection GetQueryParams((string searchText, YSearchType searchType, int page, int pageSize) tuple)
{
return new NameValueCollection {
{ "text", tuple.searchText },
{ "type", tuple.searchType.ToString() },
{ "page", tuple.page.ToString() },
{ "pageSize", tuple.pageSize.ToString() }
};
}
}

View File

@@ -7,20 +7,19 @@ using YandexMusic.API.Models.Search;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Search
{
[YApiRequest(WebRequestMethods.Http.Get, "search/suggest")]
public class YSearchSuggestBuilder : YRequestBuilder<YResponse<YSearchSuggest>, string>
{
public YSearchSuggestBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Search;
protected override NameValueCollection GetQueryParams(string searchText)
{
return new NameValueCollection {
{ "part", searchText }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "search/suggest")]
public class YSearchSuggestBuilder : YRequestBuilder<YResponse<YSearchSuggest>, string>
{
public YSearchSuggestBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override NameValueCollection GetQueryParams(string searchText)
{
return new NameValueCollection {
{ "part", searchText }
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Track;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Track
{
[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/similar")]
public class YGetTrackSimilarBuilder : YRequestBuilder<YResponse<YTrackSimilar>, string>
{
public YGetTrackSimilarBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Track;
protected override Dictionary<string, string> GetSubstitutions(string trackId)
{
return new Dictionary<string, string> {
{ "trackId", trackId }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/similar")]
public class YGetTrackSimilarBuilder : YRequestBuilder<YResponse<YTrackSimilar>, string>
{
public YGetTrackSimilarBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(string trackId)
{
return new Dictionary<string, string> {
{ "trackId", trackId }
};
}
}

View File

@@ -6,20 +6,19 @@ using YandexMusic.API.Models.Track;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Track
{
[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/supplement")]
public class YGetTrackSupplementBuilder : YRequestBuilder<YResponse<YTrackSupplement>, string>
{
public YGetTrackSupplementBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Track;
protected override Dictionary<string, string> GetSubstitutions(string trackId)
{
return new Dictionary<string, string> {
{ "trackId", trackId }
};
}
[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/supplement")]
public class YGetTrackSupplementBuilder : YRequestBuilder<YResponse<YTrackSupplement>, string>
{
public YGetTrackSupplementBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions(string trackId)
{
return new Dictionary<string, string> {
{ "trackId", trackId }
};
}
}

View File

@@ -6,21 +6,20 @@ using YandexMusic.API.Models.Track;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Track
{
[YApiRequest(WebRequestMethods.Http.Post, "tracks")]
public class YGetTracksBuilder : YRequestBuilder<YResponse<List<YTrack>>, IEnumerable<string>>
{
public YGetTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
namespace YandexMusic.API.Requests.Track;
protected override HttpContent GetContent(IEnumerable<string> trackIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "track-ids", string.Join(",", trackIds) },
{ "with-positions", "true" }
});
}
[YApiRequest(WebRequestMethods.Http.Post, "tracks")]
public class YGetTracksBuilder : YRequestBuilder<YResponse<List<YTrack>>, IEnumerable<string>>
{
public YGetTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override HttpContent GetContent(IEnumerable<string> trackIds)
{
return new FormUrlEncodedContent(new Dictionary<string, string> {
{ "track-ids", string.Join(",", trackIds) },
{ "with-positions", "true" }
});
}
}

View File

@@ -6,33 +6,32 @@ using YandexMusic.API.Models.Track;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Track
namespace YandexMusic.API.Requests.Track;
[YApiRequest(WebRequestMethods.Http.Post, "play-audio")]
public class YSendTrackInfoBuilder : YRequestBuilder<string, (YTrack track, string from, bool fromCache, string playId, string playlistId, double totalPlayedSeconds, double endPositionSeconds)>
{
[YApiRequest(WebRequestMethods.Http.Post, "play-audio")]
public class YSendTrackInfoBuilder : YRequestBuilder<string, (YTrack track, string from, bool fromCache, string playId, string playlistId, double totalPlayedSeconds, double endPositionSeconds)>
public YSendTrackInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YSendTrackInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override HttpContent GetContent((YTrack track, string from, bool fromCache, string playId, string playlistId, double totalPlayedSeconds, double endPositionSeconds) tuple)
{
Dictionary<string, string> formData = new() {
{ "track_id", tuple.track.Id },
{ "from-cache", tuple.fromCache.ToString() },
{ "play_id", tuple.playId },
{ "uid", Storage.User.Uid },
{ "timestamp", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) },
{ "client-now", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) },
{ "album-id", tuple.track.Albums.FirstOrDefault()?.Id },
{ "from", tuple.from },
{ "playlist-id", tuple.playlistId },
{ "track-length-seconds", ((double)(tuple.track.DurationMs / 1000)).ToString(CultureInfo.InvariantCulture) },
{ "total-played-seconds", tuple.totalPlayedSeconds.ToString(CultureInfo.InvariantCulture) },
{ "end-position-seconds", tuple.endPositionSeconds.ToString(CultureInfo.InvariantCulture) },
};
protected override HttpContent GetContent((YTrack track, string from, bool fromCache, string playId, string playlistId, double totalPlayedSeconds, double endPositionSeconds) tuple)
{
Dictionary<string, string> formData = new() {
{ "track_id", tuple.track.Id },
{ "from-cache", tuple.fromCache.ToString() },
{ "play_id", tuple.playId },
{ "uid", storage.User.Uid },
{ "timestamp", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) },
{ "client-now", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) },
{ "album-id", tuple.track.Albums.FirstOrDefault()?.Id },
{ "from", tuple.from },
{ "playlist-id", tuple.playlistId },
{ "track-length-seconds", ((double)(tuple.track.DurationMs / 1000)).ToString(CultureInfo.InvariantCulture) },
{ "total-played-seconds", tuple.totalPlayedSeconds.ToString(CultureInfo.InvariantCulture) },
{ "end-position-seconds", tuple.endPositionSeconds.ToString(CultureInfo.InvariantCulture) },
};
return new FormUrlEncodedContent(formData);
}
return new FormUrlEncodedContent(formData);
}
}

View File

@@ -6,38 +6,37 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Track
namespace YandexMusic.API.Requests.Track;
[YRequest(WebRequestMethods.Http.Get, "{src}")]
public class YStorageDownloadFileBuilder : YRequestBuilder<YStorageDownloadFile, string>
{
[YRequest(WebRequestMethods.Http.Get, "{src}")]
public class YStorageDownloadFileBuilder : YRequestBuilder<YStorageDownloadFile, string>
public YStorageDownloadFileBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YStorageDownloadFileBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions(string src)
{
return new Dictionary<string, string> {
{ "src", src.Split('?')[0] }
};
}
protected override Dictionary<string, string> GetSubstitutions(string src)
{
return new Dictionary<string, string> {
{ "src", src.Split('?')[0] }
};
}
protected override NameValueCollection GetQueryParams(string src)
{
NameValueCollection query = new() {
{ "format", "json" }
};
protected override NameValueCollection GetQueryParams(string src)
{
NameValueCollection query = new() {
{ "format", "json" }
};
src.Split('?')[1]
.Split('&')
.ToList()
.ForEach(p =>
{
string[] param = p.Split('=');
query.Add(param[0], param[1]);
});
src.Split('?')[1]
.Split('&')
.ToList()
.ForEach(p =>
{
string[] param = p.Split('=');
query.Add(param[0], param[1]);
});
return query;
}
return query;
}
}

View File

@@ -6,27 +6,26 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Track
namespace YandexMusic.API.Requests.Track;
[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackKey}/download-info")]
public class YTrackDownloadInfoBuilder : YRequestBuilder<YResponse<List<YTrackDownloadInfo>>, (string trackKey, bool direct)>
{
[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackKey}/download-info")]
public class YTrackDownloadInfoBuilder : YRequestBuilder<YResponse<List<YTrackDownloadInfo>>, (string trackKey, bool direct)>
public YTrackDownloadInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YTrackDownloadInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
}
protected override Dictionary<string, string> GetSubstitutions((string trackKey, bool direct) tuple)
{
return new Dictionary<string, string> {
{ "trackKey", tuple.trackKey }
};
}
protected override Dictionary<string, string> GetSubstitutions((string trackKey, bool direct) tuple)
{
return new Dictionary<string, string> {
{ "trackKey", tuple.trackKey }
};
}
protected override NameValueCollection GetQueryParams((string trackKey, bool direct) tuple)
{
return new NameValueCollection {
{ "direct", tuple.direct.ToString() }
};
}
protected override NameValueCollection GetQueryParams((string trackKey, bool direct) tuple)
{
return new NameValueCollection {
{ "direct", tuple.direct.ToString() }
};
}
}

View File

@@ -8,26 +8,25 @@ using YandexMusic.API.Models.Ugc;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Ugc
namespace YandexMusic.API.Requests.Ugc;
[YWebApiRequest(WebRequestMethods.Http.Get, "handlers/ugc-upload.jsx")]
public class YUgcGetUploadLinkBuilder : YRequestBuilder<YUgcUpload, (YPlaylist playlist, string fileName)>
{
[YWebApiRequest(WebRequestMethods.Http.Get, "handlers/ugc-upload.jsx")]
public class YUgcGetUploadLinkBuilder : YRequestBuilder<YUgcUpload, (YPlaylist playlist, string fileName)>
private static readonly Lazy<Random> Random = new(() => new Random());
public YUgcGetUploadLinkBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
private static readonly Lazy<Random> Random = new(() => new Random());
}
public YUgcGetUploadLinkBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override NameValueCollection GetQueryParams((YPlaylist playlist, string fileName) tuple)
{
return new NameValueCollection {
{ "filename", tuple.fileName },
{ "kind", tuple.playlist.Kind },
{ "visibility", "private" },
{ "external-domain", "music.yandex.ru" },
{ "ncrnd", Random.Value.NextDouble().ToString(CultureInfo.InvariantCulture) }
};
}
protected override NameValueCollection GetQueryParams((YPlaylist playlist, string fileName) tuple)
{
return new NameValueCollection {
{ "filename", tuple.fileName },
{ "kind", tuple.playlist.Kind },
{ "visibility", "private" },
{ "external-domain", "music.yandex.ru" },
{ "ncrnd", Random.Value.NextDouble().ToString(CultureInfo.InvariantCulture) }
};
}
}

View File

@@ -5,28 +5,27 @@ using YandexMusic.API.Models.Common;
using YandexMusic.API.Requests.Common;
using YandexMusic.API.Requests.Common.Attributes;
namespace YandexMusic.API.Requests.Ugc
namespace YandexMusic.API.Requests.Ugc;
[YRequest(WebRequestMethods.Http.Post, "{postTargetLink}")]
public class YUgcUploadBuilder : YRequestBuilder<YResponse<string>, (string postTargetLink, byte[] fileBytes)>
{
[YRequest(WebRequestMethods.Http.Post, "{postTargetLink}")]
public class YUgcUploadBuilder : YRequestBuilder<YResponse<string>, (string postTargetLink, byte[] fileBytes)>
public YUgcUploadBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
public YUgcUploadBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth)
{
}
protected override Dictionary<string, string> GetSubstitutions((string postTargetLink, byte[] fileBytes) tuple)
{
return new Dictionary<string, string> {
{ "postTargetLink", tuple.postTargetLink }
};
}
protected override HttpContent GetContent((string postTargetLink, byte[] fileBytes) tuple)
{
return new MultipartFormDataContent {
{ new ByteArrayContent(tuple.fileBytes), "file" }
};
}
}
protected override Dictionary<string, string> GetSubstitutions((string postTargetLink, byte[] fileBytes) tuple)
{
return new Dictionary<string, string> {
{ "postTargetLink", tuple.postTargetLink }
};
}
protected override HttpContent GetContent((string postTargetLink, byte[] fileBytes) tuple)
{
return new MultipartFormDataContent {
{ new ByteArrayContent(tuple.fileBytes), "file" }
};
}
}