diff --git a/Sources/justMUSIC/lib/model/Artist.dart b/Sources/justMUSIC/lib/model/Artist.dart new file mode 100644 index 0000000..847ab48 --- /dev/null +++ b/Sources/justMUSIC/lib/model/Artist.dart @@ -0,0 +1,17 @@ +class Artist { + String _id; + String? _name; + String? _image; + + Artist(this._id, this._name, this._image); + + String? get id => _id; + + String? get name => _name; + + String? get image => _image; + + set image(String? value) { + _image = value; + } +} diff --git a/Sources/justMUSIC/lib/model/Comment.dart b/Sources/justMUSIC/lib/model/Comment.dart new file mode 100644 index 0000000..4c8d269 --- /dev/null +++ b/Sources/justMUSIC/lib/model/Comment.dart @@ -0,0 +1,24 @@ +class Comment { + final int _id; + String _text; + DateTime _date; + List comments = []; + + // Constructor + Comment(this._id, this._text, this._date); + + // Getters and setters + int get id => _id; + + String get text => _text; + + set text(String value) { + _text = value; + } + + DateTime get date => _date; + + set date(DateTime value) { + _date = value; + } +} diff --git a/Sources/justMUSIC/lib/model/Music.dart b/Sources/justMUSIC/lib/model/Music.dart new file mode 100644 index 0000000..ff3c685 --- /dev/null +++ b/Sources/justMUSIC/lib/model/Music.dart @@ -0,0 +1,47 @@ +import 'Artist.dart'; + +class Music { + final String _id; + String? _title; + String? _cover; + String? _previewUrl; + DateTime? _date; + List _artists; + + // Constructor + Music(this._id, this._title, this._cover, this._previewUrl, this._date, + this._artists); + + //Getters and setters + String? get id => _id; + + String? get title => _title; + + set title(String? value) { + _title = value; + } + + String? get cover => _cover; + + set cover(String? value) { + _cover = value; + } + + String? get previewUrl => _previewUrl; + + set previewUrl(String? value) { + _previewUrl = value; + } + + DateTime? get date => _date; + + set date(DateTime? value) { + _date = value; + } + + List get artists => _artists; + + set artists(List value) { + _artists = value; + } +} diff --git a/Sources/justMUSIC/lib/model/Post.dart b/Sources/justMUSIC/lib/model/Post.dart new file mode 100644 index 0000000..0c248dd --- /dev/null +++ b/Sources/justMUSIC/lib/model/Post.dart @@ -0,0 +1,55 @@ +class Post { + final int _id; + final int _idUser; + String? _description; + String _idMusic; + String _location; + int _nblikes; + String? _selfie; + DateTime _date; + + // Constructor + Post(this._id, this._idUser, this._description, this._idMusic, this._location, + this._nblikes, this._selfie, this._date); + + //Getters and setters + int get id => _id; + + int get idUser => _idUser; + + String? get description => _description; + + set description(String? value) { + _description = value; + } + + String get idMusic => _idMusic; + + set idMusic(String value) { + _idMusic = value; + } + + String get location => _location; + + set location(String value) { + _location = value; + } + + int get nblikes => _nblikes; + + set nblikes(int value) { + _nblikes = value; + } + + String? get selfie => _selfie; + + set selfie(String? value) { + _selfie = value; + } + + DateTime get date => _date; + + set date(DateTime value) { + _date = value; + } +} diff --git a/Sources/justMUSIC/lib/model/User.dart b/Sources/justMUSIC/lib/model/User.dart new file mode 100644 index 0000000..f9a7607 --- /dev/null +++ b/Sources/justMUSIC/lib/model/User.dart @@ -0,0 +1,38 @@ +class User { + final int _id; + String _pseudo; + String _country; + String _mail; + String _pp; + List friends = []; + + // Constructor + User(this._id, this._pseudo, this._country, this._mail, this._pp); + + //Getters and setters + int get id => _id; + + String get pseudo => _pseudo; + + set pseudo(String value) { + _pseudo = value; + } + + String get country => _country; + + set country(String value) { + _country = value; + } + + String get mail => _mail; + + set mail(String value) { + _mail = value; + } + + String get pp => _pp; + + set pp(String value) { + _pp = value; + } +} diff --git a/Sources/justMUSIC/lib/view_model/CommentViewModel.dart b/Sources/justMUSIC/lib/view_model/CommentViewModel.dart new file mode 100644 index 0000000..f4684e1 --- /dev/null +++ b/Sources/justMUSIC/lib/view_model/CommentViewModel.dart @@ -0,0 +1,8 @@ +import '../model/Comment.dart'; + +class CommentViewModel { + // Methods + List getCommentsPost(int idPost) { + throw new Error(); + } +} diff --git a/Sources/justMUSIC/lib/view_model/MusicViewModel.dart b/Sources/justMUSIC/lib/view_model/MusicViewModel.dart new file mode 100644 index 0000000..514155b --- /dev/null +++ b/Sources/justMUSIC/lib/view_model/MusicViewModel.dart @@ -0,0 +1,96 @@ +import 'dart:convert'; + +import 'package:justmusic/view_model/TokenSpotify.dart'; +import 'package:http/http.dart' as http; +import '../model/Artist.dart'; +import '../model/Music.dart'; + +class MusicViewModel { + final String API_URL = "https://api.spotify.com/v1"; + late TokenSpotify _token; + + MusicViewModel() { + _token = new TokenSpotify(); + } + + // Methods + Future getMusic(String id) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get(Uri.parse('$API_URL/tracks/$id'), headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + final responseData = jsonDecode(response.body); + List artists = + List.from(responseData['artists'].map((artist) { + return Artist(artist['id'], artist['name'],''); + })); + + return Music( + responseData['id'], + responseData['name'], + responseData['album']['images'][0]['url'], + responseData['preview_url'], + DateTime.parse(responseData['album']['release_date']), + artists); + } else { + throw Exception( + 'Error retrieving music information : ${response.statusCode} ${response.reasonPhrase}'); + } + } + + List _getMusicsFromResponse(Map responseData) { + List musics = []; + + List tracks = responseData['tracks']['items']; + for (var track in tracks) { + List artists = List.from(track['artists'].map((artist) { + return Artist(artist['id'], artist['name'],''); + })); + + musics.add(Music( + track['id'], + track['name'], + track['album']['images'][0]['url'], + track['preview_url'], + DateTime.now(), + artists)); + } + + return musics; + } + + Future> getMusicsWithName(String name, {int limit = 20, int offset = 0, String market = "FR"}) async { + var accessToken = await _token.getAccessToken(); + var response = await http + .get(Uri.parse('$API_URL/search?q=track%3A$name&type=track&market=fr&limit=$limit&offset=$offset'), headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + Map responseData = jsonDecode(response.body); + return _getMusicsFromResponse(responseData); + } else { + throw Exception( + 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); + } + } + + Future> getMusicsWithArtistName(String name, {int limit = 20, int offset = 0, String market = "FR"}) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get( + Uri.parse('$API_URL/search?q=artist%3A$name&type=track&market=fr&limit=$limit&offset=$offset'), + headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + Map responseData = jsonDecode(response.body); + return _getMusicsFromResponse(responseData); + } else { + throw Exception( + 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); + } + } +} diff --git a/Sources/justMUSIC/lib/view_model/PostViewModel.dart b/Sources/justMUSIC/lib/view_model/PostViewModel.dart new file mode 100644 index 0000000..d1bcca3 --- /dev/null +++ b/Sources/justMUSIC/lib/view_model/PostViewModel.dart @@ -0,0 +1,31 @@ +import 'package:justmusic/model/Post.dart'; + +class PostViewModel { + List _postsFriends = []; + List _bestPosts = []; + + // Constructor + PostViewModel(); + + // Getters and setters + List get postsFriends => _postsFriends; + + List get bestPosts => _bestPosts; + + // Methods + List getPostsFriends() { + throw new Error(); + } + + List getMorePostsFriends() { + throw new Error(); + } + + List getBestPosts() { + throw new Error(); + } + + List getMoreBestPosts() { + throw new Error(); + } +} diff --git a/Sources/justMUSIC/lib/view_model/TokenSpotify.dart b/Sources/justMUSIC/lib/view_model/TokenSpotify.dart new file mode 100644 index 0000000..a221129 --- /dev/null +++ b/Sources/justMUSIC/lib/view_model/TokenSpotify.dart @@ -0,0 +1,45 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; + +class TokenSpotify { + final String clientId = 'd9b82921bbdf43efa15d0c34c28c6f93'; + final String _clientSecret = 'ba01687f59ea4ab7ad00c769e89e44d8'; + late String _accessToken; + late DateTime _tokenEnd; + + TokenSpotify() { + _tokenEnd = DateTime.now().add(Duration(seconds: -10)); + } + + Future getAccessToken() async { + if (_isTokenExpired()) { + await _refreshToken(); + } + return _accessToken; + } + + _refreshToken() async { + final basicAuth = base64Encode(utf8.encode('$clientId:$_clientSecret')); + final response = await http.post( + Uri.parse('https://accounts.spotify.com/api/token'), + headers: { + 'Authorization': 'Basic $basicAuth', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: 'grant_type=client_credentials', + ); + + if (response.statusCode == 200) { + final responseData = jsonDecode(response.body); + _accessToken = responseData['access_token']; + _tokenEnd = + DateTime.now().add(Duration(seconds: responseData['expires_in'])); + } else { + print('Error refreshing token : ${response.statusCode}'); + } + } + + bool _isTokenExpired() { + return DateTime.now().isAfter(_tokenEnd); + } +} diff --git a/Sources/justMUSIC/lib/view_model/UserViewModel.dart b/Sources/justMUSIC/lib/view_model/UserViewModel.dart new file mode 100644 index 0000000..bea7efd --- /dev/null +++ b/Sources/justMUSIC/lib/view_model/UserViewModel.dart @@ -0,0 +1,13 @@ +import '../model/User.dart'; + +class UserViewModel { + User? _userCurrent; + + // Constructor + UserViewModel(); + + // Methods + User getUser(int id) { + throw new Error(); + } +} diff --git a/Sources/justMUSIC/pubspec.yaml b/Sources/justMUSIC/pubspec.yaml index 0be4218..c84080c 100644 --- a/Sources/justMUSIC/pubspec.yaml +++ b/Sources/justMUSIC/pubspec.yaml @@ -31,6 +31,7 @@ environment: dependencies: flutter: sdk: flutter + http: ^0.13.5 # The following adds the Cupertino Icons font to your application. diff --git a/Sources/justMUSIC/test/Music_test.dart b/Sources/justMUSIC/test/Music_test.dart new file mode 100644 index 0000000..eab5022 --- /dev/null +++ b/Sources/justMUSIC/test/Music_test.dart @@ -0,0 +1,36 @@ +import 'package:justmusic/model/Artist.dart'; +import 'package:justmusic/model/Music.dart'; +import 'package:justmusic/view_model/MusicViewModel.dart'; + +Future main() async { + MusicViewModel musicVM = new MusicViewModel(); + Music m = await musicVM.getMusic('295SxdR1DqunCNwd0U767w'); + + print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); + print("date : ${m.date.toString()}, preview : ${m.previewUrl}"); + for (Artist a in m.artists) { + print("id : ${a.id}, name : ${a.name}"); + } + + print('\nMusics :'); + + List musics = await musicVM.getMusicsWithName('Shavkat'); + for (Music m in musics) { + print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); + print("date : ${m.date.toString()}, preview : ${m.previewUrl}"); + for (Artist a in m.artists) { + print("id : ${a.id}, name : ${a.name}"); + } + } + + print('\nMusics With Artist:'); + + List musics2 = await musicVM.getMusicsWithArtistName('jul'); + for (Music m in musics2) { + print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); + print("date : ${m.date.toString()}, preview : ${m.previewUrl}"); + for (Artist a in m.artists) { + print("id : ${a.id}, name : ${a.name}"); + } + } +}