1 /// 2 /// Pandora messages. 3 /// @file mediaunits/pandora/pandoramessages.cpp - pianod project 4 /// @author Perette Barella 5 /// @date 2020-03-24 6 /// @copyright Copyright 2020 Devious Fish. All rights reserved. 7 /// 8 9 #pragma once 10 11 #include <config.h> 12 13 #include <string> 14 #include <memory> 15 16 #include <parsnip.h> 17 18 #include "musictypes.h" 19 #include "pandoratypes.h" 20 21 namespace Pandora { 22 class Communication; 23 class Song; 24 class Artist; 25 class Station; 26 27 extern const std::string Type_Track; 28 extern const std::string Type_Album; 29 extern const std::string Type_Artist; 30 extern const std::string Type_Station; 31 extern const std::string Type_StationFactory; 32 33 /** Pandora request class. This provides a framework for assembling 34 requests and decoding responses. */ 35 class Request { 36 friend Communication; 37 38 private: 39 /// Where there this request will be routed to within the REST API. 40 const std::string endpoint; 41 42 protected: 43 Source *source; 44 45 Request (Source *src, const char *ep); 46 47 ThingieList extractAssortedThingsFromDictionary (const Parsnip::SerialData &message) const; 48 49 public: 50 virtual bool debug() const; 51 52 /** Convert request into a message as a Parsnip SerialData object. 53 @return SerialData containing serializable form of request. */ 54 virtual Parsnip::SerialData retrieveRequestMessage() const = 0; 55 56 /** Decode a response message, already converted to Parsnip SerialData, 57 into some internal representation. 58 @param message The message to be decoded. */ 59 virtual void extractResponse (const Parsnip::SerialData &message) const = 0; 60 }; 61 62 /// Pandora request class. A request whose response is empty/unimportant. 63 class Notification : public Request { 64 protected: 65 Notification (Source *src, const char *ep); 66 virtual void extractResponse (const Parsnip::SerialData &message) const override; 67 }; 68 69 /// Pandora message: Retrieve version number. We use this as a no-op. 70 class RetrieveVersionRequest : public Request { 71 mutable int result; 72 73 public: 74 RetrieveVersionRequest (Source *src); 75 virtual Parsnip::SerialData retrieveRequestMessage() const override; 76 virtual void extractResponse (const Parsnip::SerialData &message) const override; 77 inline const int getResult() const { 78 return result; 79 } 80 }; 81 82 /// Pandora message: Retrieve station list 83 class RequestStationList : public Request { 84 mutable std::unique_ptr<PlaylistList> results; 85 86 public: 87 RequestStationList (Source *src); 88 virtual Parsnip::SerialData retrieveRequestMessage() const override; 89 virtual void extractResponse (const Parsnip::SerialData &message) const override; 90 inline const PlaylistList &getResponse() const { 91 assert (results); 92 return *results; 93 } 94 }; 95 96 /// Pandora message: create a station 97 class RequestCreateStation : public Request { 98 std::string name; 99 std::string create_from_id; 100 mutable Station *result{nullptr}; 101 102 public: 103 RequestCreateStation (Source *src, const std::string &name, const std::string &creator_pandora_id); 104 virtual Parsnip::SerialData retrieveRequestMessage() const override; 105 virtual void extractResponse (const Parsnip::SerialData &message) const override; 106 inline Station *getResponse() const { 107 assert (result); 108 return result; 109 } 110 }; 111 112 /// Pandora message: delete a station 113 class RequestRemoveStation : public Request { 114 std::string station_id; 115 116 public: 117 RequestRemoveStation (Source *src, Station *station); 118 virtual Parsnip::SerialData retrieveRequestMessage() const override; 119 virtual void extractResponse (const Parsnip::SerialData &message) const override; 120 }; 121 122 /// Pandora message: transform a shared station into a personal station 123 class RequestTransformStation : public Request { 124 std::string station_id; 125 mutable Station *updated_info{nullptr}; 126 127 public: 128 RequestTransformStation (Source *src, Station *station); 129 virtual Parsnip::SerialData retrieveRequestMessage() const override; 130 virtual void extractResponse (const Parsnip::SerialData &message) const override; 131 inline const Station *getUpdatedStation() const { 132 assert (updated_info); 133 return updated_info; 134 } 135 }; 136 137 /// Pandora message: rename a station 138 class RequestRenameStation : public Request { 139 std::string station_id; 140 std::string name; 141 142 public: 143 RequestRenameStation (Source *src, Station *station, const std::string &new_name); 144 virtual Parsnip::SerialData retrieveRequestMessage() const override; 145 virtual void extractResponse (const Parsnip::SerialData &message) const override; 146 }; 147 148 /// Pandora message: Retrieve station seeds 149 class RequestStationSeeds : public Request { 150 protected: 151 std::string station_id; 152 mutable std::unique_ptr<ThingieList> seeds; 153 MusicThingie *extractAssortedSeed (const Parsnip::SerialData &seed_info) const; 154 RequestStationSeeds (Source *src, const char *endpoint, Station *station); 155 156 public: 157 RequestStationSeeds (Source *src, Station *station); 158 virtual Parsnip::SerialData retrieveRequestMessage() const override; 159 virtual void extractResponse (const Parsnip::SerialData &message) const override; 160 inline const ThingieList &getSeeds() const { 161 assert (seeds); 162 return *seeds; 163 } 164 }; 165 166 /// Pandora message: Retrieve station details (seeds and a few other goodies) 167 class RequestStationDetails : public RequestStationSeeds { 168 mutable int positive_feedback{-1}; 169 mutable int negative_feedback{-1}; 170 171 public: 172 RequestStationDetails (Source *src, Station *station); 173 virtual Parsnip::SerialData retrieveRequestMessage() const override; 174 virtual void extractResponse (const Parsnip::SerialData &message) const override; 175 inline const bool positiveFeedback() const { 176 assert (positive_feedback >= 0); 177 return positive_feedback; 178 } 179 inline const bool negativeFeedback() const { 180 assert (negative_feedback >= 0); 181 return negative_feedback; 182 } 183 }; 184 185 /// Pandora message: Add or remove station seeds 186 class RequestAlterStationSeed : public Request { 187 std::string station_id; 188 std::string seed_id; 189 190 public: 191 RequestAlterStationSeed (Source *src, Station *station, const std::string &id, bool add); 192 virtual Parsnip::SerialData retrieveRequestMessage() const override; 193 virtual void extractResponse (const Parsnip::SerialData &message) const override; 194 }; 195 196 /// Pandora message: Retrieve station feedback (ratings) 197 class RequestStationFeedback : public Request { 198 std::string station_id; 199 bool positive; 200 mutable std::unique_ptr<SongList> results; 201 202 public: 203 RequestStationFeedback (Source *src, Station *station, bool positive); 204 virtual Parsnip::SerialData retrieveRequestMessage() const override; 205 virtual void extractResponse (const Parsnip::SerialData &message) const override; 206 inline const SongList &getResponse() const { 207 assert (results); 208 return *results; 209 } 210 }; 211 212 /// Pandora message: Provide feedback for a song on a station. 213 class RequestAddTiredSong : public Request { 214 const std::string track_token; 215 216 public: 217 RequestAddTiredSong (Source *src, const std::string &token); 218 virtual Parsnip::SerialData retrieveRequestMessage() const override; 219 virtual void extractResponse (const Parsnip::SerialData &message) const override; 220 }; 221 222 /// Pandora message: Provide feedback for a song that has played on a station. 223 class RequestAddFeedback : public Request { 224 const std::string track_token; 225 const bool positive; 226 mutable std::unique_ptr<std::string> feedback_id; 227 228 public: 229 RequestAddFeedback (Source *src, const std::string &token, bool like); 230 virtual Parsnip::SerialData retrieveRequestMessage() const override; 231 virtual void extractResponse (const Parsnip::SerialData &message) const override; 232 inline const std::string &getResponse() const { 233 assert (feedback_id); 234 return *feedback_id; 235 } 236 }; 237 238 /// Pandora message: Remove feedback for a song on a station. 239 class RequestDeleteFeedback : public Request { 240 const std::string feedback_id; 241 const bool positive; 242 243 public: 244 RequestDeleteFeedback (Source *src, const std::string &feedback, bool like); 245 virtual Parsnip::SerialData retrieveRequestMessage() const override; 246 virtual void extractResponse (const Parsnip::SerialData &message) const override; 247 }; 248 249 /// Pandora message: Retrieve list of music to play from a station. 250 class RequestQueueTracks : public Request { 251 const std::string station_id; 252 const PlayableSong *last_play; 253 mutable std::unique_ptr<SongList> results; 254 255 public: 256 RequestQueueTracks (Source *src, const Station *station, const PlayableSong *last); 257 virtual Parsnip::SerialData retrieveRequestMessage() const override; 258 virtual void extractResponse (const Parsnip::SerialData &message) const override; 259 inline const SongList &getResponse() { 260 assert (results); 261 return *results; 262 } 263 }; 264 265 /// Pandora message: Retrieve list of music to play from a station. 266 class RequestTrackReplay : public Request { 267 const PlayableSong *request; 268 const PlayableSong *last_played; 269 mutable PlayableSong *result; 270 public: 271 RequestTrackReplay (Source *src, const PlayableSong *song, const PlayableSong *current); 272 virtual Parsnip::SerialData retrieveRequestMessage() const override; 273 virtual void extractResponse (const Parsnip::SerialData &message) const override; 274 inline PlayableSong *getResponse() { 275 assert (result); 276 return result; 277 } 278 }; 279 280 /// Pandora message: Notify servers of playback start 281 class PlaybackStartNotification : public Notification { 282 std::string track_token; 283 284 public: 285 PlaybackStartNotification (Source *src, const PlayableSong *song); 286 virtual Parsnip::SerialData retrieveRequestMessage() const override; 287 }; 288 289 /// Pandora message: Notify servers of pausing playback 290 class PlaybackPauseNotification : public Notification { 291 public: 292 PlaybackPauseNotification (Source *src, const PlayableSong * = nullptr); 293 virtual Parsnip::SerialData retrieveRequestMessage() const override; 294 }; 295 296 /// Pandora message: Notify servers of playback resumption 297 class PlaybackResumedNotification : public Notification { 298 public: 299 PlaybackResumedNotification (Source *src, const PlayableSong * = nullptr); 300 virtual Parsnip::SerialData retrieveRequestMessage() const override; 301 }; 302 303 // Pandora message: Search request. 304 class SearchRequest : public Request { 305 std::string query; 306 std::string desired_type; 307 mutable std::unique_ptr<std::vector<std::string> > results; 308 309 public: 310 static const std::string Type_ANY; 311 SearchRequest (Source *src, const std::string &q, const std::string &type = Type_ANY); 312 virtual Parsnip::SerialData retrieveRequestMessage() const override; 313 virtual void extractResponse (const Parsnip::SerialData &message) const override; 314 inline const std::vector<std::string> &getResponse() { 315 assert (results); 316 return *results; 317 } 318 }; 319 320 // Pandora message: retrieve details about songs, artists, albums, whatever. 321 class RetrieveAnnotations : public Request { 322 const std::vector<std::string> retrieval_items; 323 324 protected: 325 mutable std::unique_ptr<ThingieList> results; 326 327 public: 328 RetrieveAnnotations (Source *src, const std::vector<std::string> &items); 329 virtual Parsnip::SerialData retrieveRequestMessage() const override; 330 virtual void extractResponse (const Parsnip::SerialData &message) const override; 331 inline const ThingieList &getAnnotations() { 332 assert (results); 333 return *results; 334 } 335 }; 336 337 // Pandora message: retrieve details about a single song, artist, album, whatever. 338 class RetrieveSingleAnnotation : public RetrieveAnnotations { 339 const std::vector<std::string> retrieval_items; 340 341 public: 342 RetrieveSingleAnnotation (Source *src, const std::string &item); 343 inline MusicThingie *getAnnotation() { 344 assert (results); 345 assert (results->size() == 1); 346 return (*results).front(); 347 } 348 }; 349 350 351 // Pandora message: retrieve advertisements. 352 class RetrieveAdverts : public Request { 353 PlayableSong *last_song; 354 Station *station; 355 mutable std::unique_ptr <SongList> adverts; 356 public: 357 RetrieveAdverts (Source *src, PlayableSong *last_play, Station *sta); 358 virtual Parsnip::SerialData retrieveRequestMessage() const override; 359 virtual void extractResponse (const Parsnip::SerialData &message) const override; 360 inline SongList &getAdverts () { 361 assert (adverts); 362 return *adverts; 363 } 364 }; 365 } // namespace Pandora 366