Parcourir la source

code refactoring, added top tracks and albums endpoints, mini repo for http requests, protobuf inheritance

tags/v1.1.0^2
anastasijasavov il y a 3 ans
Parent
révision
3ab0e2b6e1
30 fichiers modifiés avec 382 ajouts et 364 suppressions
  1. 8
    4
      GrpcShared/DTO/Auth/TokenRequest.cs
  2. 8
    4
      GrpcShared/DTO/Auth/TokenResponse.cs
  3. 0
    16
      GrpcShared/DTO/HeaderParams.cs
  4. 30
    60
      GrpcShared/DTO/Search/SearchDetails.cs
  5. 7
    8
      GrpcShared/DTO/Search/SearchRequest.cs
  6. 29
    59
      GrpcShared/DTO/Search/SearchResponse.cs
  7. 15
    8
      GrpcShared/DTO/TokenMessage.cs
  8. 24
    0
      GrpcShared/DTO/TopItem/TopItemRequest.cs
  9. 63
    0
      GrpcShared/DTO/TopItem/TopItemResponse.cs
  10. 40
    20
      GrpcShared/DTO/Track/CurrentTrackResponse.cs
  11. 3
    4
      GrpcShared/DTO/Track/MultipleTrack/MultipleTrackRequest.cs
  12. 18
    18
      GrpcShared/DTO/Track/MultipleTrack/MultipleTrackResponse.cs
  13. 3
    4
      GrpcShared/DTO/Track/SaveTracks/SaveTracksRequest.cs
  14. 3
    4
      GrpcShared/DTO/Track/SingleTrack/SingleTrackRequest.cs
  15. 18
    23
      GrpcShared/DTO/Track/SingleTrack/SingleTrackResponse.cs
  16. 2
    4
      GrpcShared/DTO/Track/TrackByID/TrackRequest.cs
  17. 6
    6
      GrpcShared/DTO/Track/TrackByID/TrackResponse.cs
  18. 8
    9
      GrpcShared/DTO/User/UserInfoResponse.cs
  19. 2
    0
      GrpcShared/Interfaces/IStatsService.cs
  20. 6
    12
      IdentityProvider/Services/AuthService.cs
  21. 3
    3
      NemAnCore/Pages/Callback.razor
  22. 14
    27
      NemAnCore/Pages/FetchData.razor
  23. 4
    3
      NemAnCore/Pages/Home.razor
  24. 1
    3
      NemAnCore/Pages/Login.razor
  25. 4
    4
      NemAnCore/Services/AuthClientService.cs
  26. 2
    0
      NemAnCore/Services/Interfaces/IStatsClientService.cs
  27. 6
    0
      NemAnCore/Services/StatsClientService.cs
  28. 24
    0
      gRPCServer/HttpUtils/HttpUtils.cs
  29. 20
    5
      gRPCServer/Services/StatsService.cs
  30. 11
    56
      gRPCServer/Services/TrackService.cs

+ 8
- 4
GrpcShared/DTO/Auth/TokenRequest.cs Voir le fichier

using ProtoBuf;
using Newtonsoft.Json;
using ProtoBuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
public class TokenRequest public class TokenRequest
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string grant_type { get; set; } = "authorization_code";
[JsonProperty("grant_type")]
public string GrantType { get; set; } = "authorization_code";
[ProtoMember(2)] [ProtoMember(2)]
public string? code { get; set; }
[JsonProperty("code")]
public string? Code { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public string? redirect_uri { get; set; }
[JsonProperty("redirect_uri")]
public string? RedirectUri { get; set; }


} }

+ 8
- 4
GrpcShared/DTO/Auth/TokenResponse.cs Voir le fichier

using ProtoBuf;
using Newtonsoft.Json;
using ProtoBuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
public class TokenResponse public class TokenResponse
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string? access_token { get; set; }
[JsonProperty("access_token")]
public string? AccessToken { get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public string? refresh_token{ get; set; }
[JsonProperty("refresh_token")]
public string? RefreshToken{ get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public int? expires_in { get; set; }
[JsonProperty("expires_in")]
public int? Expiration { get; set; }
} }
} }

+ 0
- 16
GrpcShared/DTO/HeaderParams.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO
{
[ProtoContract]
public class HeaderParams
{
[ProtoMember(1)]
public string Token { get; set; }
}
}

+ 30
- 60
GrpcShared/DTO/Search/SearchDetails.cs Voir le fichier

public partial class Tracks public partial class Tracks
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public Item[]? Items { get; set; } public Item[]? Items { get; set; }
} }
[ProtoContract] [ProtoContract]
public partial class Item public partial class Item
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Album Album { get; set; }
public Album? Album { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public Artist[] Artists { get; set; }
public Artist[]? Artists { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public long DurationMs { get; set; }
public int? DurationMs { get; set; }


[ProtoMember(4)] [ProtoMember(4)]

public ExternalUrls ExternalUrls { get; set; }
public ExternalUrls? ExternalUrls { get; set; }


[ProtoMember(5)] [ProtoMember(5)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(6)] [ProtoMember(6)]

public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(7)] [ProtoMember(7)]

public string Name { get; set; }
public string? Name { get; set; }


[ProtoMember(8)] [ProtoMember(8)]
public long Popularity { get; set; }
public int? Popularity { get; set; }


[ProtoMember(9)] [ProtoMember(9)]

public long TrackNumber { get; set; }
public int? TrackNumber { get; set; }


[ProtoMember(10)] [ProtoMember(10)]

public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(11)] [ProtoMember(11)]

public string Uri { get; set; }
public string? Uri { get; set; }
} }
[ProtoContract] [ProtoContract]
public partial class Album public partial class Album
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public Image[] Images { get; set; }
public Image[]? Images { get; set; }


[ProtoMember(4)] [ProtoMember(4)]

public string Name { get; set; }
public string? Name { get; set; }


[ProtoMember(5)] [ProtoMember(5)]

public DateTimeOffset ReleaseDate { get; set; }
public DateTimeOffset? ReleaseDate { get; set; }


[ProtoMember(6)] [ProtoMember(6)]

public long TotalTracks { get; set; }
public int? TotalTracks { get; set; }


[ProtoMember(7)] [ProtoMember(7)]

public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(8)] [ProtoMember(8)]

public string Uri { get; set; }
public string? Uri { get; set; }
} }
[ProtoContract] [ProtoContract]
public partial class Image public partial class Image
{ {
[ProtoMember(1)] [ProtoMember(1)]

public long Height { get; set; }
public int? Height { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public Uri Url { get; set; }
public Uri? Url { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public long Width { get; set; }
public int? Width { get; set; }
} }
[ProtoContract] [ProtoContract]
public partial class Artist public partial class Artist
{ {
[ProtoMember(1)] [ProtoMember(1)]

public ExternalUrls ExternalUrls { get; set; }
public ExternalUrls? ExternalUrls { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(4)] [ProtoMember(4)]

public string Name { get; set; }
public string? Name { get; set; }


[ProtoMember(5)] [ProtoMember(5)]

public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(6)] [ProtoMember(6)]

public string Uri { get; set; }
public string? Uri { get; set; }
} }
[ProtoContract] [ProtoContract]
public partial class ExternalUrls public partial class ExternalUrls
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Uri Spotify { get; set; }
public Uri? Spotify { get; set; }
} }
} }
} }

+ 7
- 8
GrpcShared/DTO/Search/SearchRequest.cs Voir le fichier

namespace GrpcShared.DTO.Search namespace GrpcShared.DTO.Search
{ {
[ProtoContract] [ProtoContract]
public class SearchRequest
public class SearchRequest : TokenMessage
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string Query { get; set; }
public string? Query { get; set; }


[ProtoMember(2)] [ProtoMember(2)]
public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(3)] [ProtoMember(3)]
public string Include_External { get; set; }
public string? Include_External { get; set; }


[ProtoMember(4)] [ProtoMember(4)]
public int Limit { get; set; }
public int? Limit { get; set; }


[ProtoMember(5)] [ProtoMember(5)]
public int Offset { get; set; }
[ProtoMember(6)]
public string Token { get; set; }
public int? Offset { get; set; }
} }
} }

+ 29
- 59
GrpcShared/DTO/Search/SearchResponse.cs Voir le fichier

public class Tracks public class Tracks
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public List<Item>? Items { get; set; } public List<Item>? Items { get; set; }
} }
[ProtoContract] [ProtoContract]
public class Item public class Item
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Album? Album { get; set; } public Album? Album { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public Artist[] Artists { get; set; }
public Artist[]? Artists { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public long DurationMs { get; set; }
public int? DurationMs { get; set; }


[ProtoMember(4)] [ProtoMember(4)]

public ExternalUrls ExternalUrls { get; set; }
public ExternalUrls? ExternalUrls { get; set; }


[ProtoMember(5)] [ProtoMember(5)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(6)] [ProtoMember(6)]

public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(7)] [ProtoMember(7)]

public string Name { get; set; }
public string? Name { get; set; }


[ProtoMember(8)] [ProtoMember(8)]
public long Popularity { get; set; }
public int? Popularity { get; set; }


[ProtoMember(9)] [ProtoMember(9)]

public long TrackNumber { get; set; }
public int? TrackNumber { get; set; }


[ProtoMember(10)] [ProtoMember(10)]

public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(11)] [ProtoMember(11)]

public string Uri { get; set; }
public string? Uri { get; set; }
} }
[ProtoContract] [ProtoContract]
public class Album public class Album
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public Image[] Images { get; set; }
public Image[]? Images { get; set; }


[ProtoMember(4)] [ProtoMember(4)]

public string Name { get; set; }
public string? Name { get; set; }


[ProtoMember(5)] [ProtoMember(5)]

public DateTimeOffset ReleaseDate { get; set; }
public DateTimeOffset? ReleaseDate { get; set; }


[ProtoMember(6)] [ProtoMember(6)]

public long TotalTracks { get; set; }
public int? TotalTracks { get; set; }


[ProtoMember(7)] [ProtoMember(7)]

public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(8)] [ProtoMember(8)]

public string Uri { get; set; }
public string? Uri { get; set; }
} }
[ProtoContract] [ProtoContract]
public class Image public class Image
{ {
[ProtoMember(1)] [ProtoMember(1)]

public long Height { get; set; }
public int? Height { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public Uri Url { get; set; }
public Uri? Url { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public long Width { get; set; }
public int? Width { get; set; }
} }
[ProtoContract] [ProtoContract]
public class Artist public class Artist
{ {
[ProtoMember(1)] [ProtoMember(1)]

public ExternalUrls ExternalUrls { get; set; }
public ExternalUrls? ExternalUrls { get; set; }


[ProtoMember(2)] [ProtoMember(2)]

public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(3)] [ProtoMember(3)]

public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(4)] [ProtoMember(4)]

public string Name { get; set; }
public string? Name { get; set; }


[ProtoMember(5)] [ProtoMember(5)]

public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(6)] [ProtoMember(6)]

public string Uri { get; set; }
public string? Uri { get; set; }
} }
[ProtoContract] [ProtoContract]
public class ExternalUrls public class ExternalUrls
{ {
[ProtoMember(1)] [ProtoMember(1)]

public Uri Spotify { get; set; }
public Uri? Spotify { get; set; }
} }
} }

+ 15
- 8
GrpcShared/DTO/TokenMessage.cs Voir le fichier

using ProtoBuf;
using GrpcShared.DTO.Search;
using GrpcShared.DTO.TopItem;
using GrpcShared.DTO.Track.MultipleTrack;
using GrpcShared.DTO.Track.SaveTracks;
using GrpcShared.DTO.Track.SingleTrack;
using GrpcShared.DTO.TrackByID;
using ProtoBuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;


namespace GrpcShared.DTO namespace GrpcShared.DTO
{ {
[ProtoInclude(5, typeof(TopItemRequest))]
[ProtoInclude(6, typeof(SingleTrackRequest))]
[ProtoInclude(7, typeof(SearchRequest))]
[ProtoInclude(8,typeof(MultipleTrackRequest))]
[ProtoInclude(9,typeof(SaveTracksRequest))]
[ProtoInclude(10,typeof(TrackRequest))]

[ProtoContract(SkipConstructor = true)] [ProtoContract(SkipConstructor = true)]
public class TokenMessage public class TokenMessage
{
public TokenMessage(string? token)
{
Token = token;
}

{
[ProtoMember(1)] [ProtoMember(1)]
public string? Token { get; set; } public string? Token { get; set; }
} }

+ 24
- 0
GrpcShared/DTO/TopItem/TopItemRequest.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO.TopItem
{
[ProtoContract]
public class TopItemRequest : TokenMessage
{

[ProtoMember(1)]
[DefaultValue(true)]
public bool IsTracks { get; set; } = true;
[ProtoMember(2)]
public int? Limit { get; set; }
[ProtoMember(3)]
public int? Offset { get; set; }
}
}

+ 63
- 0
GrpcShared/DTO/TopItem/TopItemResponse.cs Voir le fichier

using Newtonsoft.Json;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO.TopItem
{
[ProtoContract]
public class TopItemResponse
{
[ProtoMember(1)]
[JsonProperty("items")]
public Item[]? Items { get; set; }
[ProtoMember(2)]
[JsonProperty("total")]
public int? Total { get; set; }
[ProtoMember(3)]
[JsonProperty("limit")]
public int? Limit { get; set; }
[ProtoMember(4)]
[JsonProperty("offset")]
public int? Offset { get; set; }
[ProtoMember(5)]
[JsonProperty("href")]
public Uri? Href { get; set; }
}
[ProtoContract]
public partial class Item
{
[ProtoMember(1)]
[JsonProperty("genres")]
public string[]? Genres { get; set; }
[ProtoMember(2)]
[JsonProperty("id")]
public string? Id { get; set; }
[ProtoMember(3)]
[JsonProperty("images")]
public Image[]? Images { get; set; }
[ProtoMember(4)]
[JsonProperty("name")]
public string? Name { get; set; }
[ProtoMember(5)]
[JsonProperty("uri")]
public string? Uri { get; set; }
}
[ProtoContract]
public partial class Image
{
[ProtoMember(1)]
[JsonProperty("height")]
public int? Height { get; set; }
[ProtoMember(2)]
[JsonProperty("url")]
public Uri? Url { get; set; }
[ProtoMember(3)]
[JsonProperty("width")]
public int? Width { get; set; }
}
}

+ 40
- 20
GrpcShared/DTO/Track/CurrentTrackResponse.cs Voir le fichier

using ProtoBuf;
using Newtonsoft.Json;
using ProtoBuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
public class CurrentTrackResponse public class CurrentTrackResponse
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string? timestamp{ get; set; }
[JsonProperty("timestamp")]
public string? Timestamp{ get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public int? progress_ms { get; set; }
[JsonProperty("progress_ms")]
public int? ProgressMs { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public bool? is_playing { get; set; }
[JsonProperty("is_playing")]
public bool? IsPlaying { get; set; }
[ProtoMember(4)] [ProtoMember(4)]
public Item? item { get; set; }
[JsonProperty("item")]
public Item? Item { get; set; }


} }
[ProtoContract] [ProtoContract]
public class Item public class Item
{ {
[ProtoMember(1)] [ProtoMember(1)]
public Album? album { get; set; }
[JsonProperty("album")]
public Album? Album { get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public Artist[]? artists { get; set; }
[JsonProperty("artists")]
public Artist[]? Artists { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public string? id { get; set; }
[JsonProperty("id")]
public string? Id { get; set; }
[ProtoMember(4)] [ProtoMember(4)]
public string? name { get; set; }
[JsonProperty("name")]
public string? Name { get; set; }
[ProtoMember(5)] [ProtoMember(5)]
public string? href { get; set; }
[JsonProperty("href")]
public string? Href { get; set; }


} }
[ProtoContract] [ProtoContract]
public class Album public class Album
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string? id { get; set; }
[JsonProperty("id")]
public string? Id { get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public string? name { get; set; }
[JsonProperty("name")]
public string? Name { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public Image[]? images { get; set; }
[JsonProperty("images")]
public Image[]? Images { get; set; }
[ProtoMember(4)] [ProtoMember(4)]
public string? href { get; set; }
[JsonProperty("href")]
public string? Href { get; set; }
} }
[ProtoContract] [ProtoContract]
public class Artist public class Artist
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string? id { get; set; }
[JsonProperty("id")]
public string? Id { get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public string? name { get; set; }
[JsonProperty("name")]
public string? Name { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public string? href { get; set; }
[JsonProperty("href")]
public string? Href { get; set; }
} }
[ProtoContract] [ProtoContract]
public class Image public class Image
{ {
[ProtoMember(1)] [ProtoMember(1)]
public int? height{ get; set; }
[JsonProperty("height")]
public int? Height{ get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public string? url { get; set; }
[JsonProperty("url")]
public string? Url { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public int? width { get; set; }
[JsonProperty("width")]
public int? Width { get; set; }
} }
} }

+ 3
- 4
GrpcShared/DTO/Track/MultipleTrack/MultipleTrackRequest.cs Voir le fichier

namespace GrpcShared.DTO.Track.MultipleTrack namespace GrpcShared.DTO.Track.MultipleTrack
{ {
[ProtoContract] [ProtoContract]
public class MultipleTrackRequest
public class MultipleTrackRequest:TokenMessage
{ {
[ProtoMember(1)] [ProtoMember(1)]
public List<string> Ids { get; set; }
[ProtoMember(2)]
public string Token { get; set; }
public List<string>? Ids { get; set; }
} }
} }

+ 18
- 18
GrpcShared/DTO/Track/MultipleTrack/MultipleTrackResponse.cs Voir le fichier

public class AudioFeature public class AudioFeature
{ {
[ProtoMember(1)] [ProtoMember(1)]
public double Danceability { get; set; }
public float? Danceability { get; set; }


[ProtoMember(2)] [ProtoMember(2)]
public double Energy { get; set; }
public float? Energy { get; set; }


[ProtoMember(3)] [ProtoMember(3)]
public long Key { get; set; }
public int? Key { get; set; }


[ProtoMember(4)] [ProtoMember(4)]
public double Loudness { get; set; }
public float? Loudness { get; set; }


[ProtoMember(5)] [ProtoMember(5)]
public long Mode { get; set; }
public int? Mode { get; set; }


[ProtoMember(6)] [ProtoMember(6)]
public double Speechiness { get; set; }
public float? Speechiness { get; set; }


[ProtoMember(7)] [ProtoMember(7)]
public double Acousticness { get; set; }
public float? Acousticness { get; set; }


[ProtoMember(8)] [ProtoMember(8)]
public long Instrumentalness { get; set; }
public int? Instrumentalness { get; set; }


[ProtoMember(9)] [ProtoMember(9)]
public double Liveness { get; set; }
public float? Liveness { get; set; }


[ProtoMember(10)] [ProtoMember(10)]
public double Valence { get; set; }
public float? Valence { get; set; }


[ProtoMember(11)] [ProtoMember(11)]
public double Tempo { get; set; }
public float? Tempo { get; set; }


[ProtoMember(12)] [ProtoMember(12)]
public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(13)] [ProtoMember(13)]
public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(14)] [ProtoMember(14)]
public string Uri { get; set; }
public string? Uri { get; set; }


[ProtoMember(15)] [ProtoMember(15)]
public Uri TrackHref { get; set; }
public Uri? TrackHref { get; set; }


[ProtoMember(16)] [ProtoMember(16)]
public Uri AnalysisUrl { get; set; }
public Uri? AnalysisUrl { get; set; }


[ProtoMember(17)] [ProtoMember(17)]
public long DurationMs { get; set; }
public int? DurationMs { get; set; }


[ProtoMember(18)] [ProtoMember(18)]
public long TimeSignature { get; set; }
public int? TimeSignature { get; set; }
} }
} }

+ 3
- 4
GrpcShared/DTO/Track/SaveTracks/SaveTracksRequest.cs Voir le fichier

namespace GrpcShared.DTO.Track.SaveTracks namespace GrpcShared.DTO.Track.SaveTracks
{ {
[ProtoContract] [ProtoContract]
public class SaveTracksRequest
public class SaveTracksRequest : TokenMessage
{ {
[ProtoMember(1)] [ProtoMember(1)]
public List<string> Ids { get; set; }
[ProtoMember(2)]
public string Token { get; set; }
public List<string>? Ids { get; set; }
} }
} }

+ 3
- 4
GrpcShared/DTO/Track/SingleTrack/SingleTrackRequest.cs Voir le fichier

namespace GrpcShared.DTO.Track.SingleTrack namespace GrpcShared.DTO.Track.SingleTrack
{ {
[ProtoContract] [ProtoContract]
public class SingleTrackRequest
public class SingleTrackRequest : TokenMessage
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string Id { get; set; }
[ProtoMember(2)]
public string Token { get; set; }
public string? Id { get; set; }
} }
} }

+ 18
- 23
GrpcShared/DTO/Track/SingleTrack/SingleTrackResponse.cs Voir le fichier

using ProtoBuf; using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace GrpcShared.DTO.Track.SingleTrack namespace GrpcShared.DTO.Track.SingleTrack
{ {
public class SingleTrackResponse public class SingleTrackResponse
{ {
[ProtoMember(1)] [ProtoMember(1)]
public double Danceability { get; set; }
public float? Danceability { get; set; }


[ProtoMember(2)] [ProtoMember(2)]
public double Energy { get; set; }
public float? Energy { get; set; }


[ProtoMember(3)] [ProtoMember(3)]
public long Key { get; set; }
public int? Key { get; set; }


[ProtoMember(4)] [ProtoMember(4)]
public double Loudness { get; set; }
public float? Loudness { get; set; }


[ProtoMember(5)] [ProtoMember(5)]
public long Mode { get; set; }
public int? Mode { get; set; }


[ProtoMember(6)] [ProtoMember(6)]
public double Speechiness { get; set; }
public float? Speechiness { get; set; }


[ProtoMember(7)] [ProtoMember(7)]
public double Acousticness { get; set; }
public float? Acousticness { get; set; }


[ProtoMember(8)] [ProtoMember(8)]
public long Instrumentalness { get; set; }
public int? Instrumentalness { get; set; }


[ProtoMember(9)] [ProtoMember(9)]
public double Liveness { get; set; }
public float? Liveness { get; set; }


[ProtoMember(10)] [ProtoMember(10)]
public double Valence { get; set; }
public float? Valence { get; set; }


[ProtoMember(11)] [ProtoMember(11)]
public double Tempo { get; set; }
public float? Tempo { get; set; }


[ProtoMember(12)] [ProtoMember(12)]
public string Type { get; set; }
public string? Type { get; set; }


[ProtoMember(13)] [ProtoMember(13)]
public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(14)] [ProtoMember(14)]
public string Uri { get; set; }
public string? Uri { get; set; }


[ProtoMember(15)] [ProtoMember(15)]
public Uri TrackHref { get; set; }
public Uri? TrackHref { get; set; }


[ProtoMember(16)] [ProtoMember(16)]
public Uri AnalysisUrl { get; set; }
public Uri? AnalysisUrl { get; set; }


[ProtoMember(17)] [ProtoMember(17)]
public long DurationMs { get; set; }
public int? DurationMs { get; set; }


[ProtoMember(18)] [ProtoMember(18)]
public long TimeSignature { get; set; }
public int? TimeSignature { get; set; }
} }
} }

GrpcShared/DTO/TrackByID/TrackRequest.cs → GrpcShared/DTO/Track/TrackByID/TrackRequest.cs Voir le fichier

namespace GrpcShared.DTO.TrackByID namespace GrpcShared.DTO.TrackByID
{ {
[ProtoContract] [ProtoContract]
public class TrackRequest
public class TrackRequest:TokenMessage
{ {
[ProtoMember(1)] [ProtoMember(1)]
[JsonProperty("id")] [JsonProperty("id")]
public string? TrackID { get; set; } public string? TrackID { get; set; }
[ProtoMember(2)]
[JsonProperty("token")]
public string? Token { get; set; }
} }
} }

GrpcShared/DTO/TrackByID/TrackResponse.cs → GrpcShared/DTO/Track/TrackByID/TrackResponse.cs Voir le fichier

{ {
[ProtoMember(1)] [ProtoMember(1)]
[JsonProperty("album")] [JsonProperty("album")]
public Album Album { get; set; }
public Album? Album { get; set; }


[ProtoMember(2)] [ProtoMember(2)]
[JsonProperty("artists")] [JsonProperty("artists")]
public Artist[] Artists { get; set; }
public Artist[]? Artists { get; set; }


[ProtoMember(3)] [ProtoMember(3)]
[JsonProperty("duration_ms")] [JsonProperty("duration_ms")]
public long DurationMs { get; set; }
public long? DurationMs { get; set; }


[ProtoMember(4)] [ProtoMember(4)]
[JsonProperty("href")] [JsonProperty("href")]
public Uri Href { get; set; }
public Uri? Href { get; set; }


[ProtoMember(5)] [ProtoMember(5)]
[JsonProperty("id")] [JsonProperty("id")]
public string Id { get; set; }
public string? Id { get; set; }


[ProtoMember(6)] [ProtoMember(6)]
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; }
public string? Name { get; set; }
} }
} }

+ 8
- 9
GrpcShared/DTO/User/UserInfoResponse.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using ProtoBuf;


namespace GrpcShared.DTO.User namespace GrpcShared.DTO.User
{ {
public class UserInfoResponse public class UserInfoResponse
{ {
[ProtoMember(1)] [ProtoMember(1)]
public string? email { get; set; }
[JsonProperty("email")]
public string? Email { get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public string? id { get; set; }
[JsonProperty("id")]
public string? Id { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public string? display_name { get; set; }
[JsonProperty("display_name")]
public string? DisplayName{ get; set; }
} }
} }

+ 2
- 0
GrpcShared/Interfaces/IStatsService.cs Voir le fichier

using GrpcShared.DTO; using GrpcShared.DTO;
using GrpcShared.DTO.TopItem;
using GrpcShared.DTO.Track; using GrpcShared.DTO.Track;
using ProtoBuf.Grpc.Configuration; using ProtoBuf.Grpc.Configuration;
using System; using System;
public interface IStatsService public interface IStatsService
{ {
Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token); Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token);
Task<TopItemResponse> GetTopItems(TopItemRequest request);
} }
} }

+ 6
- 12
IdentityProvider/Services/AuthService.cs Voir le fichier

//get client id and secret, and redirect uri from appsettings, convert to base64 and set as header //get client id and secret, and redirect uri from appsettings, convert to base64 and set as header
var secrets = await GetAuthParams(); var secrets = await GetAuthParams();
byte[] contentType = Encoding.UTF8.GetBytes($"{secrets.ClientId}:{secrets.ClientSecret}"); byte[] contentType = Encoding.UTF8.GetBytes($"{secrets.ClientId}:{secrets.ClientSecret}");
tokenRequest.redirect_uri = secrets.RedirectURI;
tokenRequest.RedirectUri = secrets.RedirectURI;


//AUTHORIZATION HEADER //AUTHORIZATION HEADER
http.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Basic " + Convert.ToBase64String(contentType)); http.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Basic " + Convert.ToBase64String(contentType));


//BODY PARAMS //BODY PARAMS
var requestBody = new Dictionary<string, string>(); var requestBody = new Dictionary<string, string>();
requestBody["grant_type"] = tokenRequest.grant_type;
requestBody["code"] = tokenRequest.code!;
requestBody["redirect_uri"] = tokenRequest.redirect_uri!;
requestBody["grant_type"] = tokenRequest.GrantType;
requestBody["code"] = tokenRequest.Code!;
requestBody["redirect_uri"] = tokenRequest.RedirectUri!;


//REQUEST //REQUEST
var response = await http.PostAsync(url, new FormUrlEncodedContent(requestBody)); var response = await http.PostAsync(url, new FormUrlEncodedContent(requestBody));


var contents = JsonConvert.DeserializeObject<TokenResponse>(await response.Content.ReadAsStringAsync()); var contents = JsonConvert.DeserializeObject<TokenResponse>(await response.Content.ReadAsStringAsync());
if (contents != null)
return new TokenResponse
{
access_token = contents!.access_token,
refresh_token = contents!.refresh_token,
expires_in = contents!.expires_in
};
else return null;
return contents;
} }


public async Task<CodeRequest> GetAuthParams() public async Task<CodeRequest> GetAuthParams()

+ 3
- 3
NemAnCore/Pages/Callback.razor Voir le fichier

//code is the only parameter in the url //code is the only parameter in the url
string code = url.Split("=")[1]; string code = url.Split("=")[1];


var response = await AuthService.GetAccessToken(new GrpcShared.DTO.Auth.TokenRequest { code = code});
var response = await AuthService.GetAccessToken(new GrpcShared.DTO.Auth.TokenRequest { Code = code});


//if (response.access_token == null) NavigationMgr.NavigateTo("/"); //if (response.access_token == null) NavigationMgr.NavigateTo("/");


//store access token in local storage //store access token in local storage
await sessionStorage.SetItemAsync("token", response.access_token);
await sessionStorage.SetItemAsync("refresh_token", response.refresh_token);
await sessionStorage.SetItemAsync("token", response.AccessToken);
await sessionStorage.SetItemAsync("refresh_token", response.RefreshToken);
//redirect to home //redirect to home
NavigationMgr.NavigateTo("/home"); NavigationMgr.NavigateTo("/home");

+ 14
- 27
NemAnCore/Pages/FetchData.razor Voir le fichier

@page "/search" @page "/search"
@attribute [Authorize]
@using Grpc.Core @using Grpc.Core
@using GrpcShared.DTO @using GrpcShared.DTO
@using GrpcShared.DTO.Search @using GrpcShared.DTO.Search
@inject IAuthClientService AuthService @inject IAuthClientService AuthService




<AuthorizeView>
<Authorized>
The user is authorized
</Authorized>
<NotAuthorized>
The User is not authorized
</NotAuthorized>
</AuthorizeView>

<PageTitle>Search</PageTitle> <PageTitle>Search</PageTitle>


<h1>Search</h1> <h1>Search</h1>


<AuthorizeView>
<Authorized>
<button class="btn btn-primary" @onclick="Click">Click me</button>
</Authorized>
</AuthorizeView>
<button class="btn btn-primary" @onclick="Click">Click me</button>






@code { @code {
protected override async Task OnInitializedAsync()
{
//MultipleTrackRequest mreq = new() { Ids = new List<string>(){"3JAeYOjyJodI4PRs44lx2l", "6clZa1yrZe7pJrYFUcD9KW"}, Token = token };
//MultipleTrackResponse multipleTrackResponse = await SearchService.GetListMultipleTrackAsync(mreq);
//protected override async Task OnInitializedAsync()
//{
//MultipleTrackRequest mreq = new() { Ids = new List<string>(){"3JAeYOjyJodI4PRs44lx2l", "6clZa1yrZe7pJrYFUcD9KW"}, Token = token };
//MultipleTrackResponse multipleTrackResponse = await SearchService.GetListMultipleTrackAsync(mreq);


//SingleTrackRequest singleTrackRequest = new() { Id = "3JAeYOjyJodI4PRs44lx2l", Token = token };
//SingleTrackResponse singleTrackResponse = await SearchService.GetListSingleTrackAsync(singleTrackRequest);
}
//SingleTrackRequest singleTrackRequest = new() { Id = "3JAeYOjyJodI4PRs44lx2l", Token = token };
//SingleTrackResponse singleTrackResponse = await SearchService.GetListSingleTrackAsync(singleTrackRequest);
//}


private async Task Click(){
private async Task Click()
{


var token = await sessionStorage.GetItemAsync<string>("token"); var token = await sessionStorage.GetItemAsync<string>("token");
TokenMessage tm = new(token) ;
SearchRequest request = new() { Query = "aitch", Type = "track", Token = token };
SearchResponse searchResponse = await SearchService.GetListSearchAsync(request);
TokenMessage tm = new() { Token = token };
SearchRequest request = new() { Query = "aitch", Type = "track", Token = token };
SearchResponse searchResponse = await SearchService.GetListSearchAsync(request);
} }





+ 4
- 3
NemAnCore/Pages/Home.razor Voir le fichier

protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
string tokenS = await sessionStorage.GetItemAsync<string>("token"); string tokenS = await sessionStorage.GetItemAsync<string>("token");
TokenMessage token = new TokenMessage(tokenS);
TokenMessage token = new TokenMessage{Token = tokenS};


// CurrentTrackResponse response = await spotifyService.GetCurrentlyPlayingTrack(token);
CurrentTrackResponse response = await spotifyService.GetCurrentlyPlayingTrack(token);


//napravi komponentu koja ce da prikazuje sta trenutno slusas i passuj joj parametre //napravi komponentu koja ce da prikazuje sta trenutno slusas i passuj joj parametre


//4fy1A2WBTPX55mUI16TQXa //4fy1A2WBTPX55mUI16TQXa
var trackById = await trackService.GetById(new GrpcShared.DTO.TrackByID.TrackRequest { TrackID = "4fy1A2WBTPX55mUI16TQXa", Token = tokenS });
//var trackById = await trackService.GetById(new GrpcShared.DTO.TrackByID.TrackRequest { TrackID = "4fy1A2WBTPX55mUI16TQXa", Token = tokenS });
var items = await spotifyService.GetTopItems(new GrpcShared.DTO.TopItem.TopItemRequest { Token = tokenS, IsTracks = false, Offset = 5});
} }
} }

+ 1
- 3
NemAnCore/Pages/Login.razor Voir le fichier

@using System.Security.Claims @using System.Security.Claims






<AuthorizeView> <AuthorizeView>
<Authorized> <Authorized>
Dobrodosli @context.User.Claims.FirstOrDefault(x => x.Type == "name")?.Value.ToUpper() Dobrodosli @context.User.Claims.FirstOrDefault(x => x.Type == "name")?.Value.ToUpper()




@code { @code {
private string message;
private string? message;


protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {

+ 4
- 4
NemAnCore/Services/AuthClientService.cs Voir le fichier

//token = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN"; //token = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN";
if (token == null) return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); if (token == null) return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));


var userInfo = await _serviceClient.GetUserInfo(new TokenMessage (token));
var userInfo = await _serviceClient.GetUserInfo(new TokenMessage{Token = token});


List<Claim> claims = new(); List<Claim> claims = new();


claims.Add(new Claim("email", userInfo.email!));
claims.Add(new Claim("id", userInfo.id!));
claims.Add(new Claim("name", userInfo.display_name!));
claims.Add(new Claim("email", userInfo.Email!));
claims.Add(new Claim("id", userInfo.Id!));
claims.Add(new Claim("name", userInfo.DisplayName!));


ClaimsIdentity identity = new(claims, "jwt"); ClaimsIdentity identity = new(claims, "jwt");
//ClaimsIdentity identity = new(); //ClaimsIdentity identity = new();

+ 2
- 0
NemAnCore/Services/Interfaces/IStatsClientService.cs Voir le fichier

using GrpcShared.DTO; using GrpcShared.DTO;
using GrpcShared.DTO.TopItem;
using GrpcShared.DTO.Track; using GrpcShared.DTO.Track;


namespace NemAnBlazor.Services.Interfaces namespace NemAnBlazor.Services.Interfaces
public interface IStatsClientService public interface IStatsClientService
{ {
Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token); Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token);
Task<TopItemResponse> GetTopItems(TopItemRequest request);
} }
} }

+ 6
- 0
NemAnCore/Services/StatsClientService.cs Voir le fichier

using Grpc.Net.Client; using Grpc.Net.Client;
using GrpcShared.DTO; using GrpcShared.DTO;
using GrpcShared.DTO.TopItem;
using GrpcShared.DTO.Track; using GrpcShared.DTO.Track;
using GrpcShared.Interfaces; using GrpcShared.Interfaces;
using NemAnBlazor.Services.Interfaces; using NemAnBlazor.Services.Interfaces;
{ {
return await _serviceClient.GetCurrentlyPlayingTrack(token); return await _serviceClient.GetCurrentlyPlayingTrack(token);
} }

public async Task<TopItemResponse> GetTopItems(TopItemRequest request)
{
return await _serviceClient.GetTopItems(request);
}
} }
} }

+ 24
- 0
gRPCServer/HttpUtils/HttpUtils.cs Voir le fichier

using Grpc.Net.Client;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;

namespace SpotifyService.HttpUtils
{
public static class HttpUtils<T>
{
public static async Task<T> GetData(HttpClient client, string url, string token)
{
//add header
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + token);

//get request
var req = await client.GetAsync(url);

//read response
var response = JsonConvert.DeserializeObject<T>(await req.Content.ReadAsStringAsync())!;

return response;

}
}
}

+ 20
- 5
gRPCServer/Services/StatsService.cs Voir le fichier

 
using GrpcShared.DTO; using GrpcShared.DTO;
using GrpcShared.DTO.TopItem;
using GrpcShared.DTO.Track; using GrpcShared.DTO.Track;
using GrpcShared.Interfaces; using GrpcShared.Interfaces;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using Newtonsoft.Json; using Newtonsoft.Json;
using SpotifyService.HttpUtils;


namespace SpotifyService.Services namespace SpotifyService.Services
{ {
public async Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token) public async Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token)
{ {
var client = _httpClientFactory.CreateClient("HttpClient"); var client = _httpClientFactory.CreateClient("HttpClient");
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + token.Token);
var searchResult = await client.GetAsync($"me/player/currently-playing");
string url = "me/player/currently-playing";


var responses = JsonConvert.DeserializeObject<CurrentTrackResponse>(await searchResult.Content.ReadAsStringAsync())!;
return await HttpUtils<CurrentTrackResponse>.GetData(client, url, token.Token!);


return responses;
}

public async Task<TopItemResponse> GetTopItems(TopItemRequest request)
{
//https://api.spotify.com/v1/me/top/albums?limit=10&offset=5
var client = _httpClientFactory.CreateClient("HttpClient");

//URL PARAMS
string url = "me/top/";
url += !request.IsTracks ? "artists" : "tracks";
url += request.Limit == null ? "" : $"?limit={request.Limit}";

if (request.Limit == null && request.Offset != null) url += $"?offset={request.Offset}";
else url += request.Offset == null ? "" : $"&offset={request.Offset}";

return await HttpUtils<TopItemResponse>.GetData(client, url, request.Token!);


} }
} }

+ 11
- 56
gRPCServer/Services/TrackService.cs Voir le fichier



var client = _httpClientFactory.CreateClient("HttpClient"); var client = _httpClientFactory.CreateClient("HttpClient");


client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token );
string url = $"search?q={request.Query}&type={request.Type}";


var searchResult = await client.GetAsync($"search?q={request.Query}&type={request.Type}");

var responses = JsonConvert.DeserializeObject<SearchResponse>(await searchResult.Content.ReadAsStringAsync())!;

return new SearchResponse
{
Tracks = responses!.Tracks
};
return await HttpUtils.HttpUtils<SearchResponse>.GetData(client, url, request.Token!);




} }

public async Task<SingleTrackResponse> ListSingleTrackAsync(SingleTrackRequest request) public async Task<SingleTrackResponse> ListSingleTrackAsync(SingleTrackRequest request)
{ {
var client = _httpClientFactory.CreateClient("HttpClient"); var client = _httpClientFactory.CreateClient("HttpClient");

client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token);

var trackResult = await client.GetAsync($"audio-features/{request.Id}");

var responses = JsonConvert.DeserializeObject<SingleTrackResponse>(await trackResult.Content.ReadAsStringAsync())!;

return new SingleTrackResponse
{
Id = responses!.Id,
Danceability = responses!.Danceability,
Key = responses!.Key,
Loudness = responses!.Loudness,
Mode = responses!.Mode,
Speechiness = responses!.Speechiness,
Acousticness = responses!.Acousticness,
Instrumentalness = responses!.Instrumentalness,
Liveness = responses!.Liveness,
Valence = responses!.Valence,
Tempo = responses!.Tempo,
Type = responses!.Type,
Uri = responses!.Uri,
TrackHref = responses!.TrackHref,
AnalysisUrl = responses!.AnalysisUrl,
DurationMs = responses!.DurationMs,
TimeSignature = responses!.TimeSignature,
};
string url = $"audio-features/{request.Id}";
return await HttpUtils.HttpUtils<SingleTrackResponse>.GetData(client, url, request.Token!);
} }
public async Task<MultipleTrackResponse> ListMultipleTrackAsync(MultipleTrackRequest request) public async Task<MultipleTrackResponse> ListMultipleTrackAsync(MultipleTrackRequest request)
{ {
var client = _httpClientFactory.CreateClient("HttpClient"); var client = _httpClientFactory.CreateClient("HttpClient");


client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token);

var param = new Dictionary<string, List<string>>(); var param = new Dictionary<string, List<string>>();
param["ids"] = request.Ids;
param["ids"] = request.Ids!;


var query = UriUtil(param); var query = UriUtil(param);
string url = $"audio-features{query}";


var trackMultipleResult = await client.GetAsync($"audio-features{query}");

var responses = JsonConvert.DeserializeObject<MultipleTrackResponse>(await trackMultipleResult.Content.ReadAsStringAsync())!;

return new MultipleTrackResponse
{
Audio_Features = responses!.Audio_Features
};
return await HttpUtils.HttpUtils<MultipleTrackResponse>.GetData(client,url,request.Token!);
} }

public async Task SaveTracks(SaveTracksRequest request) public async Task SaveTracks(SaveTracksRequest request)
{ {
var client = _httpClientFactory.CreateClient("HttpClient"); var client = _httpClientFactory.CreateClient("HttpClient");
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token); client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token);


var param = new Dictionary<string, List<string>>(); var param = new Dictionary<string, List<string>>();
param["ids"] = request.Ids;
param["ids"] = request.Ids!;


var query = UriUtil(param); var query = UriUtil(param);






} }

public static string UriUtil(Dictionary<string, List<string>> param) public static string UriUtil(Dictionary<string, List<string>> param)
{ {
bool startingQuestionMarkAdded = false; bool startingQuestionMarkAdded = false;
sb.Length = sb.Length - 3; sb.Length = sb.Length - 3;
return sb.ToString(); return sb.ToString();
} }

public async Task<TrackResponse> GetById(TrackRequest request) public async Task<TrackResponse> GetById(TrackRequest request)
{ {
var client = _httpClientFactory.CreateClient("HttpClient"); var client = _httpClientFactory.CreateClient("HttpClient");


client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token);
var track = await client.GetAsync($"tracks/{request.TrackID}");
string url = $"tracks/{request.TrackID}";


var response = JsonConvert.DeserializeObject<TrackResponse>(await track!.Content.ReadAsStringAsync())!;
return response;
return await HttpUtils.HttpUtils<TrackResponse>.GetData(client, url, request.Token!);
} }
} }
} }

Chargement…
Annuler
Enregistrer