| @@ -19,5 +19,7 @@ namespace GrpcShared.DTO | |||
| { | |||
| [ProtoMember(1)] | |||
| public HttpStatusCode ResponseMsg { get; set; } | |||
| [ProtoMember(2)] | |||
| public bool IsSaved { get; set; } = false; | |||
| } | |||
| } | |||
| @@ -16,7 +16,7 @@ namespace GrpcShared.DTO.TopItem | |||
| [DefaultValue(true)] | |||
| public bool IsTracks { get; set; } = true; | |||
| [ProtoMember(2)] | |||
| public int? Limit { get; set; } | |||
| public int? Limit { get; set; } = 9; | |||
| [ProtoMember(3)] | |||
| public int? Offset { get; set; } | |||
| } | |||
| @@ -13,17 +13,8 @@ namespace GrpcShared.DTO.TopItem | |||
| { | |||
| [ProtoMember(1)] | |||
| [JsonProperty("items")] | |||
| public Item[]? Items { get; set; } | |||
| 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; } | |||
| @@ -31,19 +22,17 @@ namespace GrpcShared.DTO.TopItem | |||
| [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)] | |||
| [ProtoMember(2)] | |||
| [JsonProperty("images")] | |||
| public Image[]? Images { get; set; } | |||
| [ProtoMember(4)] | |||
| [ProtoMember(3)] | |||
| [JsonProperty("name")] | |||
| public string? Name { get; set; } | |||
| [ProtoMember(5)] | |||
| [ProtoMember(4)] | |||
| [JsonProperty("uri")] | |||
| public string? Uri { get; set; } | |||
| } | |||
| @@ -23,6 +23,8 @@ namespace GrpcShared.DTO.Track | |||
| [ProtoMember(4)] | |||
| [JsonProperty("item")] | |||
| public Item? Item { get; set; } | |||
| [ProtoMember(5)] | |||
| public bool IsSaved { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 | |||
| # Visual Studio Version 17 | |||
| VisualStudioVersion = 17.2.32630.192 | |||
| MinimumVisualStudioVersion = 10.0.40219.1 | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NemAnBlazor", "NemAnCore\NemAnBlazor.csproj", "{74DCDAC5-76D7-4E06-A3F2-DE22CD37FB89}" | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NemAnBlazor", "NemAnBlazor\NemAnBlazor.csproj", "{74DCDAC5-76D7-4E06-A3F2-DE22CD37FB89}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpotifyService", "gRPCServer\SpotifyService.csproj", "{9E8FA4BC-BF52-47E2-8E61-A4151505ED7C}" | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpotifyService", "SpotifyService\SpotifyService.csproj", "{9E8FA4BC-BF52-47E2-8E61-A4151505ED7C}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpotifyWorker", "SpotifyWorker\SpotifyWorker.csproj", "{0CE36C12-E8D7-424A-9161-0A05306CD8BC}" | |||
| EndProject | |||
| @@ -15,7 +15,13 @@ | |||
| <h3>Home</h3> | |||
| <p>login radi</p> | |||
| <div> | |||
| <span>Choose top</span> | |||
| <select> | |||
| <option>Artists</option> | |||
| <option>Tracks</option> | |||
| </select> | |||
| </div> | |||
| @code { | |||
| protected override async Task OnInitializedAsync() | |||
| { | |||
| @@ -19,6 +19,7 @@ | |||
| </Authorized> | |||
| <NotAuthorized> | |||
| Nisi autorizovan. | |||
| <button class="btn btn-primary" @onclick="LoginUser">Login</button> | |||
| </NotAuthorized> | |||
| </AuthorizeView> | |||
| @@ -9,7 +9,7 @@ namespace SpotifyService | |||
| public const string SECRET = "ea752433d0774fad87fab5c1ee788c8d"; | |||
| //public const string REDIRECT_URI = "http://localhost:5051/callback"; | |||
| public const string REDIRECT_URI = "https://localhost:5001/callback"; | |||
| public const string SCOPE = "user-read-currently-playing user-read-email user-library-modify user-top-read user-read-private"; | |||
| public const string SCOPE = "user-read-currently-playing user-read-email user-library-modify user-top-read user-read-private user-library-read"; | |||
| /* | |||
| "ClientId": "83e1d09876b049c4bb1953185a4b3bfb", | |||
| "RedirectURI": "https://localhost:44342/callback", | |||
| @@ -25,14 +25,26 @@ namespace SpotifyService.Services | |||
| public async Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(SessionMessage message) | |||
| { | |||
| string url = "me/player/currently-playing"; | |||
| var response = await HttpUtils<CurrentTrackResponse> | |||
| .GetData(_httpClientFactory, | |||
| .GetData(_httpClientFactory, | |||
| url, | |||
| message.UserId!, | |||
| _identityService, | |||
| _authService); | |||
| string savedUrl = $"me/tracks/contains?ids={response.Item!.Id}"; | |||
| var savedResponse = await HttpUtils<List<bool>> | |||
| .GetData(_httpClientFactory, | |||
| savedUrl, | |||
| message.UserId!, | |||
| _identityService, | |||
| _authService); | |||
| if (response != null) | |||
| { | |||
| response.IsSaved = savedResponse[0]; | |||
| } | |||
| return response; | |||
| } | |||
| @@ -3,6 +3,7 @@ using Grpc.Core; | |||
| using GrpcShared; | |||
| using GrpcShared.DTO; | |||
| using GrpcShared.DTO.Search; | |||
| using GrpcShared.DTO.Track; | |||
| using GrpcShared.DTO.Track.MultipleTrack; | |||
| using GrpcShared.DTO.Track.SaveTracks; | |||
| using GrpcShared.DTO.Track.SingleTrack; | |||
| @@ -36,34 +37,71 @@ namespace SpotifyService.Services | |||
| string url = $"search?q={request.Query}&type={request.Type}"; | |||
| return await HttpUtils.HttpUtils<SearchResponse> | |||
| var response = await HttpUtils.HttpUtils<SearchResponse> | |||
| .GetData(_httpClientFactory, | |||
| url, | |||
| request.UserId!, | |||
| _identityService, | |||
| _authService); | |||
| //ovo je ako hocemo da dodamo da se prikazuje dal je sacuvana pesma od onih koje se pretrazuju, | |||
| //al ce potencijalno da prepuni requests ako ne optimizujemo pretragu | |||
| //if (response != null) | |||
| //{ | |||
| // List<string> ids = response.Tracks!.Items!.Select(x => x.Id!).ToList(); | |||
| // var param = new Dictionary<string, List<string>>(); | |||
| // param["ids"] = ids; | |||
| // var query = UriUtil(param); | |||
| // string savedUrl = $"tracks/contains{query}"; | |||
| // var isSavedResponse = await HttpUtils.HttpUtils<IsSavedResponse> | |||
| // .GetData(_httpClientFactory, | |||
| // savedUrl, | |||
| // request.UserId!, | |||
| // _identityService, | |||
| // _authService); | |||
| // for (int i = 0; i < response.Tracks.Items.Count; i++) | |||
| // { | |||
| // response.Tracks.Items[i].IsSaved = isSavedResponse.AreSaved[i]; | |||
| // } | |||
| //} | |||
| return response; | |||
| } | |||
| public async Task<SingleTrackResponse> ListSingleTrackAsync(SingleTrackRequest request) | |||
| { | |||
| string url = $"audio-features/{request.Id}"; | |||
| return await HttpUtils.HttpUtils<SingleTrackResponse> | |||
| var response = await HttpUtils.HttpUtils<SingleTrackResponse> | |||
| .GetData(_httpClientFactory, | |||
| url, | |||
| request.UserId!, | |||
| _identityService, | |||
| _authService); | |||
| string savedUrl = $"tracks/contains?ids={request.Id}"; | |||
| var savedResponse = await HttpUtils.HttpUtils <List<bool>> | |||
| .GetData(_httpClientFactory, | |||
| savedUrl, | |||
| request.UserId!, | |||
| _identityService, | |||
| _authService); | |||
| response.IsSaved = savedResponse[0]; | |||
| return response; | |||
| } | |||
| public async Task<MultipleTrackResponse> ListMultipleTrackAsync(MultipleTrackRequest request) | |||
| { | |||
| var param = new Dictionary<string, List<string>>(); | |||
| param["ids"] = request.Ids!; | |||
| var query = UriUtil(param); | |||
| string url = $"audio-features{query}"; | |||
| string url = $"audio-features{query}"; | |||
| return await HttpUtils.HttpUtils<MultipleTrackResponse> | |||
| .GetData(_httpClientFactory, | |||
| @@ -89,7 +127,7 @@ namespace SpotifyService.Services | |||
| request.UserId!, | |||
| _identityService, | |||
| _authService); | |||
| } | |||
| public static string UriUtil(Dictionary<string, List<string>> param) | |||
| { | |||
| @@ -114,7 +152,7 @@ namespace SpotifyService.Services | |||
| } | |||
| public async Task<TrackResponse> GetById(TrackRequest request) | |||
| { | |||
| string url = $"tracks/{request.TrackID}"; | |||
| return await HttpUtils.HttpUtils<TrackResponse> | |||
| @@ -23,7 +23,7 @@ | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\GrpcShared\GrpcShared.csproj" /> | |||
| <ProjectReference Include="..\IdentityProvider\IdentityProvider.csproj" /> | |||
| <ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" /> | |||
| <ProjectReference Include="..\NemAnBlazor\NemAnBlazor.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -14,7 +14,7 @@ | |||
| "AuthParams": { | |||
| "ClientId": "83e1d09876b049c4bb1953185a4b3bfb", | |||
| "RedirectURI": "https://localhost:5001/callback", | |||
| "Scope": "user-read-currently-playing user-read-email user-library-modify user-top-read user-read-private", | |||
| "Scope": "user-read-currently-playing user-read-email user-library-modify user-top-read user-read-private user-library-read", | |||
| "ClientSecret": "ea752433d0774fad87fab5c1ee788c8d" | |||
| } | |||
| } | |||
| @@ -99,6 +99,7 @@ namespace SpotifyWorker | |||
| { | |||
| UserId = res[i].Id | |||
| }); | |||
| Console.WriteLine(track.IsSaved); | |||
| if (track != null) | |||
| { | |||
| await _identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest | |||