/******************************************************************************!
* \file Server.cpp
* \author Sebastien Beaugrand
* \sa http://beaugrand.chez.com/
* \copyright CeCILL 2.1 Free Software license
******************************************************************************/
#include <chrono>
#include <iostream>
#include <filesystem>
#include <algorithm>
#include "Server.h"
#include "List.h"
#include "Player.h"
#include "path.h"
#include "log.h"
/******************************************************************************!
* \fn Server
******************************************************************************/
Server::Server(jsonrpc::AbstractServerConnector& conn,
List& list,
Player& player)
: AbstractStubServer(conn, jsonrpc::JSONRPC_SERVER_V1V2)
, mList(list)
, mPlayer(player)
{
this->StartListening();
}
/******************************************************************************!
* \fn ~Server
******************************************************************************/
Server::~Server()
{
DEBUG("");
this->StopListening();
}
/******************************************************************************!
* \fn list
******************************************************************************/
Json::Value
Server::list()
{
DEBUG("");
Json::Value result = mPlayer.titleList();
return result;
}
/******************************************************************************!
* \fn info
******************************************************************************/
Json::Value
Server::info()
{
DEBUG("");
Json::Value result = mPlayer.currentTitle();
result["abrev"] = mAbrev;
return result;
}
/******************************************************************************!
* \fn rand
******************************************************************************/
Json::Value
Server::rand()
{
DEBUG("");
const auto [path, abrev, days] = mList.rand();
mSelect = path;
mSelectTime = std::chrono::steady_clock::now();
mAbrev = abrev;
const auto [arti, date, albu] = ::splitPath(path);
Json::Value result;
result["artist"] = arti;
result["date"] = date;
result["album"] = albu;
result["abrev"] = abrev;
result["days"] = days;
return result;
}
/******************************************************************************!
* \fn ok
******************************************************************************/
Json::Value
Server::ok()
{
DEBUG("");
if (! mSelect.empty() && mSelectTime !=
std::chrono::time_point<std::chrono::steady_clock>::min()) {
const auto now = std::chrono::steady_clock::now();
const std::chrono::duration<double> diff = now - mSelectTime;
if (diff.count() < 20) {
mPlayer.m3u(mSelect);
mList.writeLog(mSelect);
mSelectTime =
std::chrono::time_point<std::chrono::steady_clock>::min();
Json::Value json = mPlayer.currentTitle();
json["cs"] = -1;
return json;
} else {
mAbrev.clear();
mSelectTime =
std::chrono::time_point<std::chrono::steady_clock>::min();
}
}
return this->pause();
}
/******************************************************************************!
* \fn play
******************************************************************************/
Json::Value
Server::play()
{
DEBUG("");
mPlayer.start();
Json::Value result = mPlayer.currentTitle();
result["abrev"] = mAbrev;
return result;
}
/******************************************************************************!
* \fn pause
******************************************************************************/
Json::Value
Server::pause()
{
DEBUG("");
mPlayer.pause();
Json::Value result = mPlayer.currentTitle();
result["abrev"] = mAbrev;
return result;
}
/******************************************************************************!
* \fn stop
******************************************************************************/
Json::Value
Server::stop()
{
DEBUG("");
auto ms = mPlayer.getPlaytime();
mList.writeResumeTime(ms);
mPlayer.stop();
Json::Value result;
result["result"] = "ok";
return result;
}
/******************************************************************************!
* \fn prev
******************************************************************************/
Json::Value
Server::prev()
{
DEBUG("");
mPlayer.startRel(-1);
Json::Value result = mPlayer.currentTitle();
result["abrev"] = mAbrev;
return result;
}
/******************************************************************************!
* \fn next
******************************************************************************/
Json::Value
Server::next()
{
DEBUG("");
mPlayer.startRel(1);
Json::Value result = mPlayer.currentTitle();
result["abrev"] = mAbrev;
return result;
}
/******************************************************************************!
* \fn artist
******************************************************************************/
Json::Value
Server::artist()
{
DEBUG("");
Json::Value json = mPlayer.currentTitle();
return mList.artist(json["artist"].asString(),
json["album"].asString());
}
/******************************************************************************!
* \fn album
******************************************************************************/
Json::Value
Server::album(const std::string& artist, int pos)
{
DEBUG("");
const auto [path, abrev] = mList.album(artist, pos);
if (! path.empty()) {
mPlayer.m3u(path);
mSelect = path;
mSelectTime =
std::chrono::time_point<std::chrono::steady_clock>::min();
mAbrev = abrev;
mList.writeLog(path);
}
Json::Value result = mPlayer.currentTitle();
if (path.empty()) {
result["abrev"] = mAbrev;
} else if (pos != -1) {
result["cs"] = -1;
}
return result;
}
/******************************************************************************!
* \fn pos
******************************************************************************/
Json::Value
Server::pos(int pos)
{
DEBUG("");
mPlayer.startId(pos);
Json::Value result = mPlayer.currentTitle();
result["abrev"] = mAbrev;
return result;
}
/******************************************************************************!
* \fn dir
******************************************************************************/
Json::Value
Server::dir(const std::string& path)
{
auto p = path;
std::ranges::replace(p, '+', ' ');
DEBUG(p);
if (std::filesystem::exists(mPlayer.musicDirectory + '/' +
p + "/00.m3u")) {
mPlayer.m3u(p + "/00.m3u");
mList.writeLog(p + "/00.m3u");
return Json::Value{};
} else {
return mList.dir(p);
}
}
/******************************************************************************!
* \fn quit
******************************************************************************/
void
Server::quit()
{
DEBUG("");
this->loop = false;
loop.notify_one();
}
/******************************************************************************!
* \fn musicDirectory
******************************************************************************/
std::string
Server::musicDirectory()
{
return mPlayer.musicDirectory;
}
/******************************************************************************!
* \fn checksum
******************************************************************************/
Json::Value
Server::checksum()
{
DEBUG("");
int cs = 0;
std::string path =
mPlayer.musicDirectory + '/' +
mSelect.substr(0, mSelect.rfind('/') + 1);
if (std::filesystem::exists(path + ".sha")) {
auto cmd = std::string("cd \"") + path +
"\"; /usr/bin/sha1sum -c .sha >/dev/null";
if (::system(cmd.c_str()) != 0) {
cs = 1;
ERROR(cs);
}
} else {
auto cmd = std::string("cd \"") + path +
"\"; /usr/bin/sha1sum * >.sha";
if (::system(cmd.c_str()) != 0) {
cs = 2;
ERROR(cs);
}
}
Json::Value json = mPlayer.currentTitle();
if (cs) {
json["cs"] = cs;
} else {
json["abrev"] = mAbrev;
}
return json;
}