diff --git a/test/Makefile.am b/test/Makefile.am
index d1105468..cb2081d0 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,22 +1,12 @@
TESTS = database-integrity sql-query database-user remote
-check_PROGRAMS = database-integrity sql-query database-user remote
+check_PROGRAMS = database-integrity sql-query database-user remote-client
-remote_SOURCES = \
- $(srcdir)/RemoteClientServer.cpp \
- $(srcdir)/TestDatabase.cpp \
- $(top_srcdir)/src/logger/Logger.cpp \
- $(top_srcdir)/src/database/Artist.cpp \
- $(top_srcdir)/src/database/Genre.cpp \
- $(top_srcdir)/src/database/Release.cpp \
- $(top_srcdir)/src/database/Track.cpp \
- $(top_srcdir)/src/database/DatabaseHandler.cpp \
- $(top_srcdir)/src/database/MediaDirectory.cpp \
- $(top_srcdir)/src/database/SqlQuery.cpp \
- $(top_srcdir)/src/database/User.cpp \
- $(top_srcdir)/src/database/Video.cpp
-nodist_remote_SOURCES = \
+remote_client_SOURCES = \
+ $(srcdir)/RemoteClient.cpp \
+ $(top_srcdir)/src/logger/Logger.cpp
+nodist_remote_client_SOURCES = \
$(builddir)/auth.pb.cc \
$(builddir)/collection.pb.cc \
$(builddir)/common.pb.cc \
@@ -31,7 +21,7 @@ BUILT_SOURCES = \
$(builddir)/messages.pb.h
-remote_CXXFLAGS=-std=c++11 -Wall -Wextra -DBOOST_LOG_DYN_LINK -I$(top_srcdir) -I$(top_srcdir)/src
+remote_client_CXXFLAGS=-std=c++11 -Wall -Wextra -DBOOST_LOG_DYN_LINK -I$(top_srcdir) -I$(top_srcdir)/src
%.pb.cc %.pb.h: $(top_srcdir)/src/remote/proto/%.proto
$(PROTOC) --proto_path=$(top_srcdir)/src/remote/proto/ --cpp_out=$(builddir)/ $^
diff --git a/test/RemoteClientServer.cpp b/test/RemoteClientServer.cpp
deleted file mode 100644
index 58ec4a75..00000000
--- a/test/RemoteClientServer.cpp
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * Copyright (C) 2013 Emeric Poupon
- *
- * This file is part of LMS.
- *
- * LMS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * LMS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with LMS. If not, see .
- */
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include "remote/messages/Header.hpp"
-#include "messages.pb.h"
-
-#include "TestDatabase.hpp"
-
-struct GenreInfo
-{
- uint64_t id;
- std::string name;
-};
-
-std::ostream& operator<<(std::ostream& os, const GenreInfo& info)
-{
- os << "id = " << info.id << ", name = '" << info.name << "'";
- return os;
-}
-
-struct ArtistInfo
-{
- uint64_t id;
- std::string name;
-};
-
-std::ostream& operator<<(std::ostream& os, const ArtistInfo& info)
-{
- os << "id = " << info.id << ", name = '" << info.name << "'";
- return os;
-}
-
-struct ReleaseInfo
-{
- uint64_t id;
- std::string name;
-};
-
-std::ostream& operator<<(std::ostream& os, const ReleaseInfo& info)
-{
- os << "id = " << info.id << ", name = '" << info.name;
- return os;
-}
-
-struct TrackInfo
-{
- uint64_t id;
-
- uint64_t release_id;
- uint64_t artist_id;
- std::vector genre_id;
-
- uint32_t disc_number;
- uint32_t track_number;
-
- std::string name;
-
- boost::posix_time::time_duration duration;
-
- TrackInfo(): id(0), release_id(0), artist_id(0), disc_number(0), track_number(0) {}
-};
-
-std::ostream& operator<<(std::ostream& os, const TrackInfo& info)
-{
- os << "id = " << info.id << ", name = '" << info.name << "', track_number = " << info.track_number << ", duration = " << info.duration;
- return os;
-}
-
-struct Cover
-{
- std::string mimeType;
- std::vector data;
-};
-
-// Ugly class for testing purposes
-
-class TestClient
-{
- public:
- TestClient(boost::asio::ip::tcp::endpoint endpoint)
- : _context(boost::asio::ssl::context::sslv23), // be large on this
- _socket(_ioService, _context)
- {
- boost::asio::ip::tcp::resolver resolver(_ioService);
-
- _socket.set_verify_mode(boost::asio::ssl::verify_peer);
- _socket.set_verify_callback(boost::bind(&TestClient::verifyCertificate, this, _1, _2));
-
- boost::asio::connect(_socket.lowest_layer(), resolver.resolve(endpoint));
-
- _socket.handshake(boost::asio::ssl::stream_base::client);
- }
-
- void getArtists(std::vector& artists, const std::vector& genreIds)
- {
-
- const std::size_t requestedBatchSize = 128;
- std::size_t offset = 0;
- std::size_t res = 0;
-
-
- while ((res = getArtists(artists, genreIds, offset, requestedBatchSize) ) > 0)
- offset += res;
-
- }
-
- std::size_t getArtists(std::vector& artists, const std::vector& genreIds, std::size_t offset, std::size_t size)
- {
- std::size_t nbArtists = 0;
-
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest );
-
- request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetArtistList);
- request.mutable_audio_collection_request()->mutable_get_artists()->mutable_batch_parameter()->set_size(size);
- request.mutable_audio_collection_request()->mutable_get_artists()->mutable_batch_parameter()->set_offset(offset);
- BOOST_FOREACH(uint64_t genreId, genreIds)
- request.mutable_audio_collection_request()->mutable_get_artists()->add_genre_id(genreId);
-
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.has_audio_collection_response())
- throw std::runtime_error("not an audio_collection_response!");
-
- if (!response.audio_collection_response().has_artist_list())
- throw std::runtime_error("not an artist_list!");
-
- for (int i = 0; i < response.audio_collection_response().artist_list().artists_size(); ++i)
- {
- if (!response.audio_collection_response().artist_list().artists(i).has_name())
- throw std::runtime_error("no artist name!");
-
- ArtistInfo artist;
- artist.id = response.audio_collection_response().artist_list().artists(i).id();
- artist.name = response.audio_collection_response().artist_list().artists(i).name();
-
- artists.push_back( artist );
- nbArtists++;
- }
-
- return nbArtists;
- }
-
- void getGenres(std::vector& genres)
- {
-
- const std::size_t requestedBatchSize = 8;
- std::size_t offset = 0;
- std::size_t res = 0;
-
- while ((res = getGenres(genres, offset, requestedBatchSize) ) > 0)
- offset += res;
-
- }
-
- std::size_t getGenres(std::vector& genres, std::size_t offset, std::size_t size)
- {
- std::size_t nbAdded = 0;
-
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest );
-
- request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetGenreList);
- request.mutable_audio_collection_request()->mutable_get_genres()->mutable_batch_parameter()->set_size(size);
- request.mutable_audio_collection_request()->mutable_get_genres()->mutable_batch_parameter()->set_offset(offset);
-
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.has_audio_collection_response())
- throw std::runtime_error("not an audio_collection_response!");
-
- if (!response.audio_collection_response().has_genre_list())
- throw std::runtime_error("not an genre_list!");
-
- for (int i = 0; i < response.audio_collection_response().genre_list().genres_size(); ++i)
- {
- if (!response.audio_collection_response().genre_list().genres(i).has_name())
- throw std::runtime_error("no genre name!");
-
- GenreInfo genre;
- genre.id = response.audio_collection_response().genre_list().genres(i).id();
- genre.name = response.audio_collection_response().genre_list().genres(i).name();
-
- genres.push_back( genre );
- nbAdded++;
- }
- return nbAdded;
- }
-
- void getReleases(std::vector& releases, const std::vector artistIds)
- {
-
- const std::size_t requestedBatchSize = 256;
- std::size_t offset = 0;
- std::size_t res = 0;
-
- while ((res = getReleases(releases, artistIds, offset, requestedBatchSize) ) > 0)
- offset += res;
-
- }
-
- std::size_t getReleases(std::vector& releases, const std::vector artistIds, std::size_t offset, std::size_t size)
- {
- std::size_t nbAdded = 0;
-
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest );
-
- request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetReleaseList);
- request.mutable_audio_collection_request()->mutable_get_releases()->mutable_batch_parameter()->set_size(size);
- request.mutable_audio_collection_request()->mutable_get_releases()->mutable_batch_parameter()->set_offset(offset);
- BOOST_FOREACH(uint64_t artistId, artistIds)
- request.mutable_audio_collection_request()->mutable_get_releases()->add_artist_id(artistId);
-
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.audio_collection_response().has_type())
- throw std::runtime_error("Missing type!");
-
-// if (!response.audio_collection_response().type() != Remote::ServerMessage::AudioCollectionResponse::TypeReleaseList)
-// throw std::runtime_error("Bad type!");
-
- if (!response.has_audio_collection_response())
- throw std::runtime_error("not an audio_collection_response!");
-
- if (!response.audio_collection_response().has_release_list())
- throw std::runtime_error("not an release list!");
-
- for (int i = 0; i < response.audio_collection_response().release_list().releases_size(); ++i)
- {
- if (!response.audio_collection_response().release_list().releases(i).has_name())
- throw std::runtime_error("no release name!");
-
- ReleaseInfo release;
- release.id = response.audio_collection_response().release_list().releases(i).id();
- release.name = response.audio_collection_response().release_list().releases(i).name();
-
- releases.push_back( release );
- nbAdded++;
- }
- return nbAdded;
- }
-
- void getTracks(std::vector& tracks, const std::vector artistIds, const std::vector releaseIds, const std::vector genreIds)
- {
- const std::size_t requestedBatchSize = 0;
- std::size_t offset = 0;
- std::size_t res = 0;
-
- while ((res = getTracks(tracks, artistIds, releaseIds, genreIds, offset, requestedBatchSize) ) > 0)
- offset += res;
- }
-
- std::size_t getTracks(std::vector& tracks,
- const std::vector artistIds,
- const std::vector releaseIds,
- const std::vector genreIds,
- std::size_t offset,
- std::size_t size)
- {
- std::size_t nbAdded = 0;
-
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest );
-
- request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetTrackList);
- request.mutable_audio_collection_request()->mutable_get_tracks()->mutable_batch_parameter()->set_size(size);
- request.mutable_audio_collection_request()->mutable_get_tracks()->mutable_batch_parameter()->set_offset(offset);
-
- BOOST_FOREACH(uint64_t artistId, artistIds)
- request.mutable_audio_collection_request()->mutable_get_tracks()->add_artist_id(artistId);
- BOOST_FOREACH(uint64_t releaseId, releaseIds)
- request.mutable_audio_collection_request()->mutable_get_tracks()->add_release_id(releaseId);
- BOOST_FOREACH(uint64_t genreId, genreIds)
- request.mutable_audio_collection_request()->mutable_get_tracks()->add_genre_id(genreId);
-
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.has_audio_collection_response())
- throw std::runtime_error("not an audio_collection_response!");
-
- if (!response.audio_collection_response().has_track_list())
- throw std::runtime_error("not an track list!");
-
- for (int i = 0; i < response.audio_collection_response().track_list().tracks_size(); ++i)
- {
-
- TrackInfo track;
- track.id = response.audio_collection_response().track_list().tracks(i).id();
- track.name = response.audio_collection_response().track_list().tracks(i).name();
- track.duration = boost::posix_time::seconds(response.audio_collection_response().track_list().tracks(i).duration_secs());
- if (response.audio_collection_response().track_list().tracks(i).has_track_number())
- track.track_number = response.audio_collection_response().track_list().tracks(i).track_number();
-
- if (response.audio_collection_response().track_list().tracks(i).has_disc_number())
- track.disc_number = response.audio_collection_response().track_list().tracks(i).disc_number();
-
-
- tracks.push_back( track );
- nbAdded++;
- }
-
- return nbAdded;
- }
-
-
- void getMediaAudio(uint64_t audioId, std::vector& data)
- {
-
- // Prepare
- uint32_t handle = mediaAudioPrepare( audioId );
-
- // Get while available
- mediaGet( handle, data );
-
- // Terminate
- mediaTerminate( handle );
- }
-
- void getCoverTrack(std::vector& coverArt, uint64_t trackId)
- {
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage::AudioCollectionRequest );
-
- request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetCoverArt);
- request.mutable_audio_collection_request()->mutable_get_cover_art()->set_type( Remote::AudioCollectionRequest::GetCoverArt::TypeGetCoverArtTrack);
- request.mutable_audio_collection_request()->mutable_get_cover_art()->set_track_id( trackId );
- request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 256 );
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.has_audio_collection_response())
- throw std::runtime_error("not an audio_collection_response!");
-
- for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i)
- {
- Cover cover;
- cover.mimeType = response.audio_collection_response().cover_art(i).mime_type();
- cover.data.assign(response.audio_collection_response().cover_art(i).data().begin(), response.audio_collection_response().cover_art(i).data().end());;
-
- coverArt.push_back(cover);
- }
- }
-
- void getCoverRelease(std::vector& coverArt, uint64_t releaseId)
- {
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage::AudioCollectionRequest );
-
- request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetCoverArt);
- request.mutable_audio_collection_request()->mutable_get_cover_art()->set_type( Remote::AudioCollectionRequest::GetCoverArt::TypeGetCoverArtRelease);
- request.mutable_audio_collection_request()->mutable_get_cover_art()->set_release_id( releaseId );
- request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 256 );
-
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.has_audio_collection_response())
- throw std::runtime_error("not an audio_collection_response!");
-
- for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i)
- {
- Cover cover;
- cover.mimeType = response.audio_collection_response().cover_art(i).mime_type();
- cover.data.assign(response.audio_collection_response().cover_art(i).data().begin(), response.audio_collection_response().cover_art(i).data().end());;
-
- coverArt.push_back(cover);
- }
-
- }
-
- std::string getRevision(void)
- {
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage::AudioCollectionRequest );
-
- request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetRevision);
-
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.has_audio_collection_response())
- throw std::runtime_error("not an audio_collection_response!");
-
- if (!response.audio_collection_response().has_revision())
- throw std::runtime_error("not a revision!");
-
- return response.audio_collection_response().revision().rev();
- }
-
- bool login(const std::string& username, const std::string& password)
- {
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage::AuthRequest );
-
- request.mutable_auth_request()->set_type( Remote::AuthRequest::TypePassword);
- request.mutable_auth_request()->mutable_password()->set_user_login( username );
- request.mutable_auth_request()->mutable_password()->set_user_password( password );
-
- sendMsg(request);
-
- // Receive responses
- Remote::ServerMessage response;
- recvMsg(response);
-
- // Process message
- if (!response.has_auth_response())
- throw std::runtime_error("not an auth response!");
-
- if (!response.auth_response().has_password_result())
- throw std::runtime_error("not a password result!");
-
- switch( response.auth_response().password_result().type())
- {
- case Remote::AuthResponse::PasswordResult::TypePasswordValid:
- return true;
- case Remote::AuthResponse::PasswordResult::TypePasswordInvalid:
- return false;
- case Remote::AuthResponse::PasswordResult::TypeLoginThrottling:
- if (response.auth_response().password_result().has_delay())
- std::cerr << "Has to wait for " << response.auth_response().password_result().delay() << " seconds" << std::endl;
-
- return false;
- default:
- throw std::runtime_error("bad password result type");
- }
- }
-
- private:
-
- bool verifyCertificate(bool preverified, boost::asio::ssl::verify_context& ctx)
- {
- // In this example we will simply print the certificate's subject name.
- std::array subject_name;
-
- X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
- X509_NAME_oneline(X509_get_subject_name(cert), subject_name.data(), subject_name.size());
-
- std::cout << "Verifying '" << std::string(subject_name.data()) << "', preverified = " << std::boolalpha << preverified << std::endl;
-
- return true; // preverified;
- }
-
- uint32_t mediaAudioPrepare(uint64_t audioId)
- {
-
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage_Type_MediaRequest);
-
- request.mutable_media_request()->set_type( Remote::MediaRequest_Type_TypeMediaPrepare);
- request.mutable_media_request()->mutable_prepare()->set_type(Remote::MediaRequest_Prepare_Type_AudioRequest);
-
- // Set fields
- request.mutable_media_request()->mutable_prepare()->mutable_audio()->set_track_id( audioId );
- request.mutable_media_request()->mutable_prepare()->mutable_audio()->set_codec_type( Remote::MediaRequest::Prepare::AudioCodecTypeOGA );
- request.mutable_media_request()->mutable_prepare()->mutable_audio()->set_bitrate( Remote::MediaRequest::Prepare::AudioBitrate_64_kbps );
-
- std::cout << "Sending prepare request" << std::endl;
- sendMsg(request);
-
- std::cout << "Waiting for response" << std::endl;
- // Receive response
- Remote::ServerMessage response;
- recvMsg(response);
-
- std::cout << "Got a response" << std::endl;
-
- // Process message
- if (!response.has_media_response())
- throw std::runtime_error("Preapre: not an media reponse!");
-
- if (!response.media_response().has_prepare_result())
- throw std::runtime_error("Prepare: not an prepare result msg!");
-
- if (!response.media_response().prepare_result().has_handle())
- throw std::runtime_error("Prepare: cannot get handle");
-
- return response.media_response().prepare_result().handle();
- }
-
- void mediaGet(uint32_t handle, std::vector& data)
- {
- while (mediaGetPart(handle, data) > 0)
- ;
- }
-
-
- std::size_t mediaGetPart(uint32_t handle, std::vector& data)
- {
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage::MediaRequest);
-
- request.mutable_media_request()->set_type( Remote::MediaRequest::TypeMediaGetPart);
- request.mutable_media_request()->mutable_get_part()->set_handle(handle);
- request.mutable_media_request()->mutable_get_part()->set_requested_data_size(65536);
-
- std::cout << "Sending GetPart request" << std::endl;
- sendMsg(request);
-
- std::cout << "Waiting for response" << std::endl;
- // Receive response
- Remote::ServerMessage response;
- recvMsg(response);
-
- std::cout << "Got a response" << std::endl;
-
- if (!response.has_media_response())
- throw std::runtime_error("not an media response");
-
- // Process message
- if (response.media_response().type() != Remote::MediaResponse::TypePartResult)
- throw std::runtime_error("GetPart: not a Part response!");
-
- if (!response.media_response().has_part_result())
- throw std::runtime_error("GetPart: does not have a Part result!");
-
- std::copy(response.media_response().part_result().data().begin(), response.media_response().part_result().data().end(), std::back_inserter(data));
-
- return response.media_response().part_result().data().size();
- }
-
- void mediaTerminate( uint32_t handle )
- {
- // Send request
- Remote::ClientMessage request;
-
- request.set_type( Remote::ClientMessage::MediaRequest);
-
- request.mutable_media_request()->set_type( Remote::MediaRequest::TypeMediaTerminate);
- request.mutable_media_request()->mutable_terminate()->set_handle(handle);
-
- sendMsg(request);
-
- // Receive response
- Remote::ServerMessage response;
- recvMsg(response);
-
-
- // Process message
- if (!response.has_media_response())
- throw std::runtime_error("Terminate: not an media response");
-
- if (!response.media_response().has_terminate_result())
- throw std::runtime_error("Terminate: not an terminate msg!");
-
- }
-
-
- void sendMsg(const ::google::protobuf::Message& message)
- {
- std::ostream os(&_outputStreamBuf);
-
- // Serialize message
- if (message.SerializeToOstream(&os))
- {
-
- if (_outputStreamBuf.size() > Remote::Header::max_data_size)
- {
- std::ostringstream oss; oss << "Message too big = " << _outputStreamBuf.size() << " bytes! (max is " << Remote::Header::max_data_size << ")" << std::endl;
- throw std::runtime_error("Message to big!");
- }
-
- // Send message header
- std::array headerBuffer;
-
- // Generate header content
- {
- Remote::Header header;
- header.setDataSize(_outputStreamBuf.size());
- header.to_buffer(headerBuffer);
- }
-
- boost::asio::write(_socket, boost::asio::buffer(headerBuffer));
-
- // Send serialized message
- std::size_t n = boost::asio::write(_socket,
- _outputStreamBuf.data(),
- boost::asio::transfer_exactly(_outputStreamBuf.size()));
- assert(n == _outputStreamBuf.size());
-
- _outputStreamBuf.consume(n);
-
- }
- else
- {
- std::cerr << "Cannot serialize message!" << std::endl;
- throw std::runtime_error("message.SerializeToString failed!");
- }
-
- }
-
- void recvMsg(::google::protobuf::Message& message)
- {
- std::istream is(&_inputStreamBuf);
-
- {
- // reserve bytes in output sequence
- boost::asio::streambuf::mutable_buffers_type bufs = _inputStreamBuf.prepare(Remote::Header::size);
-
- std::size_t n = boost::asio::read(_socket,
- bufs,
- boost::asio::transfer_exactly(Remote::Header::size));
-
- assert(n == Remote::Header::size);
- _inputStreamBuf.commit(n);
-
- }
-
- Remote::Header header;
- if (!header.from_istream(is))
- throw std::runtime_error("Cannot read header from buffer!");
-
- // Read in a stream buffer
- {
- // reserve bytes in output sequence
- boost::asio::streambuf::mutable_buffers_type bufs = _inputStreamBuf.prepare(header.getDataSize());
-
- std::size_t n = boost::asio::read(_socket,
- bufs,
- boost::asio::transfer_exactly(header.getDataSize()));
-
- assert(n == header.getDataSize());
- _inputStreamBuf.commit(n);
-
- if (!message.ParseFromIstream(&is))
- throw std::runtime_error("message.ParseFromIstream failed!");
-
- }
- }
-
- typedef boost::asio::ssl::stream ssl_socket;
-
- boost::asio::io_service _ioService;
- boost::asio::ssl::context _context;
- ssl_socket _socket;
-
- boost::asio::streambuf _inputStreamBuf;
- boost::asio::streambuf _outputStreamBuf;
-
-};
-
-
-int main()
-{
- try {
- bool extendedTests = true;
- bool writeCovers = false;
-
- std::cout << "Running test... extendedTests = " << std::boolalpha << extendedTests << std::endl;
-
- // Client
- // connect to loopback
- TestClient client( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4::loopback(), 5080));
-
- // Use a dumb account in order to test the login
- if (!client.login("admin", "admin"))
- throw std::runtime_error("login failed!");
-
- // **** REVISION ***
- std::cout << "Getting revision..." << std::endl;
- std::string rev = client.getRevision();
- std::cout << "Revision '" << rev << "'" << std::endl;
-
- // ****** Artists *********
- std::cout << "Getting artists..." << std::endl;
- std::vector artists;
- client.getArtists(artists, std::vector());
-
- std::cout << "Got " << artists.size() << " artists!" << std::endl;
- BOOST_FOREACH(const ArtistInfo& artist, artists)
- std::cout << "Artist: '" << artist << "'" << std::endl;
-
- // ***** Genres *********
- std::cout << "Getting genres..." << std::endl;
- std::vector genres;
- client.getGenres(genres);
-
- std::cout << "Got " << genres.size() << " genres!" << std::endl;
- BOOST_FOREACH(const GenreInfo& genre, genres)
- std::cout << "Genre: '" << genre << "'" << std::endl;
-
- // **** Releases ******
- std::cout << "Getting releases..." << std::endl;
- std::vector releases;
- client.getReleases(releases, std::vector());
- BOOST_FOREACH(const ReleaseInfo& release, releases)
- std::cout << "Release: '" << release << "'" << std::endl;
-
- // **** Tracks ******
- std::cout << "Getting tracks..." << std::endl;
- std::vector tracks;
- client.getTracks(tracks, std::vector(), std::vector(), std::vector());
- BOOST_FOREACH(const TrackInfo& track, tracks)
- std::cout << "Track: '" << track << "'" << std::endl;
-
- // Caution: long test!
- if (extendedTests)
- {
-
- std::cout << "Getting artist for each genre..." << std::endl;
- // Get the artists for each genre
- BOOST_FOREACH(const GenreInfo& genre, genres)
- {
- std::cout << "Getting artists genre '" << genre.name << "'" << std::endl;
- std::vector artists;
- client.getArtists(artists, std::vector(1, genre.id));
-
- BOOST_FOREACH(const ArtistInfo& artist, artists)
- std::cout << "-> Artist: " << artist << std::endl;
- }
-
- std::cout << "Getting tracks for each artist..." << std::endl;
- // Get the tracks for each artist
- BOOST_FOREACH(const ArtistInfo& artist, artists)
- {
- std::vector tracks;
- client.getTracks(tracks, std::vector(1, artist.id), std::vector(), std::vector());
-
- std::cout << "Artist '" << artist.name << "', nb tracks = " << tracks.size() << std::endl;
- BOOST_FOREACH(const TrackInfo& track, tracks)
- std::cout << "Artist '" << artist.name << "', track: '" << track << "'" << std::endl;
- }
- }
-
- // ***** Covers *******
- if (extendedTests)
- {
- BOOST_FOREACH(const ReleaseInfo& release, releases)
- {
- std::vector coverArts;
- client.getCoverRelease(coverArts, release.id);
-
- if (writeCovers)
- {
- boost::filesystem::create_directory("cover");
- BOOST_FOREACH(const Cover coverArt, coverArts)
- {
- std::ostringstream oss; oss << "cover/" << release.id << "." << release.name << ".jpeg";
- std::ofstream out(oss.str().c_str());
- BOOST_FOREACH(unsigned char c, coverArt.data)
- out.put(c);
- }
- }
-
- std::cout << "Release '" << release << "', spotted " << coverArts.size() << " covers!" << std::endl;
- }
-
- BOOST_FOREACH(const TrackInfo& track, tracks)
- {
- std::vector coverArt;
- client.getCoverTrack(coverArt, track.id);
-
- std::cout << "Track '" << track << "', spotted " << coverArt.size() << " covers!" << std::endl;
- }
-
- }
-
- // ****** Transcode test ********
- const std::vector mediaIds = {14000, 14001};
- BOOST_FOREACH(uint64_t mediaId, mediaIds)
- {
- std::vector data;
- client.getMediaAudio(mediaId, data);
- std::cout << "Media size = " << data.size() << std::endl;
- }
-
- std::cout << "End of tests!" << std::endl;
- }
- catch(std::exception& e)
- {
- std::cerr << "Caught exception " << e.what() << std::endl;
- return EXIT_FAILURE;
- }
-
- std::cout << "Normal quit..." << std::endl;
- return EXIT_SUCCESS;
-}
-
-