From 0abdf545a00fb7bff3b6a67e382023b66a4ceecc Mon Sep 17 00:00:00 2001 From: Andreas Date: Sat, 13 Jun 2015 16:00:15 +0200 Subject: [PATCH] Network remote: Insert Song as well as urls. Is used for global search to add metadata for non library tracks. --- .../remotecontrolmessages.proto | 24 +++++++- src/networkremote/incomingdataparser.cpp | 55 ++++++++++++++++--- src/networkremote/incomingdataparser.h | 4 ++ src/networkremote/outgoingdatacreator.cpp | 3 + src/playlist/playlistmanager.cpp | 7 +++ src/playlist/playlistmanager.h | 2 + 6 files changed, 86 insertions(+), 9 deletions(-) diff --git a/ext/libclementine-remote/remotecontrolmessages.proto b/ext/libclementine-remote/remotecontrolmessages.proto index b96e9fadf..f28a78894 100644 --- a/ext/libclementine-remote/remotecontrolmessages.proto +++ b/ext/libclementine-remote/remotecontrolmessages.proto @@ -69,6 +69,24 @@ enum EngineState { // Song Metadata message SongMetadata { + enum Type { + UNKNOWN = 0; + ASF = 1; + FLAC = 2; + MP4 = 3; + MPC = 4; + MPEG = 5; + OGGFLAC = 6; + OGGSPEEX = 7; + OGGVORBIS = 8; + AIFF = 9; + WAV = 10; + TRUEAUDIO = 11; + CDDA = 12; + OGGOPUS = 13; + STREAM = 99; + } + optional int32 id = 1; // unique id of the song optional int32 index = 2; // Index of the current row of the active playlist optional string title = 3; @@ -88,6 +106,9 @@ message SongMetadata { optional int32 file_size = 17; optional float rating = 18; // 0 (0 stars) to 1 (5 stars) optional string url = 19; + optional string art_automatic = 20; + optional string art_manual = 21; + optional Type type = 22; } // Playlist informations @@ -217,6 +238,7 @@ message RequestInsertUrls { optional int32 position = 3 [default=-1]; optional bool play_now = 4 [default=false]; optional bool enqueue = 5 [default=false]; + repeated SongMetadata songs = 6; } // Client want to change track @@ -320,7 +342,7 @@ message ResponseGlobalSearchStatus { // The message itself message Message { - optional int32 version = 1 [default=20]; + optional int32 version = 1 [default=21]; optional MsgType type = 2 [default=UNKNOWN]; // What data is in the message? optional RequestConnect request_connect = 21; diff --git a/src/networkremote/incomingdataparser.cpp b/src/networkremote/incomingdataparser.cpp index dc864f3d0..fbaa84d62 100644 --- a/src/networkremote/incomingdataparser.cpp +++ b/src/networkremote/incomingdataparser.cpp @@ -20,6 +20,7 @@ #include #include "core/logging.h" +#include "core/timeconstants.h" #include "engines/enginebase.h" #include "internet/core/internetmodel.h" #include "playlist/playlistmanager.h" @@ -60,6 +61,9 @@ IncomingDataParser::IncomingDataParser(Application* app) : app_(app) { connect(this, SIGNAL(InsertUrls(int, const QList&, int, bool, bool)), app_->playlist_manager(), SLOT(InsertUrls(int, const QList&, int, bool, bool))); + connect(this, SIGNAL(InsertSongs(int, const SongList&, int, bool, bool)), + app_->playlist_manager(), + SLOT(InsertSongs(int, const SongList&, int, bool, bool))); connect(this, SIGNAL(RemoveSongs(int, const QList&)), app_->playlist_manager(), SLOT(RemoveItemsWithoutUndo(int, const QList&))); @@ -235,16 +239,28 @@ void IncomingDataParser::SetShuffleMode(const pb::remote::Shuffle& shuffle) { void IncomingDataParser::InsertUrls(const pb::remote::Message& msg) { const pb::remote::RequestInsertUrls& request = msg.request_insert_urls(); - // Extract urls - QList urls; - for (auto it = request.urls().begin(); it != request.urls().end(); ++it) { - std::string s = *it; - urls << QUrl(QStringFromStdString(s)); + // Insert plain urls without metadata + if (request.urls().size() > 0) { + QList urls; + for (auto it = request.urls().begin(); it != request.urls().end(); ++it) { + std::string s = *it; + urls << QUrl(QStringFromStdString(s)); + } + + // Insert the urls + emit InsertUrls(request.playlist_id(), urls, request.position(), + request.play_now(), request.enqueue()); } - // Insert the urls - emit InsertUrls(request.playlist_id(), urls, request.position(), - request.play_now(), request.enqueue()); + // Add songs with metadata if present + if (request.songs().size() > 0) { + SongList songs; + for (int i = 0; i < request.songs().size(); i++) { + songs << CreateSongFromProtobuf(request.songs(i)); + } + emit InsertSongs(request.playlist_id(), songs, request.position(), + request.play_now(), request.enqueue()); + } } void IncomingDataParser::RemoveSongs(const pb::remote::Message& msg) { @@ -301,3 +317,26 @@ void IncomingDataParser::GlobalSearch(RemoteClient *client, const pb::remote::Me emit DoGlobalSearch(QStringFromStdString(msg.request_global_search().query()), client); } + +Song IncomingDataParser::CreateSongFromProtobuf(const pb::remote::SongMetadata& pb){ + Song song; + song.Init(QStringFromStdString(pb.title()), + QStringFromStdString(pb.artist()), + QStringFromStdString(pb.album()), + pb.length() * kNsecPerSec); + + song.set_albumartist(QStringFromStdString(pb.albumartist())); + song.set_genre(QStringFromStdString(pb.genre())); + song.set_year(QStringFromStdString(pb.pretty_year()).toInt()); + song.set_track(pb.track()); + song.set_disc(pb.disc()); + song.set_url(QUrl(QStringFromStdString(pb.url()))); + song.set_filesize(pb.file_size()); + song.set_rating(pb.rating()); + song.set_basefilename(QStringFromStdString(pb.filename())); + song.set_art_automatic(QStringFromStdString(pb.art_automatic())); + song.set_art_manual(QStringFromStdString(pb.art_manual())); + song.set_filetype(static_cast(pb.type())); + + return song; +} diff --git a/src/networkremote/incomingdataparser.h b/src/networkremote/incomingdataparser.h index 4c6bd7400..2f2bb0f7c 100644 --- a/src/networkremote/incomingdataparser.h +++ b/src/networkremote/incomingdataparser.h @@ -44,6 +44,8 @@ signals: void SetShuffleMode(PlaylistSequence::ShuffleMode mode); void InsertUrls(int id, const QList& urls, int pos, bool play_now, bool enqueue); + void InsertSongs(int id, const SongList& songs, int pos, bool play_now, + bool enqueue); void RemoveSongs(int id, const QList& indices); void SeekTo(int seconds); void SendLibrary(RemoteClient* client); @@ -67,6 +69,8 @@ signals: void ClosePlaylist(const pb::remote::Message& msg); void RateSong(const pb::remote::Message& msg); void GlobalSearch(RemoteClient* client, const pb::remote::Message& msg); + + Song CreateSongFromProtobuf(const pb::remote::SongMetadata& pb); }; #endif // INCOMINGDATAPARSER_H diff --git a/src/networkremote/outgoingdatacreator.cpp b/src/networkremote/outgoingdatacreator.cpp index 3e08bb2ff..ca8fdbc93 100644 --- a/src/networkremote/outgoingdatacreator.cpp +++ b/src/networkremote/outgoingdatacreator.cpp @@ -379,6 +379,9 @@ void OutgoingDataCreator::CreateSong(const Song& song, const QImage& art, song_metadata->set_file_size(song.filesize()); song_metadata->set_rating(song.rating()); song_metadata->set_url(DataCommaSizeFromQString(song.url().toString())); + song_metadata->set_art_automatic(DataCommaSizeFromQString(song.art_automatic())); + song_metadata->set_art_manual(DataCommaSizeFromQString(song.art_manual())); + song_metadata->set_type(static_cast< ::pb::remote::SongMetadata_Type>(song.filetype())); // Append coverart if (!art.isNull()) { diff --git a/src/playlist/playlistmanager.cpp b/src/playlist/playlistmanager.cpp index c958baf71..93d6a1e37 100644 --- a/src/playlist/playlistmanager.cpp +++ b/src/playlist/playlistmanager.cpp @@ -470,6 +470,13 @@ void PlaylistManager::InsertUrls(int id, const QList& urls, int pos, playlists_[id].p->InsertUrls(urls, pos, play_now, enqueue); } +void PlaylistManager::InsertSongs(int id, const SongList& songs, int pos, + bool play_now, bool enqueue) { + Q_ASSERT(playlists_.contains(id)); + + playlists_[id].p->InsertSongs(songs, pos, play_now, enqueue); +} + void PlaylistManager::RemoveItemsWithoutUndo(int id, const QList& indices) { Q_ASSERT(playlists_.contains(id)); diff --git a/src/playlist/playlistmanager.h b/src/playlist/playlistmanager.h index b0dc53187..377411f26 100644 --- a/src/playlist/playlistmanager.h +++ b/src/playlist/playlistmanager.h @@ -220,6 +220,8 @@ class PlaylistManager : public PlaylistManagerInterface { void InsertUrls(int id, const QList& urls, int pos = -1, bool play_now = false, bool enqueue = false); + void InsertSongs(int id, const SongList& songs, int pos = -1, + bool play_now = false, bool enqueue = false); // Removes items with given indices from the playlist. This operation is not // undoable. void RemoveItemsWithoutUndo(int id, const QList& indices);