Discman
Loading...
Searching...
No Matches
album_art_provider.cc
Go to the documentation of this file.
1
6
8#include "last_fm.h"
9#include "spotify.h"
10
12
14 if (_instance == nullptr) {
15 std::vector<std::string> providers = {
16 "lastfm",
17 "spotify"
18 };
19
20 std::string provider = std::getenv("DISCMAN_ALBUMART_PROVIDER")
21 ? std::getenv("DISCMAN_ALBUMART_PROVIDER")
22 : "";
23
24 std::transform(provider.begin(), provider.end(), provider.begin(), [](unsigned char c) {
25 return std::tolower(c);
26 });
27
28 auto it = std::find(providers.begin(), providers.end(), provider);
29
30 int providerIndex = std::distance(providers.begin(), it);
31
32 switch (providerIndex) {
33 case 0:
34 try {
35 _instance = new LastFM;
36 break;
37 } catch (std::exception&) {
38
39 }
40 default:
41 case 1:
42 try {
43 _instance = new Spotify;
44 } catch (std::exception&) {
45 _instance = new LastFM;
46 }
47 break;
48 }
49 }
50
51 return _instance;
52}
53
55 if (_instance) delete _instance;
56}
57
59
60}
61
62
63
64AlbumArtProvider::AlbumArt AlbumArtProvider::album_art(const std::string& url, const int width, const int height) {
65 cURLpp::Cleanup cleanup;
66 cURLpp::Easy easyhandle;
67
68 std::stringstream ss;
69 easyhandle.setOpt(cURLpp::Options::Url(url));
70 easyhandle.setOpt(cURLpp::Options::WriteStream(&ss));
71 easyhandle.perform();
72
73 std::string data = ss.str();
74 Glib::RefPtr<Glib::Bytes> bytes = Glib::Bytes::create(data.c_str(), data.size());
75 Glib::RefPtr<Gio::MemoryInputStream> is = Gio::MemoryInputStream::create();
76 is->add_bytes(bytes);
77
79 .art = Gdk::Pixbuf::create_from_stream_at_scale(is, width, height, true),
80 .url = url
81 };
82
83 return art;
84}
85
86std::string AlbumArtProvider::url_with_params(const std::string& url, const std::map<std::string, std::string>& params) {
87 std::string new_url(url);
88 if (new_url[new_url.length() - 1] != '/') new_url += '/';
89
90 std::stringstream ss;
91 ss << new_url;
92 for (std::map<std::string, std::string>::const_iterator it=params.cbegin(); it!=params.cend(); ++it) {
93 ss << (it == params.cbegin() ? '?' : '&');
94
95 ss << it->first << '=' << url_encode(it->second);
96 }
97
98 return ss.str();
99}
100
101std::string AlbumArtProvider::url_encode(const std::string& input) {
102 std::stringstream escaped;
103 escaped.fill('0');
104 escaped << std::hex;
105
106 for (std::string::const_iterator i = input.begin(), n = input.end(); i != n; ++i) {
107 const std::string::value_type c = (*i);
108
109 if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
110 escaped << c;
111 continue;
112 } else if (c == ' ') {
113 escaped << '+';
114 continue;
115 }
116
117 escaped << std::uppercase;
118 escaped << '%' << std::setw(2) << int((unsigned char) c);
119 escaped << std::nouppercase;
120 }
121
122 return escaped.str();
123}
Abstracts web services that provide album art images.
virtual std::vector< AlbumArt > album_art(const std::string &artist, const std::string &title, const int width, const int height)=0
Return all album art matching the criteria, at a specific width and height.
virtual void init()
Initializes the AlbumArtProvider (i.e. retrieve an API key).
static AlbumArtProvider * _instance
The global AlbumArtProvider instance.
static std::string url_encode(const std::string &input)
Encodes an arbitrary string into a query parameter value.
static void destroy()
Destroys the AlbumArtProvider.
AlbumArtProvider()
AlbumArtProvider constructor.
static AlbumArtProvider * instance()
Factory method to return the album art provider. It may be called one or more times....
static std::string url_with_params(const std::string &url, const std::map< std::string, std::string > &params)
Returns the URL of the API endpoint with the given parameters encoded as query parameters.
An interface to last.fm for retrieving album art.
Definition last_fm.h:31
An interface to Spotify for retrieving album art.
Definition spotify.h:31
An album art image and its URL.