polybar-dwm/include/interfaces/mpd.hpp

189 lines
4.2 KiB
C++
Raw Normal View History

#pragma once
2016-05-19 14:41:06 +00:00
#include <string>
#include <stdlib.h>
#include <memory>
#include <chrono>
#include <mpd/client.h>
#include "config.hpp"
#include "lemonbuddy.hpp"
#include "exception.hpp"
#include "utils/math.hpp"
namespace mpd
{
class Exception : public ::Exception
{
public:
2016-06-21 01:59:43 +00:00
Exception(std::string msg, bool clearable)
2016-05-19 14:41:06 +00:00
: ::Exception(msg + (clearable ? " (clearable)" : " (not clearable)")){}
};
class ClientError : public Exception
{
public:
2016-06-21 01:59:43 +00:00
explicit ClientError(std::string msg, mpd_error code, bool clearable)
2016-05-19 14:41:06 +00:00
: Exception("[mpd::ClientError::"+ std::to_string(code) +"] "+ msg, clearable){}
};
class ServerError : public Exception
{
public:
2016-06-21 01:59:43 +00:00
ServerError(std::string msg, mpd_server_error code, bool clearable)
2016-05-19 14:41:06 +00:00
: Exception("[mpd::ServerError::"+ std::to_string(code) +"] "+ msg, clearable){}
};
enum State
{
UNKNOWN = 1 << 0,
STOPPED = 1 << 1,
PLAYING = 1 << 2,
PAUSED = 1 << 4,
};
struct Song
{
Song(){}
explicit Song(mpd_song *song);
2016-05-19 14:41:06 +00:00
std::shared_ptr<mpd_song> song;
std::string get_artist();
std::string get_album();
std::string get_title();
// unsigned get_duration();
2016-05-19 14:41:06 +00:00
operator bool() {
return this->song.get() != nullptr;
}
};
class Connection;
2016-05-19 14:41:06 +00:00
struct Status
{
struct StatusDeleter
{
void operator()(mpd_status *status) {
mpd_status_free(status);
}
};
explicit Status(mpd_status *status);
2016-05-19 14:41:06 +00:00
std::unique_ptr<struct mpd_status, StatusDeleter> status;
std::unique_ptr<Song> song;
std::chrono::system_clock::time_point updated_at;
int state = UNKNOWN;
bool random = false,
repeat = false,
single = false;
int song_id;
unsigned long total_time;
unsigned long elapsed_time;
unsigned long elapsed_time_ms;
void set(std::unique_ptr<struct mpd_status, StatusDeleter> status);
void update(int event, std::unique_ptr<Connection>& connection);
2016-06-27 21:16:51 +00:00
void update(int event, Connection *connection);
2016-05-19 14:41:06 +00:00
void update_timer();
// unsigned get_total_time();
// unsigned get_elapsed_time();
2016-05-19 14:41:06 +00:00
unsigned get_elapsed_percentage();
std::string get_formatted_elapsed();
std::string get_formatted_total();
};
class Connection
{
struct ConnectionDeleter
{
void operator()(mpd_connection *connection)
{
if (connection == nullptr)
return;
//TRACE("Releasing mpd_connection");
mpd_connection_free(connection);
}
};
std::unique_ptr<mpd_connection, ConnectionDeleter> connection;
std::string host;
std::string password;
int port;
2016-05-19 14:41:06 +00:00
int timeout = 15;
bool mpd_command_list_active = false;
bool mpd_idle = false;
int mpd_fd;
2016-06-01 14:29:17 +00:00
void check_connection();
2016-05-19 14:41:06 +00:00
void check_prerequisites();
void check_prerequisites_commands_list();
2016-06-01 14:29:17 +00:00
void check_errors();
2016-05-19 14:41:06 +00:00
public:
Connection(std::string host, int port, std::string password)
: host(host), password(password), port(port) {}
2016-05-19 14:41:06 +00:00
2016-06-01 14:29:17 +00:00
void connect();
2016-05-19 14:41:06 +00:00
void disconnect();
bool connected();
// bool retry_connection(int interval = 1);
2016-05-19 14:41:06 +00:00
void idle();
int noidle();
2016-06-21 01:59:43 +00:00
void set_host(std::string host) { this->host = host; }
2016-05-19 14:41:06 +00:00
void set_port(int port) { this->port = port; }
2016-06-21 01:59:43 +00:00
void set_password(std::string password) { this->password = password; }
2016-05-19 14:41:06 +00:00
void set_timeout(int timeout) { this->timeout = timeout; }
2016-06-27 21:16:51 +00:00
std::unique_ptr<Status> get_status(bool update = true);
std::unique_ptr<Status> get_status_safe(bool update = true);
2016-05-19 14:41:06 +00:00
std::unique_ptr<Song> get_song();
void play();
void pause(bool state);
// void toggle();
2016-05-19 14:41:06 +00:00
void stop();
void prev();
void next();
void seek(int percentage);
void set_repeat(bool mode);
void set_random(bool mode);
void set_single(bool mode);
2016-05-19 14:41:06 +00:00
};
struct MpdStatus
{
bool random, repeat, single;
std::string artist;
std::string album;
std::string title;
int elapsed_time = 0;
int total_time = 0;
float get_elapsed_percentage();
std::string get_formatted_elapsed();
std::string get_formatted_total();
operator bool() {
return !this->artist.empty() && !this->title.empty();
}
};
}