diff --git a/README.md b/README.md
index 6c029ea3..2ecaa872 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,9 @@ This command requires root privileges
```sh
$ /usr/bin/lms --docroot='/usr/share/lms/docroot/;/resources,/css,/images' --approot=/usr/share/lms/approot --http-address 0.0.0.0 --http-port 5081
```
-The exectuable needs write accesses to the /var/lms/ directory
+It is highly recommended to run LMS as a non root user.
+The exectuable needs write accesses to the /var/lms/ directory.
+
## Setting up SSL materials (optional)
Here is just a self signed certificate example, you could do use a CA if you want.
diff --git a/configure.ac b/configure.ac
index f7e9611a..c7af1f14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,41 +8,10 @@ AC_LANG_CPLUSPLUS
# Checks for programs
AC_PROG_CXX
-
-AC_ARG_ENABLE(lmsapi, AS_HELP_STRING([--enable-lmsapi],
- [Build with the lmsapi protocol support. Defaults to yes.])],
- [enable_lmsapi="$enableval"],
- [enable_lmsapi="yes"])
-
-# ProtoBuf compiler.
-# First, specify with --with-protoc=/path/of/protoc.
-# Or, specify with env variable PROTOC.
-# If neither of the above, find it in the path.
-AS_IF([test "$enable_lmsapi" = "yes"],
- [AC_ARG_WITH([protoc],
- [AS_HELP_STRING([--with-protoc=/path/of/protoc],
- [Location of the protocol buffers compiler protoc. Defaults to looking on path.])],
- [PROTOC="$withval"],
- [ AS_IF([test "x${PROTOC}" == "x"],
- [AC_PATH_PROG([PROTOC], [protoc], [no])])]
- )
- ]
- [ AS_IF([test "${PROTOC}" == "no"], [AC_MSG_ERROR([ProtoBuf compiler "protoc" not found.])]) ]
- [AC_CHECK_LIB( [protobuf],
- [main],
- ,
- [AC_MSG_ERROR([libprotobuf not found!])])]
- [lmsapi=true]
- ,
- [lmsapi=false])
-
-AM_CONDITIONAL([LMSAPI], [test x$lmsapi = xtrue])
-AS_IF([test x$lmsapi = xtrue], [AC_DEFINE(HAVE_LMSAPI, [1], [Enable LMS API support])])
-
AC_ARG_ENABLE([video], AS_HELP_STRING([--enable-video],
- [Enable Video support. Default to yes.])],
+ [Enable Video support. Default to no.])],
[enable_video="$enableval"],
- [enable_video="yes"])
+ [enable_video="no"])
AM_CONDITIONAL([VIDEO], [test x$enable_video = xyes])
AS_IF([test x$enable_video = xyes], [AC_DEFINE(HAVE_VIDEO, [1], [Enable Video support])])
diff --git a/lms-api/proto/auth.proto b/lms-api/proto/auth.proto
deleted file mode 100644
index 1ad02a48..00000000
--- a/lms-api/proto/auth.proto
+++ /dev/null
@@ -1,65 +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 .
- */
-
-package LmsAPI;
-
-message AuthRequest
-{
- message Password
- {
- required string user_login = 1;
- required string user_password = 2;
- }
-
- enum Type
- {
- TypePassword = 1;
- }
-
- required Type type = 1;
-
- optional Password password = 2;
-}
-
-message AuthResponse
-{
-
- message PasswordResult
- {
- enum Type
- {
- TypePasswordInvalid = 1;
- TypeLoginThrottling = 2; // The attempt was not processed because of throttling
- TypePasswordValid = 3;
- }
- required Type type = 1;
-
- optional uint32 delay = 2; // in seconds, in case of PasswordInvalid/LoginThrottling
- }
-
- enum Type
- {
- TypePasswordResult = 1;
- }
-
- required Type type = 1;
-
- optional PasswordResult password_result = 2;
-}
-
diff --git a/lms-api/proto/collection.proto b/lms-api/proto/collection.proto
deleted file mode 100644
index 8666a98b..00000000
--- a/lms-api/proto/collection.proto
+++ /dev/null
@@ -1,195 +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 .
- */
-
-package LmsAPI;
-
-message AudioCollectionRequest
-{
-
- message SearchFilter
- {
- repeated uint64 artist_id = 1; // has one of these artists
- repeated uint64 genre_id = 2; // has one of these genres
- repeated uint64 release_id = 3; // hase one of these releases
- repeated uint64 track_id = 4; // has one of theses tracks
- }
-
- message BatchParameter
- {
- required uint32 offset = 1; // First element requested
- required uint32 size = 2; // Number of elements requested. Server may not honor this size if too big
- }
-
- message GetGenreList
- {
- required BatchParameter batch_parameter = 1;
- optional SearchFilter search_filter = 2;
- }
-
- message GetArtistList
- {
- required BatchParameter batch_parameter = 1;
- optional SearchFilter search_filter = 2;
- }
-
- message GetReleaseList
- {
- required BatchParameter batch_parameter = 1;
- optional SearchFilter search_filter = 2;
- }
-
- message GetTrackList
- {
- required BatchParameter batch_parameter = 1;
- optional SearchFilter search_filter = 2;
- }
-
- message GetCoverArt
- {
- enum Type
- {
- TypeGetCoverArtRelease = 1;
- TypeGetCoverArtTrack = 2;
- }
-
- required Type type = 1;
-
- optional uint64 release_id = 2; // Release that owns the cover art
- optional uint64 track_id = 3; // Track that owns the cover art
-
- required uint32 size = 4; // Scale image to size*size pixels. Set 0 to get the biggest image
- }
-
- enum Type
- {
- TypeGetRevision = 1;
- TypeGetGenreList = 2;
- TypeGetArtistList = 3;
- TypeGetReleaseList = 4;
- TypeGetTrackList = 5;
- TypeGetCoverArt = 6;
- }
-
- required Type type = 1;
-
- optional GetGenreList get_genres = 3;
- optional GetArtistList get_artists = 4;
- optional GetReleaseList get_releases = 5;
- optional GetTrackList get_tracks = 6;
- optional GetCoverArt get_cover_art = 7;
-}
-
-
-message AudioCollectionResponse
-{
-
- message Revision
- {
- required string rev = 1; // Unique identifier of the database revision
- }
-
- message GenreList
- {
- repeated Genre genres = 1;
- }
-
- message ArtistList
- {
- repeated Artist artists = 1;
- }
-
- message ReleaseList
- {
- repeated Release releases = 1;
- }
-
- message TrackList
- {
- repeated Track tracks = 1;
- }
-
- message CoverArt
- {
- optional string mime_type = 1;
- required bytes data = 2;
- }
-
- message Genre
- {
- required uint64 id = 1;
- optional string mbid = 2;
- required string name = 3;
- }
-
- message Artist
- {
- required uint64 id = 1;
- optional string mbid = 2;
- required string name = 3;
- }
-
- message Release
- {
- required uint64 id = 1;
- optional string mbid = 2;
- required string name = 3;
- }
-
- message Track
- {
- required uint64 id = 1; // Track id
- optional string mbid = 2;
-
- required uint64 artist_id = 3;
- required uint64 release_id = 4;
- repeated uint64 genre_id = 5;
-
- optional string artist_mbid = 6;
- optional string release_mbid = 7;
- optional uint32 disc_number = 8;
- optional uint32 track_number = 9;
- required string name = 10;
- required uint32 duration_secs = 11;
- optional string release_date = 12;
- optional string original_release_date = 13;
- }
-
- enum Type {
- TypeRevision = 1;
- TypeGenreList = 2;
- TypeArtistList = 3;
- TypeReleaseList = 4;
- TypeTrackList = 5;
- TypeCoverArt = 6;
- }
-
-
- required Type type = 1;
-
- optional Revision revision = 2;
- optional GenreList genre_list = 3;
- optional ArtistList artist_list = 4;
- optional ReleaseList release_list = 5;
- optional TrackList track_list = 6;
- repeated CoverArt cover_art = 7;
-}
-
-
-
-
diff --git a/lms-api/proto/media.proto b/lms-api/proto/media.proto
deleted file mode 100644
index 20af5d02..00000000
--- a/lms-api/proto/media.proto
+++ /dev/null
@@ -1,137 +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 .
- */
-
-package LmsAPI;
-
-message MediaRequest
-{
-
- message Prepare
- {
-
- enum AudioCodecType
- {
- AudioCodecTypeOGA = 1;
- }
- enum AudioBitrate {
- AudioBitrate_32_kbps = 1;
- AudioBitrate_64_kbps = 2;
- AudioBitrate_96_kbps = 3;
- AudioBitrate_128_kbps = 4;
- AudioBitrate_192_kbps = 5;
- AudioBitrate_256_kbps = 6;
- }
-
- enum VideoCodecType
- {
- VideoCodecTypeOGV = 1;
- }
- enum VideoBitrate {
- VideoBitrate_512_kbps = 1;
- }
-
- message Audio
- {
- required int64 track_id = 1; // Id if the media
- required AudioCodecType codec_type = 2;
- required AudioBitrate bitrate = 3;
- optional uint32 stream_idx = 4;
- optional uint32 offset_secs = 5;
- }
-
- message Video
- {
- required int64 video_id = 1; // Id if the media
- required VideoCodecType codec_type = 2;
- required AudioBitrate audio_bitrate = 3;
- required VideoBitrate video_bitrate = 4;
- optional uint32 offset_secs = 5;
- optional uint32 audio_stream_idx = 6;
- optional uint32 video_stream_idx = 7;
- optional uint32 subtitle_stream_idx = 8;
- }
-
- enum Type {
- AudioRequest = 1;
- VideoRequest = 2;
- }
-
- required Type type = 1;
-
- optional Audio audio = 2;
- optional Video video = 3;
- }
-
- message GetPart
- {
- required uint32 handle = 1; // handle that uniquely identify the media. Get using the Prepare request
- required uint32 requested_data_size = 2; // Amount of data requested. May receive more or less. May receive 0 byte if complete
- }
-
- message Terminate
- {
- required uint32 handle = 1;
- }
-
- enum Type
- {
- TypeMediaPrepare = 1;
- TypeMediaGetPart = 2;
- TypeMediaTerminate = 3;
- }
-
- required Type type = 1;
-
- optional Prepare prepare = 2;
- optional GetPart get_part = 3;
- optional Terminate terminate = 4;
-
-} // MediaRequest
-
-message MediaResponse
-{
-
- message PrepareResult
- {
- optional uint32 handle = 1; // handle iif prepare request was ok
- }
-
- message PartResult
- {
- optional bytes data = 2; // 0 bytes when the media is over, nothing when the request is ill formed
- }
-
- message TerminateResult
- {
- }
-
- enum Type
- {
- TypePrepareResult = 1;
- TypePartResult = 2;
- TypeTerminateResult = 3;
- }
-
- required Type type = 1;
-
- optional PrepareResult prepare_result = 2;
- optional PartResult part_result = 3;
- optional TerminateResult terminate_result = 4;
-}
-
diff --git a/lms-api/proto/messages.proto b/lms-api/proto/messages.proto
deleted file mode 100644
index a6eb280b..00000000
--- a/lms-api/proto/messages.proto
+++ /dev/null
@@ -1,69 +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 .
- */
-
-import "auth.proto";
-import "collection.proto";
-import "media.proto";
-
-package LmsAPI;
-
-// Every request sent by the client must be a ClientMessage
-// The server will answer using a ServerMessage
-//
-// The client must authenticate first before querying data
-// If an expected message is received, the connection is dropped by the server
-//
-// A header is to be added before the serialized protobuf message in order to keep
-// track of where one message ends and the next begins.
-// Format:
-// MAGIC (4 bytes, 0xDE, 0xAD, 0xBE, 0xEF)- SIZE (4 bytes, big endian encoded) - serialized proto message
-message ClientMessage
-{
- enum Type
- {
- AuthRequest = 1;
- AudioCollectionRequest = 2;
- MediaRequest = 3;
- }
-
- required Type type = 1;
-
- optional AuthRequest auth_request = 2;
- optional AudioCollectionRequest audio_collection_request = 3;
- optional MediaRequest media_request = 4;
-}
-
-
-message ServerMessage
-{
- enum Type
- {
- AuthResponse = 1;
- AudioCollectionResponse = 2;
- MediaResponse = 3;
- }
-
- required Type type = 1;
-
- optional AuthResponse auth_response = 2;
- optional AudioCollectionResponse audio_collection_response = 3;
- optional MediaResponse media_response = 4;
-}
-
-
diff --git a/src/Makefile.am b/src/Makefile.am
index 33a25015..ce6a0c12 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,52 +59,6 @@ lms_SOURCES += \
$(srcdir)/ui/video/VideoParametersDialog.cpp
endif
-if LMSAPI
-lms_SOURCES += \
- $(srcdir)/lms-api/server/Connection.cpp \
- $(srcdir)/lms-api/server/ConnectionManager.cpp \
- $(srcdir)/lms-api/server/AudioCollectionRequestHandler.cpp \
- $(srcdir)/lms-api/server/AuthRequestHandler.cpp \
- $(srcdir)/lms-api/server/MediaRequestHandler.cpp \
- $(srcdir)/lms-api/server/RequestHandler.cpp \
- $(srcdir)/lms-api/server/Server.cpp \
- $(srcdir)/service/LmsAPIServerService.cpp
-
-nodist_lms_SOURCES = \
- $(builddir)/auth.pb.cc \
- $(builddir)/auth.pb.h \
- $(builddir)/collection.pb.cc \
- $(builddir)/collection.pb.h \
- $(builddir)/media.pb.cc \
- $(builddir)/media.pb.h \
- $(builddir)/messages.pb.cc \
- $(builddir)/messages.pb.h
-
-BUILT_SOURCES = \
- $(builddir)/auth.pb.cc \
- $(builddir)/auth.pb.h \
- $(builddir)/collection.pb.cc \
- $(builddir)/collection.pb.h \
- $(builddir)/media.pb.cc \
- $(builddir)/media.pb.h \
- $(builddir)/messages.pb.cc \
- $(builddir)/messages.pb.h
-
-MOSTLYCLEANFILES = \
- $(builddir)/auth.pb.cc \
- $(builddir)/auth.pb.h \
- $(builddir)/collection.pb.cc \
- $(builddir)/collection.pb.h \
- $(builddir)/media.pb.cc \
- $(builddir)/media.pb.h \
- $(builddir)/messages.pb.cc \
- $(builddir)/messages.pb.h
-
-%.pb.cc %.pb.h: $(top_srcdir)/lms-api/proto/%.proto
- $(PROTOC) --proto_path=$(top_srcdir)/lms-api/proto/ --cpp_out=$(builddir)/ $^
-
-endif
-
-lms_CXXFLAGS=-std=c++11 -Wall -I$(top_srcdir)/third-party -I$(srcdir)/ui -I$(srcdir)/lms-api $(MAGICKXX_CFLAGS)
+lms_CXXFLAGS=-std=c++11 -Wall -I$(top_srcdir)/third-party -I$(srcdir)/ui $(MAGICKXX_CFLAGS)
lms_LDADD=$(MAGICKXX_LIBS)
diff --git a/src/config/ConfigReader.cpp b/src/config/ConfigReader.cpp
deleted file mode 100644
index 1598e71b..00000000
--- a/src/config/ConfigReader.cpp
+++ /dev/null
@@ -1,98 +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 "ConfigReader.hpp"
-
-namespace {
-
-}
-
-ConfigReader::ConfigReader()
-: _config (nullptr)
-{
-}
-
-ConfigReader&
-ConfigReader::instance()
-{
- static ConfigReader instance;
- return instance;
-}
-
-void
-ConfigReader::setFile(boost::filesystem::path p)
-{
- if (_config != nullptr)
- delete _config;
-
- _config = new libconfig::Config();
-
- _config->readFile(p.string().c_str());
-}
-
-std::string
-ConfigReader::getString(std::string setting, std::string def)
-{
- try {
- return _config->lookup(setting);
- }
- catch (std::exception &e)
- {
- return def;
- }
-}
-
-unsigned long
-ConfigReader::getULong(std::string setting, unsigned long def)
-{
- try {
- return static_cast(_config->lookup(setting));
- }
- catch (...)
- {
- return def;
- }
-}
-
-long
-ConfigReader::getLong(std::string setting, long def)
-{
- try {
- return _config->lookup(setting);
- }
- catch (...)
- {
- return def;
- }
-}
-
-bool
-ConfigReader::getBool(std::string setting, bool def)
-{
- try {
- return _config->lookup(setting);
- }
- catch (...)
- {
- return def;
- }
-}
-
diff --git a/src/config/ConfigReader.hpp b/src/config/ConfigReader.hpp
deleted file mode 100644
index c503053a..00000000
--- a/src/config/ConfigReader.hpp
+++ /dev/null
@@ -1,50 +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 .
- */
-
-#ifndef CONFIG_READER_HPP
-#define CONFIG_READER_HPP
-
-#include
-#include
-
-class ConfigReader
-{
- public:
-
- ConfigReader(const ConfigReader&) = delete;
- ConfigReader& operator=(const ConfigReader&) = delete;
-
- static ConfigReader& instance();
-
- void setFile(boost::filesystem::path p);
-
- /* Default values are returned in case of setting not found */
- std::string getString(std::string setting, std::string def = "");
- unsigned long getULong(std::string setting, unsigned long def = 0);
- long getLong(std::string setting, long def = 0);
- bool getBool(std::string setting, bool def = false);
-
- private:
-
- ConfigReader();
-
- libconfig::Config *_config;
-};
-
-#endif
diff --git a/src/cover/CoverArtGrabber.cpp b/src/cover/CoverArtGrabber.cpp
index 4b791049..738d04f3 100644
--- a/src/cover/CoverArtGrabber.cpp
+++ b/src/cover/CoverArtGrabber.cpp
@@ -18,7 +18,6 @@
*/
#include "logger/Logger.hpp"
-#include "config/ConfigReader.hpp"
#include "av/AvInfo.hpp"
#include "CoverArtGrabber.hpp"
diff --git a/src/lms-api/messages/Header.hpp b/src/lms-api/messages/Header.hpp
deleted file mode 100644
index d0e97cc6..00000000
--- a/src/lms-api/messages/Header.hpp
+++ /dev/null
@@ -1,105 +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 .
- */
-
-#ifndef REMOTE_HEADER_HPP
-#define REMOTE_HEADER_HPP
-
-#include
-
-namespace LmsAPI
-{
-
-
-class Header
-{
- public:
- static const std::size_t size = 8; // HeaderSize
- static const std::size_t max_data_size = 65536*64 - size;
-
- Header() : _dataSize(0) {}
-
- void setDataSize(std::size_t size) { _dataSize = size; }
- std::size_t getDataSize(void) const {return _dataSize;}
-
- bool from_istream(std::istream &is)
- {
- std::array buffer;
-
- bool res = is.read(reinterpret_cast(buffer.data()), buffer.size());
-
- if (res && is.gcount() == buffer.size())
- return from_buffer(buffer);
- else
- return false;
- }
-
- bool from_buffer(const std::array& buffer)
- {
- if (decode32(&buffer[0]) != _magic)
- {
- return false;
- }
- else
- {
- _dataSize = decode32(&buffer[4]);
- return _dataSize <= max_data_size;
- }
- }
-
-/* void to_ostream(std::ostream& os)
- {
-
-
- }*/
-
- void to_buffer(std::array& buffer) const
- {
- encode32(_magic, &buffer[0]);
- encode32(_dataSize, &buffer[4]);
- }
-
- private:
- static uint32_t decode32(const unsigned char* data)
- {
- return (static_cast(data[0]) << 24)
- + (static_cast(data[1]) << 16)
- + (static_cast(data[2]) << 8)
- + (static_cast(data[3]));
- }
-
- static void encode32(uint32_t value, unsigned char* data)
- {
- data[0] = (value >> 24) & 0xFF;
- data[1] = (value >> 16) & 0xFF;
- data[2] = (value >> 8) & 0xFF;
- data[3] = (value) & 0xFF;
- }
-
- static const uint32_t _magic = 0xdeadbeef;
-
- uint32_t _dataSize;
-};
-
-
-
-} // namespace LmsAPI
-
-
-#endif
-
diff --git a/src/lms-api/server/AudioCollectionRequestHandler.cpp b/src/lms-api/server/AudioCollectionRequestHandler.cpp
deleted file mode 100644
index 2f4a5427..00000000
--- a/src/lms-api/server/AudioCollectionRequestHandler.cpp
+++ /dev/null
@@ -1,393 +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 // std::min
-
-#include
-#include
-
-#include "logger/Logger.hpp"
-
-#include "AudioCollectionRequestHandler.hpp"
-
-#include "database/Types.hpp"
-#include "cover/CoverArtGrabber.hpp"
-
-namespace LmsAPI {
-namespace Server {
-
-using namespace Database;
-
-static SearchFilter SearchFilterFromRequest(const AudioCollectionRequest_SearchFilter& request)
-{
- SearchFilter filter;
-
- for (int id = 0; id < request.artist_id_size(); ++id)
- filter.idMatch[SearchFilter::Field::Artist].push_back( request.artist_id(id) );
-
- for (int id = 0; id < request.genre_id_size(); ++id)
- filter.idMatch[SearchFilter::Field::Genre].push_back( request.genre_id(id) );
-
- for (int id = 0; id < request.release_id_size(); ++id)
- filter.idMatch[SearchFilter::Field::Release].push_back( request.release_id(id) );
-
- for (int id = 0; id < request.track_id_size(); ++id)
- filter.idMatch[SearchFilter::Field::Track].push_back( request.track_id(id) );
-
- return filter;
-}
-
-AudioCollectionRequestHandler::AudioCollectionRequestHandler(Handler& db)
-: _db(db)
-{}
-
-bool
-AudioCollectionRequestHandler::process(const AudioCollectionRequest& request, AudioCollectionResponse& response)
-{
-
- bool res = false;
-
- switch (request.type())
- {
- case AudioCollectionRequest::TypeGetRevision:
- // No payload
- res = processGetRevision(*response.mutable_revision());
- if (res)
- response.set_type(AudioCollectionResponse::TypeRevision);
- break;
-
- case AudioCollectionRequest::TypeGetGenreList:
- if (request.has_get_genres())
- {
- res = processGetGenres(request.get_genres(), *response.mutable_genre_list());
- if (res)
- response.set_type(AudioCollectionResponse::TypeArtistList);
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad AudioCollectionRequest::TypeGetGenreList";
- break;
-
- case AudioCollectionRequest::TypeGetArtistList:
- if (request.has_get_artists())
- {
- res = processGetArtists(request.get_artists(), *response.mutable_artist_list());
- if (res)
- response.set_type(AudioCollectionResponse::TypeArtistList);
-
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad AudioCollectionRequest::TypeGetArtistList message!";
- break;
-
- case AudioCollectionRequest::TypeGetReleaseList:
- if (request.has_get_releases())
- {
- res = processGetReleases(request.get_releases(), *response.mutable_release_list());
- if (res)
- response.set_type(AudioCollectionResponse::TypeReleaseList);
-
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad AudioCollectionRequest::TypeGetReleaseList message!";
- break;
-
- case AudioCollectionRequest::TypeGetTrackList:
- if (request.has_get_tracks())
- {
- res = processGetTracks(request.get_tracks(), *response.mutable_track_list());
- if (res)
- response.set_type(AudioCollectionResponse::TypeTrackList);
-
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad AudioCollectionRequest::TypeGetTrackList message!";
- break;
-
- case AudioCollectionRequest::TypeGetCoverArt:
- if (request.has_get_cover_art())
- res = processGetCoverArt(request.get_cover_art(), response);
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad AudioCollectionRequest::TypeGetCoverArt message!";
- break;
-
- default:
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Unhandled AudioCollectionRequest_Type = " << request.type();
-
- }
-
- return res;
-}
-
-
-bool
-AudioCollectionRequestHandler::processGetGenres(const AudioCollectionRequest::GetGenreList& request, AudioCollectionResponse::GenreList& response)
-{
- // sanity checks
- if (!request.has_batch_parameter())
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "No batch parameters found!";
- return false;
- }
-
- std::size_t size = request.batch_parameter().size();
- if (!size)
- size = _maxListArtists;
- size = std::min(size, _maxListArtists);
-
- // Get filters
- SearchFilter filter;
- if (request.has_search_filter())
- filter = SearchFilterFromRequest(request.search_filter());
-
- Wt::Dbo::Transaction transaction( _db.getSession() );
-
- std::vector genres = Genre::getByFilter( _db.getSession(), filter, request.batch_parameter().offset(), static_cast(size));
-
- for (Genre::pointer genre : genres)
- {
- AudioCollectionResponse_Genre* addGenre = response.add_genres();
-
- addGenre->set_id(genre.id());
- addGenre->set_name( std::string( boost::locale::conv::to_utf(genre->getName(), "UTF-8") ) );
- }
-
- return true;
-}
-
-bool
-AudioCollectionRequestHandler::processGetArtists(const AudioCollectionRequest::GetArtistList& request, AudioCollectionResponse::ArtistList& response)
-{
- // sanity checks
- if (!request.has_batch_parameter())
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "No batch parameters found!";
- return false;
- }
-
- std::size_t size = request.batch_parameter().size();
- if (!size)
- size = _maxListArtists;
- size = std::min(size, _maxListArtists);
-
- // Get filters
- SearchFilter filter;
- if (request.has_search_filter())
- filter = SearchFilterFromRequest(request.search_filter());
-
- // Now fetch requested data...
-
- Wt::Dbo::Transaction transaction( _db.getSession() );
-
- std::vector artists
- = Artist::getByFilter(_db.getSession(), filter,
- request.batch_parameter().offset(), static_cast(size) );
-
- for (Artist::pointer artist : artists)
- {
- AudioCollectionResponse_Artist *addArtist = response.add_artists();
-
- addArtist->set_id(artist.id());
- addArtist->set_name( std::string( boost::locale::conv::to_utf(artist->getName(), "UTF-8") ) );
- if (!artist->getMBID().empty())
- addArtist->set_mbid(artist->getMBID());
- }
-
- return true;
-}
-
-bool
-AudioCollectionRequestHandler::processGetReleases(const AudioCollectionRequest::GetReleaseList& request, AudioCollectionResponse::ReleaseList& response)
-{
- // sanity checks
- if (!request.has_batch_parameter())
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "No batch parameters found!";
- return false;
- }
-
- std::size_t size = request.batch_parameter().size();
- if (!size)
- size = _maxListReleases;
- size = std::min(size, _maxListReleases);
-
- // Get filters
- SearchFilter filter;
- if (request.has_search_filter())
- filter = SearchFilterFromRequest(request.search_filter());
-
- Wt::Dbo::Transaction transaction( _db.getSession() );
-
- std::vector releases
- = Release::getByFilter( _db.getSession(), filter,
- request.batch_parameter().offset(), static_cast(size));
-
- for (Release::pointer release : releases)
- {
- AudioCollectionResponse_Release *addRelease = response.add_releases();
-
- addRelease->set_id(release.id());
- addRelease->set_name( std::string( boost::locale::conv::to_utf(release->getName(), "UTF-8")));
- if (!release->getMBID().empty())
- addRelease->set_mbid(release->getMBID());
- }
-
- return true;
-}
-
-bool
-AudioCollectionRequestHandler::processGetTracks(const AudioCollectionRequest::GetTrackList& request, AudioCollectionResponse::TrackList& response)
-{
- // sanity checks
- if (!request.has_batch_parameter())
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "No batch parameters found!";
- return false;
- }
-
- std::size_t size = request.batch_parameter().size();
- if (!size)
- size = _maxListTracks;
- size = std::min(size, _maxListTracks);
-
- // Get filters
- SearchFilter filter;
- if (request.has_search_filter())
- filter = SearchFilterFromRequest(request.search_filter());
-
- Wt::Dbo::Transaction transaction( _db.getSession() );
-
- std::vector tracks
- = Track::getByFilter( _db.getSession(), filter,
- request.batch_parameter().offset(), static_cast(size));
-
- for (Track::pointer track : tracks)
- {
- AudioCollectionResponse_Track* newTrack = response.add_tracks();
-
- newTrack->set_id(track.id());
- newTrack->set_disc_number( track->getDiscNumber() );
- newTrack->set_track_number( track->getTrackNumber() );
- newTrack->set_artist_id( track->getArtist().id() );
- newTrack->set_release_id( track->getRelease().id() );
-
- newTrack->set_name( std::string( boost::locale::conv::to_utf(track->getName(), "UTF-8") ) );
- newTrack->set_duration_secs( track->getDuration().total_seconds() );
-
- // Only send the year part of the release times
- if (!track->getDate().is_special())
- newTrack->set_release_date( std::to_string(track->getDate().date().year()) );
- if (!track->getOriginalDate().is_special())
- newTrack->set_original_release_date( std::to_string(track->getOriginalDate().date().year()) );
- if (!track->getMBID().empty())
- newTrack->set_mbid(track->getMBID());
-
- for (Genre::pointer genre : track->getGenres())
- newTrack->add_genre_id( genre.id() );
-
- }
-
- return true;
-}
-
-bool
-AudioCollectionRequestHandler::processGetCoverArt(const AudioCollectionRequest::GetCoverArt& request, AudioCollectionResponse& response)
-{
- bool res = false;
-
- response.set_type(AudioCollectionResponse::TypeCoverArt);
-
- std::vector coverArts;
-
- switch(request.type())
- {
- case AudioCollectionRequest::GetCoverArt::TypeGetCoverArtRelease:
- if (request.has_release_id())
- {
- coverArts = CoverArt::Grabber::instance().getFromRelease( _db.getSession(), request.release_id());
- res = true;
- }
- break;
-
- case AudioCollectionRequest::GetCoverArt::TypeGetCoverArtTrack:
- if (request.has_track_id())
- {
- coverArts = CoverArt::Grabber::instance().getFromTrack(_db.getSession(), request.track_id());
- res = true;
- }
- break;
- }
-
- for (CoverArt::CoverArt& coverArt : coverArts)
- {
- AudioCollectionResponse_CoverArt* cover_art = response.add_cover_art();
-
- if (request.has_size())
- {
- std::size_t size = request.size();
- if (size > _maxCoverArtSize || size == 0)
- size = _maxCoverArtSize;
- if (size < _minCoverArtSize)
- size = _minCoverArtSize;
-
- coverArt.scale(size);
- }
-
- cover_art->set_mime_type(coverArt.getMimeType());
- cover_art->set_data( std::string( coverArt.getData().begin(), coverArt.getData().end()) );
- }
-
- return res;
-}
-
-bool
-AudioCollectionRequestHandler::processGetRevision(AudioCollectionResponse::Revision& response)
-{
-
- bool res = false;
-
- Wt::Dbo::Transaction transaction( _db.getSession() );
-
- MediaDirectorySettings::pointer settings = MediaDirectorySettings::get( _db.getSession() );
-
- std::string hashStr = boost::posix_time::to_iso_string(settings->getLastUpdated());
-
- boost::uuids::detail::sha1 s;
- for (const char c : hashStr)
- s.process_byte(c);
-
- unsigned int digest[5];
- s.get_digest(digest);
-
- std::ostringstream oss;
- for (std::size_t i = 0; i < 5; ++i)
- oss << std::hex << std::setfill('0') << std::setw(4) << digest[i];
-
- response.set_rev(oss.str());
-
- res = true;
-
- return res;
-}
-
-
-
-} // namespace LmsAPI
-} // namespace Server
-
-
diff --git a/src/lms-api/server/AudioCollectionRequestHandler.hpp b/src/lms-api/server/AudioCollectionRequestHandler.hpp
deleted file mode 100644
index 5d7522c4..00000000
--- a/src/lms-api/server/AudioCollectionRequestHandler.hpp
+++ /dev/null
@@ -1,61 +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 .
- */
-
-#ifndef REMOTE_AUDIO_COLLECTION_REQUEST_HANDLER
-#define REMOTE_AUDIO_COLLECTION_REQUEST_HANDLER
-
-#include "database/DatabaseHandler.hpp"
-
-#include "messages.pb.h"
-
-namespace LmsAPI {
-namespace Server {
-
-class AudioCollectionRequestHandler
-{
- public:
- AudioCollectionRequestHandler(Database::Handler& db);
-
- bool process(const AudioCollectionRequest& request, AudioCollectionResponse& response);
-
- private:
-
- bool processGetRevision(AudioCollectionResponse::Revision& response);
- bool processGetArtists(const AudioCollectionRequest::GetArtistList& request, AudioCollectionResponse::ArtistList& response);
- bool processGetGenres(const AudioCollectionRequest::GetGenreList& request, AudioCollectionResponse::GenreList& response);
- bool processGetReleases(const AudioCollectionRequest::GetReleaseList& request, AudioCollectionResponse::ReleaseList& response);
- bool processGetTracks(const AudioCollectionRequest::GetTrackList& request, AudioCollectionResponse::TrackList& response);
- bool processGetCoverArt(const AudioCollectionRequest::GetCoverArt& request, AudioCollectionResponse& response);
-
- Database::Handler& _db;
-
- static const std::size_t _maxListArtists = 256;
- static const std::size_t _maxListGenres = 256;
- static const std::size_t _maxListReleases = 128;
- static const std::size_t _maxListTracks = 128;
-
- static const std::size_t _minCoverArtSize = 64; // in pixels, square
- static const std::size_t _maxCoverArtSize = 512; // in pixels, square
-};
-
-} // namespace LmsAPI
-} // namespace Server
-
-#endif
-
diff --git a/src/lms-api/server/AuthRequestHandler.cpp b/src/lms-api/server/AuthRequestHandler.cpp
deleted file mode 100644
index b0f98a70..00000000
--- a/src/lms-api/server/AuthRequestHandler.cpp
+++ /dev/null
@@ -1,105 +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 "logger/Logger.hpp"
-
-#include "AuthRequestHandler.hpp"
-
-namespace LmsAPI {
-namespace Server {
-
-AuthRequestHandler::AuthRequestHandler(Database::Handler& db)
-: _db(db)
-{
-}
-
-bool
-AuthRequestHandler::process(const AuthRequest& request, AuthResponse& response)
-{
- bool res = false;
-
- switch (request.type())
- {
- case AuthRequest::TypePassword:
- if (request.has_password())
- {
- res = processPassword(request.password(), *response.mutable_password_result());
- if (res)
- response.set_type(AuthResponse::TypePasswordResult);
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad AuthRequest::TypePassword";
- break;
- }
-
- return res;
-}
-
-
-bool
-AuthRequestHandler::processPassword(const AuthRequest::Password& request, AuthResponse::PasswordResult& response)
-{
- bool res = false;
-
- // Get the user
- const Wt::Auth::User& user = _db.getUserDatabase().findWithIdentity(Wt::Auth::Identity::LoginName, request.user_login());
- if (user.isValid())
- {
- // Now attempt to log the user in
-
- Wt::Auth::PasswordResult result = _db.getPasswordService().verifyPassword(user, request.user_password());
- switch( result )
- {
- case Wt::Auth::PasswordInvalid:
- response.set_type(AuthResponse::PasswordResult::TypePasswordInvalid);
- LMS_LOG(MOD_REMOTE, SEV_NOTICE) << "User '" << request.user_login() << "': invalid password";
- res = true;
- break;
- case Wt::Auth::LoginThrottling:
- response.set_type(AuthResponse::PasswordResult::TypeLoginThrottling);
- response.set_delay(_db.getPasswordService().delayForNextAttempt(user));
- res = true;
- break;
- case Wt::Auth::PasswordValid:
- response.set_type(AuthResponse::PasswordResult::TypePasswordValid);
- // Log the user in
- _db.getLogin().login( user );
- LMS_LOG(MOD_REMOTE, SEV_NOTICE) << "User '" << request.user_login() << "' successfully logged in";
- res = true;
- break;
- default:
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Cannot handle password result!";
- break;
- }
-
- }
- else
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Invalid user '" << request.user_login();
- response.set_type(AuthResponse::PasswordResult::TypePasswordInvalid);
- }
-
- return res;
-}
-
-} // namespace Server
-} // namespace LmsAPI
-
diff --git a/src/lms-api/server/AuthRequestHandler.hpp b/src/lms-api/server/AuthRequestHandler.hpp
deleted file mode 100644
index 363dcab2..00000000
--- a/src/lms-api/server/AuthRequestHandler.hpp
+++ /dev/null
@@ -1,47 +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 .
- */
-
-#ifndef LMSAPI_AUTH_REQUEST_HANDLER
-#define LMSAPI_AUTH_REQUEST_HANDLER
-
-#include "database/DatabaseHandler.hpp"
-
-#include "messages.pb.h"
-
-namespace LmsAPI {
-namespace Server {
-
-class AuthRequestHandler
-{
- public:
- AuthRequestHandler(Database::Handler& db);
-
- bool process(const AuthRequest& request, AuthResponse& response);
-
- private:
-
- bool processPassword(const AuthRequest::Password& request, AuthResponse::PasswordResult& response);
-
- Database::Handler& _db;
-};
-
-} // namespace Server
-} // namespace LmsAPI
-
-#endif
diff --git a/src/lms-api/server/Connection.cpp b/src/lms-api/server/Connection.cpp
deleted file mode 100644
index f8d0e688..00000000
--- a/src/lms-api/server/Connection.cpp
+++ /dev/null
@@ -1,250 +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 "logger/Logger.hpp"
-
-#include "messages.pb.h"
-
-#include "RequestHandler.hpp"
-
-#include "ConnectionManager.hpp"
-#include "Connection.hpp"
-
-namespace LmsAPI {
-namespace Server {
-
-Connection::Connection(boost::asio::io_service& ioService,
- boost::asio::ssl::context& context,
- ConnectionManager& manager,
- Wt::Dbo::SqlConnectionPool& connectionPool)
-: _closing(false),
-_socket(ioService, context),
-_connectionManager(manager),
-_requestHandler(connectionPool)
-{
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "Server::Connection::Connection, Creating connection";
-}
-
-void
-Connection::start()
-{
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "Starting connection...";
- _socket.async_handshake(boost::asio::ssl::stream_base::server,
- boost::bind(&Connection::handleHandshake, this,
- boost::asio::placeholders::error));
-}
-
-void
-Connection::handleHandshake(const boost::system::error_code& error)
-{
- if (!error)
- {
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "Handshake successfully performed... Now reading messages";
- readMsg();
- }
- else if (error != boost::asio::error::operation_aborted)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Connection::handleHandshake: " << error.message();
- _connectionManager.stop(shared_from_this());
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Handshake error: " << error.message();
-}
-
-
-void
-Connection::readMsg()
-{
- // Read a header first
- boost::asio::streambuf::mutable_buffers_type bufs = _inputStreamBuf.prepare(LmsAPI::Header::size);
-
- boost::asio::async_read(_socket,
- bufs,
- boost::asio::transfer_exactly(LmsAPI::Header::size),
- boost::bind(&Connection::handleReadHeader, shared_from_this(),
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred));
-}
-
-void
-Connection::stop()
-{
- if (!_closing)
- {
- boost::system::error_code ec;
-
- _closing = true;
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "Server::Connection::stop, Stopping connection " << this;
- _socket.shutdown(ec);
-
- if (ec)
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Error while shutting down connection " << this << ": " << ec.message();
-
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "Server::Connection::stop, connection stopped " << this;
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "Stop: close already in progress...";
-}
-
-void
-Connection::handleReadHeader(const boost::system::error_code& error, std::size_t bytes_transferred)
-{
- if (!error)
- {
- if (bytes_transferred != LmsAPI::Header::size)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "bytes_transferred (" << bytes_transferred << ") != LmsAPI::Header::size!";
- _connectionManager.stop(shared_from_this());
- return;
- }
-
- _inputStreamBuf.commit(bytes_transferred);
-
- std::istream is(&_inputStreamBuf);
-
- LmsAPI::Header header;
- if (!header.from_istream(is))
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Cannot read header from buffer!";
- _connectionManager.stop(shared_from_this());
- return;
- }
-
- // Now read the real message payload
- boost::asio::streambuf::mutable_buffers_type bufs = _inputStreamBuf.prepare(header.getDataSize());
-
- boost::asio::async_read(_socket,
- bufs,
- boost::asio::transfer_exactly(header.getDataSize()),
- boost::bind(&Connection::handleReadMsg, shared_from_this(),
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred));
-
- }
- else if (error != boost::asio::error::operation_aborted)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Connection::handleReadHeader: " << error.message();
- _connectionManager.stop(shared_from_this());
- }
-}
-
-void
-Connection::handleReadMsg(const boost::system::error_code& error, std::size_t bytes_transferred)
-{
- if (!error)
- {
- _inputStreamBuf.commit(bytes_transferred);
-
- std::istream is(&_inputStreamBuf);
- std::ostream os(&_outputStreamBuf);
-
- LmsAPI::ServerMessage response;
- LmsAPI::ClientMessage request;
-
- if (!request.ParseFromIstream(&is))
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Parse request failed!";
- _connectionManager.stop(shared_from_this());
- return;
- }
-
- if (!_requestHandler.process(request, response))
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Process request failed!";
- _connectionManager.stop(shared_from_this());
- return;
- }
-
- {
- boost::system::error_code ec;
-
- if (!response.SerializeToOstream(&os))
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Cannot serialize to ostream!";
- _connectionManager.stop(shared_from_this());
- return;
- }
-
- if (_outputStreamBuf.size() >= LmsAPI::Header::max_data_size)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "output message is too big! " << _outputStreamBuf.size() << " > " << LmsAPI::Header::max_data_size;
- _connectionManager.stop(shared_from_this());
- return;
- }
-
- std::array headerBuffer;
- {
- LmsAPI::Header header;
- header.setDataSize(_outputStreamBuf.size());
- header.to_buffer(headerBuffer);
- }
-
- std::size_t n = boost::asio::write(_socket,
- boost::asio::buffer(headerBuffer),
- boost::asio::transfer_exactly(LmsAPI::Header::size),
- ec);
- if (ec)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "cannot write header: " << error.message();
- _connectionManager.stop(shared_from_this());
- }
- else
- {
- assert(n == LmsAPI::Header::size);
- }
-
- // Now send serialized payload
- n = boost::asio::write(_socket,
- _outputStreamBuf.data(),
- boost::asio::transfer_exactly(_outputStreamBuf.size()),
- ec);
-
- if (ec)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "cannot write msg: " << error.message();
- _connectionManager.stop(shared_from_this());
- }
- else
- {
- assert(n == _outputStreamBuf.size());
- _outputStreamBuf.consume(n);
- }
-
- }
-
- // All good here, read another message
- readMsg();
- }
- else if (error != boost::asio::error::operation_aborted)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Connection::handleRead: " << error.message();
- _connectionManager.stop(shared_from_this());
- }
-}
-
-
-} // namespace Server
-} // namespace LmsAPI
diff --git a/src/lms-api/server/Connection.hpp b/src/lms-api/server/Connection.hpp
deleted file mode 100644
index b254733f..00000000
--- a/src/lms-api/server/Connection.hpp
+++ /dev/null
@@ -1,98 +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 .
- */
-
-#ifndef LMSAPI_CONNECTION_HPP
-#define LMSAPI_CONNECTION_HPP
-
-#include
-#include
-
-#include
-#include
-
-#include "RequestHandler.hpp"
-
-#include "messages/Header.hpp"
-
-namespace LmsAPI {
-namespace Server {
-
-class ConnectionManager;
-
-/// Represents a single connection from a client.
-class Connection : public std::enable_shared_from_this
-{
- public:
-
- typedef boost::asio::ssl::stream ssl_socket;
-
- Connection(const Connection&) = delete;
- Connection& operator=(const Connection&) = delete;
-
- typedef std::shared_ptr pointer;
-
- /// Construct a connection with the given io_service.
- explicit Connection(boost::asio::io_service& ioService, boost::asio::ssl::context& context,
- ConnectionManager& manager,
- Wt::Dbo::SqlConnectionPool& connectionPool);
-
- ssl_socket::lowest_layer_type& getSocket() {return _socket.lowest_layer();}
-
- /// Start the first asynchronous operation for the connection.
- void start();
-
- /// Stop all asynchronous operations associated with the connection.
- void stop();
-
- private:
- bool _closing;
-
- /// Read a new message on the the connection
- void readMsg();
-
- /// Handle completion of ssl handshake
- void handleHandshake(const boost::system::error_code& error);
-
- /// Handle completion of a read operation.
- void handleReadHeader(const boost::system::error_code& e,
- std::size_t bytes_transferred);
-
- void handleReadMsg(const boost::system::error_code& e,
- std::size_t bytes_transferred);
-
- /// Socket for the connection.
- ssl_socket _socket;
-
- /// The manager for this connection.
- ConnectionManager& _connectionManager;
-
- /// The handler used to process the incoming requests.
- RequestHandler _requestHandler;
-
- boost::asio::streambuf _inputStreamBuf;
- boost::asio::streambuf _outputStreamBuf;
-};
-
-
-} // namespace Server
-} // namespace LmsAPI
-
-#endif
-
-
diff --git a/src/lms-api/server/ConnectionManager.cpp b/src/lms-api/server/ConnectionManager.cpp
deleted file mode 100644
index c4fc6eb7..00000000
--- a/src/lms-api/server/ConnectionManager.cpp
+++ /dev/null
@@ -1,62 +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 "ConnectionManager.hpp"
-
-namespace LmsAPI {
-namespace Server {
-
-ConnectionManager::ConnectionManager()
-{
-}
-
-
-void
-ConnectionManager::start(Connection::pointer c)
-{
- _connections.insert(c);
- c->start();
-}
-
-void
-ConnectionManager::stop(Connection::pointer c)
-{
- _connections.erase(c);
- c->stop();
-}
-
-void
-ConnectionManager::stopAll()
-{
- BOOST_FOREACH(Connection::pointer c, _connections)
- {
- c->stop();
- }
- _connections.clear();
-}
-
-
-} // namespace Server
-} // namespace LmsAPI
-
-
diff --git a/src/lms-api/server/ConnectionManager.hpp b/src/lms-api/server/ConnectionManager.hpp
deleted file mode 100644
index ce2b194a..00000000
--- a/src/lms-api/server/ConnectionManager.hpp
+++ /dev/null
@@ -1,58 +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 .
- */
-
-#ifndef REMOTE_CONNECTION_MANAGER_HPP
-#define REMOTE_CONNECTION_MANAGER_HPP
-
-#include
-
-#include "Connection.hpp"
-
-namespace LmsAPI {
-namespace Server {
-
-/// Manages open connections so that they may be cleanly stopped when the server
-/// needs to shut down.
-
-class ConnectionManager
-{
- public:
- ConnectionManager(const ConnectionManager&) = delete;
- ConnectionManager& operator=(const ConnectionManager&) = delete;
-
- ConnectionManager();
-
- /// Add the specified connection to the manager and start it.
- void start(Connection::pointer c);
-
- /// Stop the specified connection.
- void stop(Connection::pointer c);
-
- /// Stop all connections.
- void stopAll();
-
- private:
- /// The managed connections.
- std::set _connections;
-};
-
-} // namespace Server
-} // namespace LmsAPI
-
-#endif
diff --git a/src/lms-api/server/MediaRequestHandler.cpp b/src/lms-api/server/MediaRequestHandler.cpp
deleted file mode 100644
index be3e6b53..00000000
--- a/src/lms-api/server/MediaRequestHandler.cpp
+++ /dev/null
@@ -1,217 +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 "logger/Logger.hpp"
-
-#include "MediaRequestHandler.hpp"
-
-#include "database/Types.hpp"
-
-namespace LmsAPI {
-namespace Server {
-
-MediaRequestHandler::MediaRequestHandler(Database::Handler& db)
-: _db(db)
-{}
-
-bool
-MediaRequestHandler::process(const MediaRequest& request, MediaResponse& response)
-{
-
- bool res = false;
-
- switch (request.type())
- {
- case MediaRequest::TypeMediaPrepare:
- if (request.has_prepare())
- {
- if (request.prepare().has_audio())
- res = processAudioPrepare(request.prepare().audio(), *response.mutable_prepare_result());
- else if (request.prepare().has_video())
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Video prepare not supported!";
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad MediaRequest::TypeMediaPrepare!";
-
- if (res)
- response.set_type(MediaResponse::TypePrepareResult);
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad MediaRequest::TypeMediaPrepare!";
- break;
-
- case MediaRequest::TypeMediaGetPart:
- if (request.has_get_part())
- {
- res = processGetPart(request.get_part(), *response.mutable_part_result());
- if (res)
- response.set_type(MediaResponse::TypePartResult);
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad MediaRequest::TypeMediaGet!";
-
- break;
-
- case MediaRequest::TypeMediaTerminate:
- if (request.has_terminate())
- {
- res = processTerminate(request.terminate(), *response.mutable_terminate_result());
- if (res)
- response.set_type(MediaResponse::TypePartResult);
- }
- else
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Bad MediaRequest::TypeMediaTerminate!";
-
- break;
-
- default:
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Unhandled MediaRequest type = " << request.type();
- }
-
- return res;
-}
-
-bool
-MediaRequestHandler::processAudioPrepare(const MediaRequest::Prepare::Audio& request, MediaResponse::PrepareResult& response)
-{
- std::size_t bitrate;
- Transcode::Format::Encoding format;
-
- switch( request.codec_type())
- {
- case MediaRequest::Prepare::AudioCodecTypeOGA: format = Transcode::Format::OGA; break;
- default:
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Unhandled codec type = " << request.codec_type();
- return false;
- }
-
- switch( request.bitrate() )
- {
- case MediaRequest::Prepare::AudioBitrate_32_kbps: bitrate = 32000; break;
- case MediaRequest::Prepare::AudioBitrate_64_kbps: bitrate = 64000; break;
- case MediaRequest::Prepare::AudioBitrate_96_kbps: bitrate = 96000; break;
- case MediaRequest::Prepare::AudioBitrate_128_kbps: bitrate = 128000; break;
- case MediaRequest::Prepare::AudioBitrate_192_kbps: bitrate = 192000; break;
- case MediaRequest::Prepare::AudioBitrate_256_kbps: bitrate = 256000; break;
- default:
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Unhandled bitrate type = " << request.bitrate();
- return false;
- }
-
- // TODO use user's bitrate limits!
- // TODO limit transcoder number by user?
-
- if (_transcoders.size() + 1 > _maxTranscoders)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Transcoder limit reached!" << std::endl;
- // Just answer an empty response, dont delete existing trasncode jobs
- return true;
- }
-
- try
- {
- Wt::Dbo::Transaction transaction( _db.getSession());
-
- Database::Track::pointer track = Database::Track::getById( _db.getSession(), request.track_id() );
- if (!track)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Requested track does not exist" << std::endl;
- // Track does no longer exist, just answer an empty response
- return true;
- }
-
- Transcode::InputMediaFile inputFile(track->getPath());
- Transcode::Parameters parameters(inputFile, Transcode::Format::get( format ));
- parameters.setBitrate( Transcode::Stream::Audio, bitrate);
-
- std::shared_ptr transcoder = std::make_shared( parameters );
-
- // now get a unique id (relative to this connection!)
- uint32_t handle = _curHandle++;
- assert(_transcoders.find(handle) == _transcoders.end());
-
- _transcoders[handle] = transcoder;
-
- response.set_handle(handle);
-
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "Set up new transcode, handle = " << handle;
- }
- catch(std::exception& e)
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "Caught exception: " << e.what();
- return false;
- }
-
- return true;
-}
-
-bool
-MediaRequestHandler::processGetPart(const MediaRequest::GetPart& request, MediaResponse::PartResult& response)
-{
- std::size_t dataSize = request.requested_data_size();
- std::vector data;
- if (dataSize > _maxPartSize)
- dataSize = _maxPartSize;
-
- TranscoderMap::iterator itTranscoder = _transcoders.find(request.handle());
- if (itTranscoder == _transcoders.end())
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "No transcoder found for handle " << request.handle();
- return true;
- }
-
- std::shared_ptr transcoder = itTranscoder->second;
-
- if (!transcoder->isComplete())
- {
- data.reserve(dataSize);
- transcoder->process(data, dataSize);
- }
-
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "MediaRequestHandler::processGetPart, handle = " << request.handle() << ", isComplete = " << std::boolalpha << transcoder->isComplete() << ", size = " << data.size();
-
- std::copy(data.begin(), data.end(), std::back_inserter(*response.mutable_data()));
-
- return true;
-}
-
-
-bool
-MediaRequestHandler::processTerminate(const MediaRequest::Terminate& request, MediaResponse::TerminateResult& response)
-{
- LMS_LOG(MOD_REMOTE, SEV_DEBUG) << "MediaRequestHandler: resetting transcoder for handle " << request.handle();
-
- if (_transcoders.find(request.handle()) == _transcoders.end())
- {
- LMS_LOG(MOD_REMOTE, SEV_ERROR) << "No transcoder found for handle " << request.handle();
- return true;
- }
- else
- {
- _transcoders.erase(request.handle());
- }
-
- return true;
-}
-
-
-
-} // namespace LmsAPI
-} // namespace Server
-
-
diff --git a/src/lms-api/server/MediaRequestHandler.hpp b/src/lms-api/server/MediaRequestHandler.hpp
deleted file mode 100644
index f3f30c20..00000000
--- a/src/lms-api/server/MediaRequestHandler.hpp
+++ /dev/null
@@ -1,65 +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 .
- */
-
-#ifndef REMOTE_MEDIA_REQUEST_HANDLER
-#define REMOTE_MEDIA_REQUEST_HANDLER
-
-#include