Skip to content

Commit

Permalink
Initial support for podcasts, fixes #110
Browse files Browse the repository at this point in the history
  • Loading branch information
kraxarn committed Oct 2, 2021
1 parent 56e9ac7 commit 51962d4
Show file tree
Hide file tree
Showing 22 changed files with 562 additions and 7 deletions.
13 changes: 13 additions & 0 deletions lib/include/lib/spotify/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "lib/spotify/track.hpp"
#include "lib/spotify/audiofeatures.hpp"
#include "lib/spotify/savedalbum.hpp"
#include "lib/spotify/episode.hpp"
#include "lib/spotify/callback.hpp"
#include "lib/httpclient.hpp"
#include "lib/datetime.hpp"
Expand Down Expand Up @@ -270,6 +271,18 @@ namespace lib

//endregion

//region Shows

/** Get a show */
void show(const std::string &show_id,
lib::callback<lib::spt::show> &callback);

/** Get episodes in a show */
void show_episodes(const lib::spt::show &show,
lib::callback<std::vector<lib::spt::episode>> &callback);

//endregion

/**
* Refresh access token with refresh token
* @return Refresh was successful
Expand Down
5 changes: 5 additions & 0 deletions lib/include/lib/spotify/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ namespace lib
public:
entity() = default;

/**
* Manually construct a entity
*/
entity(std::string id, std::string name);

/**
* Entity ID
*/
Expand Down
102 changes: 102 additions & 0 deletions lib/include/lib/spotify/episode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#pragma once

#include "lib/spotify/entity.hpp"
#include "lib/json.hpp"
#include "lib/spotify/track.hpp"
#include "lib/spotify/show.hpp"

namespace lib
{
namespace spt
{
/**
* A specific episode of a show
*/
class episode: public entity
{
public:
/**
* 30 second MP3 preview
*/
std::string audio_preview_url;

/**
* Description in plain text
*/
std::string description;

/**
* Length in milliseconds
*/
int duration_ms = 0;

/**
* If episode has explicit content
* @note false if unknown
*/
bool is_explicit = false;

/**
* External URLs
*/
std::map<std::string, std::string> external_urls;

/**
* Link ot the Web API endpoint
*/
std::string href;

/**
* Description in HTML
*/
std::string html_description;

/**
* URL to cover art
*/
std::string image;

/**
* Hosted outside of Spotify's CDN
*/
bool is_externally_hosted = false;

/**
* Playable in current market
*/
bool is_playable = false;

/**
* Languages used in ISO 639 codes
*/
std::vector<std::string> languages;

/**
* Date when first released
* @note Varying precision
*/
std::string release_date;

/**
* Precision of release_date
*/
std::string release_date_precision;

/**
* Spotify URI
*/
std::string uri;

/**
* Convert to track entity, mostly for compatibility
*/
auto to_track(const lib::spt::show &show) const -> lib::spt::track;
};

/** Episode -> JSON */
void to_json(nlohmann::json &j, const episode &e);

/** JSON -> Episode */
void from_json(const nlohmann::json &j, episode &e);
}
}
6 changes: 6 additions & 0 deletions lib/include/lib/spotify/searchresults.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "lib/spotify/artist.hpp"
#include "lib/spotify/playlist.hpp"
#include "lib/spotify/track.hpp"
#include "lib/spotify/show.hpp"

#include <vector>

Expand Down Expand Up @@ -38,6 +39,11 @@ namespace lib
* Playlists found
*/
std::vector<lib::spt::playlist> playlists;

/**
* Shows/podcasts found
*/
std::vector<lib::spt::show> shows;
};

/**
Expand Down
86 changes: 86 additions & 0 deletions lib/include/lib/spotify/show.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#pragma once

#include "lib/spotify/entity.hpp"
#include "lib/enum/mediatype.hpp"
#include "lib/json.hpp"
#include "lib/enums.hpp"

namespace lib
{
namespace spt
{
/**
* A show with episodes
*/
class show: public entity
{
public:
/**
* Countries, in ISO 3166, which show can be played in
*/
std::vector<std::string> available_markets;

/**
* Description in plain text
*/
std::string description;

/**
* If show has explicit content
* @note false if unknown
*/
bool is_explicit = false;

/**
* External URLs
*/
std::map<std::string, std::string> external_urls;

/**
* Link to the Web API endpoint
*/
std::string href;

/**
* Description in HTML
*/
std::string html_description;

/**
* Cover art
*/
std::string image;

/**
* Hosted outside of Spotify's CDN
*/
bool is_externally_hosted = false;

/**
* Languages used
*/
std::vector<std::string> languages;

/**
* Media type
*/
lib::media_type media_type;

/**
* Publisher
*/
std::string publisher;

/**
* Spotify URI
*/
std::string uri;
};

/** Show -> JSON */
void to_json(nlohmann::json &j, const show &s);

/** JSON -> Show */
void from_json(const nlohmann::json &j, show &s);
}
}
9 changes: 8 additions & 1 deletion lib/src/spotify/entity.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
#include "lib/spotify/entity.hpp"
#include <utility>

lib::spt::entity::entity(std::string id, std::string name)
: id(std::move(id)),
name(std::move(name))
{
}

void lib::spt::to_json(nlohmann::json &j, const entity &e)
{
Expand Down Expand Up @@ -44,7 +51,7 @@ auto lib::spt::entity::combine_names(const std::vector<entity> &entities,
{
std::vector<std::string> names;
names.reserve(entities.size());
for (const auto &entity : entities)
for (const auto &entity: entities)
{
names.push_back(entity.name);
}
Expand Down
66 changes: 66 additions & 0 deletions lib/src/spotify/episode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "lib/spotify/episode.hpp"

void lib::spt::to_json(nlohmann::json &j, const episode &e)
{
j = nlohmann::json{
{"audio_preview_url", e.audio_preview_url},
{"description", e.description},
{"duration_ms", e.duration_ms},
{"explicit", e.is_explicit},
{"external_urls", e.external_urls},
{"href", e.href},
{"html_description", e.html_description},
{"id", e.id},
{"image", e.image},
{"is_externally_hosted", e.is_externally_hosted},
{"is_playable", e.is_playable},
{"languages", e.languages},
{"name", e.name},
{"release_date", e.release_date},
{"release_date_precision", e.release_date_precision},
{"uri", e.uri},
};
}

void lib::spt::from_json(const nlohmann::json &j, episode &e)
{
if (!j.is_object())
{
return;
}

j.at("audio_preview_url").get_to(e.audio_preview_url);
j.at("description").get_to(e.description);
j.at("duration_ms").get_to(e.duration_ms);
j.at("explicit").get_to(e.is_explicit);
j.at("external_urls").get_to(e.external_urls);
j.at("href").get_to(e.href);
j.at("html_description").get_to(e.html_description);
j.at("id").get_to(e.id);
j.at("is_externally_hosted").get_to(e.is_externally_hosted);
j.at("is_playable").get_to(e.is_playable);
j.at("languages").get_to(e.languages);
j.at("name").get_to(e.name);
j.at("release_date").get_to(e.release_date);
j.at("release_date_precision").get_to(e.release_date_precision);
j.at("uri").get_to(e.uri);

lib::json::find_item("image", j, e.image);
}

auto lib::spt::episode::to_track(const lib::spt::show &show) const -> lib::spt::track
{
lib::spt::track track;

track.id = id;
track.album.name = show.name;
track.artists.emplace_back(std::string(), show.publisher);
track.name = name;
track.image = show.image;
track.duration = duration_ms;
track.is_local = false;
track.is_playable = is_playable;
track.added_at = release_date;

return track;
}
2 changes: 2 additions & 0 deletions lib/src/spotify/searchresults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ void lib::spt::to_json(nlohmann::json &j, const search_results &s)
{"artists", s.artists},
{"tracks", s.tracks},
{"playlists", s.playlists},
{"shows", s.shows},
};
}

Expand All @@ -21,4 +22,5 @@ void lib::spt::from_json(const nlohmann::json &j, search_results &s)
j.at("artists").at("items").get_to(s.artists);
j.at("playlists").at("items").get_to(s.playlists);
j.at("tracks").at("items").get_to(s.tracks);
j.at("shows").at("items").get_to(s.shows);
}
45 changes: 45 additions & 0 deletions lib/src/spotify/show.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "lib/spotify/show.hpp"

void lib::spt::to_json(nlohmann::json &j, const show &s)
{
j = nlohmann::json{
{"available_markets", s.available_markets},
{"description", s.description},
{"explicit", s.is_explicit},
{"external_urls", s.external_urls},
{"href", s.href},
{"html_description", s.html_description},
{"image", s.image},
{"is_externally_hosted", s.is_externally_hosted},
{"languages", s.languages},
{"media_type", lib::enums<lib::media_type>::to_string(s.media_type)},
{"publisher", s.publisher},
{"uri", s.uri},
};
}

void lib::spt::from_json(const nlohmann::json &j, show &s)
{
if (!j.is_object())
{
return;
}

j.at("available_markets").get_to(s.available_markets);
j.at("description").get_to(s.description);
j.at("explicit").get_to(s.is_explicit);
j.at("external_urls").get_to(s.external_urls);
j.at("href").get_to(s.href);
j.at("html_description").get_to(s.html_description);
j.at("id").get_to(s.id);
j.at("is_externally_hosted").get_to(s.is_externally_hosted);
j.at("languages").get_to(s.languages);
j.at("name").get_to(s.name);
j.at("publisher").get_to(s.publisher);
j.at("uri").get_to(s.uri);

lib::json::find_item("image", j, s.image);

const auto &media_type = j.at("media_type").get<std::string>();
s.media_type = lib::enums<lib::media_type>::parse(media_type);
}
Loading

0 comments on commit 51962d4

Please sign in to comment.