Ajout gestion des erreurs pour l'API Spotify.
continuous-integration/drone/push Build is passing Details

Début de la gestion des playlists Spotify.
messagerie_lucas_test
Félix MIELCAREK 2 years ago
parent bd50b7aba9
commit c227d05883

@ -3,6 +3,7 @@ import 'dart:math';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'dart:developer' as dev; import 'dart:developer' as dev;
import '../exceptions/api_exception.dart';
import 'track.dart'; import 'track.dart';
class Api { class Api {
@ -12,12 +13,14 @@ class Api {
//for web api //for web api
get redirectUri => 'https://daflmusic.000webhostapp.com/callback/'; get redirectUri => 'https://daflmusic.000webhostapp.com/callback/';
final _scopes = 'user-read-playback-state user-read-currently-playing'; final _scopes =
'user-read-playback-state user-read-currently-playing user-read-recently-played';
late String _state; late String _state;
dynamic _codeVerifier; dynamic _codeVerifier;
dynamic _codeChallenge; dynamic _codeChallenge;
late String _encodedLogs; late String _encodedLogs;
final _tokenType = 'Bearer '; final _tokenType = 'Bearer ';
late http.Response _response; //use _setResponse() as kind of a private setter
//from web api //from web api
String? _code; String? _code;
@ -74,11 +77,11 @@ class Api {
//session management //session management
requestUserAuthorization(Uri url) async { requestUserAuthorization(Uri url) async {
if (url.queryParameters['state'] == _state.toString()) { if (url.queryParameters['state'] != _state.toString()) {
_code = url.queryParameters['code']; throw ApiException();
await _requestAccessToken();
} }
// TODO : implement the else _code = url.queryParameters['code'];
await _requestAccessToken();
} }
_requestAccessToken() async { _requestAccessToken() async {
@ -89,18 +92,19 @@ class Api {
'client_id': _clientId, 'client_id': _clientId,
'code_verifier': _codeVerifier 'code_verifier': _codeVerifier
}); });
var response = await _client.post(urlToken, headers: <String, String>{ _setResponse(await _client.post(urlToken, headers: <String, String>{
'Authorization': 'Basic $_encodedLogs', 'Authorization': 'Basic $_encodedLogs',
'Content-Type': 'application/x-www-form-urlencoded' 'Content-Type': 'application/x-www-form-urlencoded'
}); }));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map; var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
_accessToken = decodedResponse['access_token']; _accessToken = decodedResponse['access_token'];
_expiresIn = decodedResponse['expires_in']; _expiresIn = decodedResponse['expires_in'];
_tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!)); _tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!));
_refreshToken = decodedResponse['refresh_token']; _refreshToken = decodedResponse['refresh_token'];
} }
Future<String?> _getToken() async { //handle 401 status code (bad or expired token)
Future<String?> _getAccessToken() async {
await _tokenValidity(); await _tokenValidity();
return _accessToken; return _accessToken;
} }
@ -111,16 +115,23 @@ class Api {
} }
} }
_setResponse(value) {
if (value.statusCode != 200) {
throw ApiException();
}
_response = value;
}
_getRefreshedAccessToken() async { _getRefreshedAccessToken() async {
var urlToken = Uri.https('accounts.spotify.com', 'api/token', { var urlToken = Uri.https('accounts.spotify.com', 'api/token', {
'grant_type': 'refresh_token', 'grant_type': 'refresh_token',
'refresh_token': _refreshToken, 'refresh_token': _refreshToken,
'client_id': _clientId 'client_id': _clientId
}); });
var response = await _client.post(urlToken, headers: <String, String>{ _setResponse(await _client.post(urlToken, headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded' 'Content-Type': 'application/x-www-form-urlencoded'
}); }));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map; var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
_accessToken = decodedResponse['access_token']; _accessToken = decodedResponse['access_token'];
_expiresIn = decodedResponse['expires_in']; _expiresIn = decodedResponse['expires_in'];
_tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!)); _tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!));
@ -128,29 +139,40 @@ class Api {
//functional methods //functional methods
Future<String> getCurrentlyPlayingTrack() async { Future<String> getRecentlyPlayedTrack() async {
var url = Uri.https('api.spotify.com', 'v1/me/player/currently-playing'); var url = Uri.https(
var token = await _getToken(); 'api.spotify.com', 'v1/me/player/recently-played', {'limit': '1'});
var response = await _client.get(url, headers: <String, String>{ var token = await _getAccessToken();
_setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token', 'Authorization': '$_tokenType $token',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}); }));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map; var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
return decodedResponse['item']['id']; return decodedResponse['items'][0]['track']['id'];
} }
Future<Track> getTrackInfo(String id) async { Future<Track> getTrackInfo(String id) async {
var url = Uri.https('api.spotify.com', 'v1/tracks/$id'); var url = Uri.https('api.spotify.com', 'v1/tracks/$id');
var token = await _getToken(); var token = await _getAccessToken();
var response = await _client.get(url, headers: <String, String>{ _setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token', 'Authorization': '$_tokenType $token',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}); }));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map; var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
return Track( return Track(decodedResponse['artists'][0]['name'], decodedResponse['name'],
decodedResponse['artists'][0]['name'], decodedResponse['album']['images'][0]['url']);
decodedResponse['name'], }
decodedResponse['album']['images']
[decodedResponse['album']['images'].length - 1]['url']); getPlaylists() async {
var url = Uri.https('api.spotify.com', 'v1/me/playlists', {'limit': '50'});
var token = await _getAccessToken();
_setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
dev.log(decodedResponse['items']
.where((element) => element['name'] == 'daflmusic')
.toString());
} }
} }

@ -1,6 +1,9 @@
import 'dart:io'; import 'dart:io';
import 'package:dafl_project_flutter/main.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'dart:developer' as dev;
import '../exceptions/api_exception.dart';
import '../main.dart';
import 'track.dart';
class MyInAppBrowser extends InAppBrowser { class MyInAppBrowser extends InAppBrowser {
var options = InAppBrowserClassOptions( var options = InAppBrowserClassOptions(
@ -24,11 +27,19 @@ class MyInAppBrowser extends InAppBrowser {
@override @override
Future onLoadStart(url) async { Future onLoadStart(url) async {
if (url!.origin + url.path == MyApp.api.redirectUri) { if (url!.origin + url.path == MyApp.api.redirectUri) {
await MyApp.api.requestUserAuthorization(url); try {
/*String id = await MyApp.api.getCurrentlyPlayingTrack(); await MyApp.api.requestUserAuthorization(url);
Track track = await MyApp.api.getTrackInfo(id);
print('${track.artist} ${track.name} ${track.albumImage}');*/ /*String id = await MyApp.api.getRecentlyPlayedTrack();
close(); Track track = await MyApp.api.getTrackInfo(id);
dev.log('${track.artist} ${track.name} ${track.albumImage}');*/
await MyApp.api.getPlaylists();
} on ApiException {
// TODO : add notification to show that an error occured
} finally {
close();
}
} }
} }
} }

@ -0,0 +1,7 @@
import 'dart:developer' as dev;
class ApiException implements Exception {
ApiException() {
dev.log('Api exception raised');
}
}
Loading…
Cancel
Save