Skip to content

Commit

Permalink
Merge pull request #146 from hayribakici/episodes
Browse files Browse the repository at this point in the history
Adds episode API
  • Loading branch information
rinukkusu authored Mar 13, 2023
2 parents 7fd4509 + 8c5e29e commit f48f55f
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 7 deletions.
1 change: 1 addition & 0 deletions lib/spotify.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ part 'src/endpoints/browse.dart';
part 'src/endpoints/categories.dart';
part 'src/endpoints/endpoint_base.dart';
part 'src/endpoints/endpoint_paging.dart';
part 'src/endpoints/episodes.dart';
part 'src/endpoints/me.dart';
part 'src/endpoints/player.dart';
part 'src/endpoints/playlists.dart';
Expand Down
27 changes: 27 additions & 0 deletions lib/src/endpoints/episodes.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2023, hayribakici. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.

part of spotify;

class Episodes extends EndpointBase {
@override
String get _path => 'v1/episodes';

Episodes(SpotifyApiBase api) : super(api);

Future<EpisodeFull> get(String id, [String? market]) async {
assert(id.isNotEmpty, 'No episode id was provided');
var jsonString =
await _api._get('$_path/$id?' + _buildQuery({'market': market}));
return EpisodeFull.fromJson(jsonDecode(jsonString));
}

Future<Iterable<EpisodeFull>> list(List<String> ids,
[String? market]) async {
assert(ids.isNotEmpty, 'No episode id\'s were provided');
var jsonString = await _api._get(
'$_path?' + _buildQuery({'ids': ids.join(','), 'market': market}));
var episodesJson = jsonDecode(jsonString)['episodes'] as Iterable<dynamic>;
return episodesJson.map((json) => EpisodeFull.fromJson(json));
}
}
39 changes: 37 additions & 2 deletions lib/src/models/_models.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 9 additions & 4 deletions lib/src/models/copyright.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ class Copyright extends Object {
/// The copyright text for this album.
String? text;

/// The type of copyright:
/// C = the copyright
/// P = the sound recording (performance) copyright.
String? type;
/// The type of copyright
CopyrightType? type;
}

enum CopyrightType {
/// C = the copyright
C,
/// P = the sound recording (performance) copyright.
P
}
11 changes: 11 additions & 0 deletions lib/src/models/episode.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,14 @@ class Episode extends Object {
factory Episode.fromJson(Map<String, dynamic> json) =>
_$EpisodeFromJson(json);
}

@JsonSerializable(createToJson: false)
class EpisodeFull extends Episode {

EpisodeFull();

Show? show;

factory EpisodeFull.fromJson(Map<String, dynamic> json) =>
_$EpisodeFullFromJson(json);
}
3 changes: 3 additions & 0 deletions lib/src/models/show.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@ class Show {
/// The Spotify URI for the show.
String? uri;

@JsonKey(name: 'total_episodes', defaultValue: 0)
int? totalEpisodes;

factory Show.fromJson(Map<String, dynamic> json) => _$ShowFromJson(json);
}
3 changes: 3 additions & 0 deletions lib/src/spotify_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ abstract class SpotifyApiBase {
Tracks get tracks => _tracks;
late Playlists _playlists;
Playlists get playlists => _playlists;
late Episodes _episodes;
Episodes get episodes => _episodes;
late RecommendationsEndpoint _recommendations;
RecommendationsEndpoint get recommendations => _recommendations;
late Users _users;
Expand All @@ -46,6 +48,7 @@ abstract class SpotifyApiBase {
_albums = Albums(this);
_browse = Browse(this);
_tracks = Tracks(this);
_episodes = Episodes(this);
_playlists = Playlists(this);
_recommendations = RecommendationsEndpoint(this);
_player = PlayerEndpoint(this);
Expand Down
75 changes: 75 additions & 0 deletions test/data/v1/episodes/5Xt5DXGzch68nYYamXrNxZ.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"audio_preview_url": "https://p.scdn.co/mp3-preview/2f37da1d4221f40b9d1a98cd191f4d6f1646ad17",
"description": "A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.",
"html_description": "<p>A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.</p>\n",
"duration_ms": 1686230,
"explicit": true,
"external_urls": {
"spotify": "string"
},
"href": "https://api.spotify.com/v1/episodes/5Xt5DXGzch68nYYamXrNxZ",
"id": "5Xt5DXGzch68nYYamXrNxZ",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228\n",
"height": 300,
"width": 300
}
],
"is_externally_hosted": true,
"is_playable": true,
"language": "en",
"languages": [
"fr",
"en"
],
"name": "Starting Your Own Podcast: Tips, Tricks, and Advice From Anchor Creators",
"release_date": "1981-12-15",
"release_date_precision": "day",
"resume_point": {
"fully_played": true,
"resume_position_ms": 0
},
"type": "episode",
"uri": "spotify:episode:0zLhl3WsOCQHbe1BPTiHgr",
"restrictions": {
"reason": "string"
},
"show": {
"available_markets": [
"string"
],
"copyrights": [
{
"text": "No rights",
"type": "C"
}
],
"description": "hi",
"html_description": "string",
"explicit": true,
"external_urls": {
"spotify": "string"
},
"href": "string",
"id": "string",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228\n",
"height": 300,
"width": 300
}
],
"is_externally_hosted": true,
"languages": [
"string"
],
"media_type": "string",
"name": "The No-Show",
"publisher": "string",
"type": "show",
"uri": "string",
"total_episodes": 1
}

}
87 changes: 87 additions & 0 deletions test/data/v1/me/episodes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"href": "https://api.spotify.com/v1/me/shows?offset=0&limit=20\n",
"limit": 20,
"next": "https://api.spotify.com/v1/me/shows?offset=1&limit=1",
"offset": 0,
"previous": "https://api.spotify.com/v1/me/shows?offset=1&limit=1",
"total": 4,
"items": [
{
"added_at": "2019-08-24T14:15:22Z",
"episode": {
"audio_preview_url": "https://p.scdn.co/mp3-preview/2f37da1d4221f40b9d1a98cd191f4d6f1646ad17",
"description": "A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.\n",
"html_description": "<p>A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.</p>\n",
"duration_ms": 1686230,
"explicit": true,
"external_urls": {
"spotify": "string"
},
"href": "https://api.spotify.com/v1/episodes/5Xt5DXGzch68nYYamXrNxZ",
"id": "5Xt5DXGzch68nYYamXrNxZ",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228\n",
"height": 300,
"width": 300
}
],
"is_externally_hosted": true,
"is_playable": true,
"language": "en",
"languages": [
"fr",
"en"
],
"name": "Starting Your Own Podcast: Tips, Tricks, and Advice From Anchor Creators",
"release_date": "1981-12-15",
"release_date_precision": "day",
"resume_point": {
"fully_played": true,
"resume_position_ms": 0
},
"type": "episode",
"uri": "spotify:episode:0zLhl3WsOCQHbe1BPTiHgr",
"restrictions": {
"reason": "string"
},
"show": {
"available_markets": [
"string"
],
"copyrights": [
{
"text": "string",
"type": "string"
}
],
"description": "string",
"html_description": "string",
"explicit": true,
"external_urls": {
"spotify": "string"
},
"href": "string",
"id": "string",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228\n",
"height": 300,
"width": 300
}
],
"is_externally_hosted": true,
"languages": [
"string"
],
"media_type": "string",
"name": "string",
"publisher": "string",
"type": "show",
"uri": "string",
"total_episodes": 0
}
}
}
]
}
29 changes: 28 additions & 1 deletion test/spotify_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ Future main() async {
expect(show.type, 'show');
expect(show.id, '4AlxqGkkrqe0mfIx3Mi7Xt');
expect(show.name, 'Universo Flutter');
expect(show.totalEpisodes, 26);
});

test('list', () async {
Expand Down Expand Up @@ -174,7 +175,7 @@ Future main() async {
expect(result.item!.name, 'As I Am');
});

test('devices', () async {
test('Devices', () async {
var result = await spotify.player.devices();
expect(result.length, 1);
expect(result.first.id, '5fbb3ba6aa454b5534c4ba43a8c7e8e45a63ad0e');
Expand Down Expand Up @@ -289,6 +290,32 @@ Future main() async {
expect(list[albumIds[1]], isFalse);
expect(list[albumIds[2]], isTrue);
});

group('Episodes', () {
test('getEpisode', () async {
var result = await spotify.episodes.get('5Xt5DXGzch68nYYamXrNxZ');

expect(result.durationMs, 1686230);
expect(result.explicit, true);
expect(result.audioPreviewUrl,
'https://p.scdn.co/mp3-preview/2f37da1d4221f40b9d1a98cd191f4d6f1646ad17');
expect(result.href,
'https://api.spotify.com/v1/episodes/5Xt5DXGzch68nYYamXrNxZ');
expect(result.name,
'Starting Your Own Podcast: Tips, Tricks, and Advice From Anchor Creators');
expect(result.releaseDate, DateTime(1981, 12, 15));
expect(result.type, 'episode');
expect(result.description,
'A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.');
expect(result.show == null, false);

var show = result.show;
expect(show?.copyrights?.first.type, CopyrightType.C);
expect(show?.isExternallyHosted, true);
expect(show?.name, 'The No-Show');
expect(show?.totalEpisodes, 1);
});
});
});

group('Player', () {
Expand Down

0 comments on commit f48f55f

Please sign in to comment.