lastfm gui
This commit is contained in:
parent
35d0ce747b
commit
6f29111c40
|
@ -65,10 +65,6 @@ public:
|
||||||
|
|
||||||
parameters["api_sig"] = getApiSignature(parameters);
|
parameters["api_sig"] = getApiSignature(parameters);
|
||||||
|
|
||||||
// if you url encode the parameters before making the signature, the signature will be invalid. But url encoding
|
|
||||||
// is needed to properly handle non ascii characters. Notice to myself: The last fm api is horrible.
|
|
||||||
parameters["artist"] = utils::urlEncode(artist);
|
|
||||||
parameters["track"] = utils::urlEncode(track);
|
|
||||||
std::string postBody = utils::getURLEncodedPostBody(parameters);
|
std::string postBody = utils::getURLEncodedPostBody(parameters);
|
||||||
std::string response = utils::httpRequest(api_base, "POST", postBody);
|
std::string response = utils::httpRequest(api_base, "POST", postBody);
|
||||||
|
|
||||||
|
|
182
src/main.cpp
182
src/main.cpp
|
@ -16,6 +16,7 @@
|
||||||
std::string lastPlayingSong = "";
|
std::string lastPlayingSong = "";
|
||||||
std::string lastMediaSource = "";
|
std::string lastMediaSource = "";
|
||||||
std::string currentSongTitle = "";
|
std::string currentSongTitle = "";
|
||||||
|
LastFM* lastfm = nullptr;
|
||||||
|
|
||||||
void handleRPCTasks() {
|
void handleRPCTasks() {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -37,16 +38,23 @@ void handleRPCTasks() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleMediaTasks() {
|
void initLastFM(bool checkMode = false) {
|
||||||
|
if (lastfm)
|
||||||
|
delete lastfm;
|
||||||
auto settings = utils::getSettings();
|
auto settings = utils::getSettings();
|
||||||
LastFM lastfm(settings.lastfm.username, settings.lastfm.password, settings.lastfm.api_key,
|
if (!settings.lastfm.enabled && !checkMode)
|
||||||
|
return;
|
||||||
|
lastfm = new LastFM(settings.lastfm.username, settings.lastfm.password, settings.lastfm.api_key,
|
||||||
settings.lastfm.api_secret);
|
settings.lastfm.api_secret);
|
||||||
if (settings.lastfm.enabled) {
|
LastFM::LASTFM_STATUS status = lastfm->authenticate();
|
||||||
LastFM::LASTFM_STATUS status = lastfm.authenticate();
|
|
||||||
if (status)
|
if (status)
|
||||||
wxMessageBox(_("Error authenticating at LastFM!"), _("PlayerLink"), wxOK | wxICON_ERROR);
|
wxMessageBox(_("Error authenticating at LastFM!"), _("PlayerLink"), wxOK | wxICON_ERROR);
|
||||||
|
else if (checkMode)
|
||||||
|
wxMessageBox(_("The LastFM authentication was successful."), _("PlayerLink"), wxOK | wxICON_INFORMATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleMediaTasks() {
|
||||||
|
initLastFM();
|
||||||
int64_t lastMs = 0;
|
int64_t lastMs = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
@ -76,8 +84,9 @@ void handleMediaTasks() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (lastPlayingSong.find(mediaInformation->songTitle + mediaInformation->songArtist +
|
if (lastPlayingSong.find(mediaInformation->songTitle + mediaInformation->songArtist +
|
||||||
mediaInformation->songAlbum) == std::string::npos)
|
mediaInformation->songAlbum) == std::string::npos &&
|
||||||
lastfm.scrobble(mediaInformation->songArtist, mediaInformation->songTitle);
|
lastfm)
|
||||||
|
lastfm->scrobble(mediaInformation->songArtist, mediaInformation->songTitle);
|
||||||
|
|
||||||
lastPlayingSong = currentlyPlayingSong;
|
lastPlayingSong = currentlyPlayingSong;
|
||||||
currentSongTitle = mediaInformation->songArtist + " - " + mediaInformation->songTitle;
|
currentSongTitle = mediaInformation->songArtist + " - " + mediaInformation->songTitle;
|
||||||
|
@ -166,16 +175,46 @@ private:
|
||||||
wxFrame* settingsFrame;
|
wxFrame* settingsFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerLinkFrame : public wxFrame {
|
class wxTextCtrlWithPlaceholder : public wxTextCtrl {
|
||||||
protected:
|
public:
|
||||||
wxStaticText* settingsText;
|
wxTextCtrlWithPlaceholder(wxWindow* parent, wxWindowID id, const wxString& value,
|
||||||
wxStaticLine* settingsDivider;
|
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||||
wxStaticText* enabledAppsText;
|
long style = 0, const wxValidator& validator = wxDefaultValidator,
|
||||||
wxCheckBox* anyOtherCheckbox;
|
const wxString& name = "textCtrl")
|
||||||
wxStaticLine* appsDivider;
|
: wxTextCtrl(parent, id, value, pos, size, style, validator, name), placeholder(""), showPlaceholder(true) {
|
||||||
wxStaticText* startupText;
|
Bind(wxEVT_SET_FOCUS, &wxTextCtrlWithPlaceholder::OnFocus, this);
|
||||||
wxCheckBox* autostartCheckbox;
|
Bind(wxEVT_KILL_FOCUS, &wxTextCtrlWithPlaceholder::OnBlur, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPlaceholderText(const wxString& p) {
|
||||||
|
placeholder = p;
|
||||||
|
SetValue(placeholder);
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnFocus(wxFocusEvent& event) {
|
||||||
|
if (GetValue() == placeholder)
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
showPlaceholder = false;
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnBlur(wxFocusEvent& event) {
|
||||||
|
if (GetValue().IsEmpty() || GetValue() == "") {
|
||||||
|
SetValue(placeholder);
|
||||||
|
showPlaceholder = true;
|
||||||
|
}
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxString placeholder;
|
||||||
|
bool showPlaceholder;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlayerLinkFrame : public wxFrame {
|
||||||
public:
|
public:
|
||||||
PlayerLinkFrame(wxWindow* parent, wxIcon& icon, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString,
|
PlayerLinkFrame(wxWindow* parent, wxIcon& icon, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString,
|
||||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(300, 200),
|
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(300, 200),
|
||||||
|
@ -184,20 +223,22 @@ public:
|
||||||
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
|
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
|
||||||
this->SetIcon(icon);
|
this->SetIcon(icon);
|
||||||
|
|
||||||
wxBoxSizer* mainContainer;
|
auto mainContainer = new wxBoxSizer(wxVERTICAL);
|
||||||
mainContainer = new wxBoxSizer(wxVERTICAL);
|
// header start
|
||||||
|
auto settingsText = new wxStaticText(this, wxID_ANY, _("Settings"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
settingsText = new wxStaticText(this, wxID_ANY, _("Settings"), wxDefaultPosition, wxDefaultSize, 0);
|
|
||||||
settingsText->Wrap(-1);
|
settingsText->Wrap(-1);
|
||||||
mainContainer->Add(settingsText, 0, wxALIGN_CENTER | wxALL, 5);
|
mainContainer->Add(settingsText, 0, wxALIGN_CENTER | wxALL, 5);
|
||||||
|
// header end
|
||||||
|
|
||||||
settingsDivider = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
|
// enabled apps start
|
||||||
|
auto settingsDivider = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
|
||||||
mainContainer->Add(settingsDivider, 0, wxEXPAND | wxALL, 5);
|
mainContainer->Add(settingsDivider, 0, wxEXPAND | wxALL, 5);
|
||||||
|
|
||||||
wxBoxSizer* enabledAppsContainer;
|
wxBoxSizer* enabledAppsContainer;
|
||||||
enabledAppsContainer = new wxBoxSizer(wxHORIZONTAL);
|
enabledAppsContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
enabledAppsText = new wxStaticText(this, wxID_ANY, _("Enabled Apps:"), wxDefaultPosition, wxDefaultSize, 0);
|
auto enabledAppsText =
|
||||||
|
new wxStaticText(this, wxID_ANY, _("Enabled Apps:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
enabledAppsText->Wrap(-1);
|
enabledAppsText->Wrap(-1);
|
||||||
enabledAppsContainer->Add(enabledAppsText, 0, wxALL, 5);
|
enabledAppsContainer->Add(enabledAppsText, 0, wxALL, 5);
|
||||||
|
|
||||||
|
@ -222,10 +263,10 @@ public:
|
||||||
appCheckboxContainer->Add(checkbox, 0, wxALL, 5);
|
appCheckboxContainer->Add(checkbox, 0, wxALL, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
anyOtherCheckbox = new wxCheckBox(this, wxID_ANY, _("Any other"), wxDefaultPosition, wxDefaultSize, 0);
|
auto anyOtherCheckbox = new wxCheckBox(this, wxID_ANY, _("Any other"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
anyOtherCheckbox->SetValue(settings.anyOtherEnabled);
|
anyOtherCheckbox->SetValue(settings.anyOtherEnabled);
|
||||||
anyOtherCheckbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) {
|
anyOtherCheckbox->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& event) {
|
||||||
bool isChecked = this->anyOtherCheckbox->IsChecked();
|
bool isChecked = anyOtherCheckbox->IsChecked();
|
||||||
auto settings = utils::getSettings();
|
auto settings = utils::getSettings();
|
||||||
settings.anyOtherEnabled = isChecked;
|
settings.anyOtherEnabled = isChecked;
|
||||||
utils::saveSettings(settings);
|
utils::saveSettings(settings);
|
||||||
|
@ -236,21 +277,102 @@ public:
|
||||||
enabledAppsContainer->Add(appCheckboxContainer, 1, wxEXPAND, 5);
|
enabledAppsContainer->Add(appCheckboxContainer, 1, wxEXPAND, 5);
|
||||||
|
|
||||||
mainContainer->Add(enabledAppsContainer, 0, 0, 5);
|
mainContainer->Add(enabledAppsContainer, 0, 0, 5);
|
||||||
|
// enabled apps end
|
||||||
|
|
||||||
appsDivider = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
|
// LastFM start
|
||||||
|
auto lastfmDivider = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
|
||||||
|
mainContainer->Add(lastfmDivider, 0, wxEXPAND | wxALL, 5);
|
||||||
|
|
||||||
|
wxBoxSizer* lastFMContainer;
|
||||||
|
lastFMContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
|
auto lastfmText = new wxStaticText(this, wxID_ANY, _("LastFM:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
lastfmText->Wrap(-1);
|
||||||
|
lastFMContainer->Add(lastfmText, 0, wxALL, 5);
|
||||||
|
|
||||||
|
wxBoxSizer* lastfmSettingsContainer;
|
||||||
|
lastfmSettingsContainer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
|
auto lastfmEnabledCheckbox = new wxCheckBox(this, wxID_ANY, _("Enabled"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
lastfmEnabledCheckbox->SetValue(settings.lastfm.enabled);
|
||||||
|
lastfmEnabledCheckbox->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& event) {
|
||||||
|
bool isChecked = lastfmEnabledCheckbox->IsChecked();
|
||||||
|
auto settings = utils::getSettings();
|
||||||
|
settings.lastfm.enabled = isChecked;
|
||||||
|
utils::saveSettings(settings);
|
||||||
|
});
|
||||||
|
lastfmSettingsContainer->Add(lastfmEnabledCheckbox, 0, wxALIGN_CENTER | wxALL, 5);
|
||||||
|
lastFMContainer->Add(lastfmSettingsContainer, 1, wxEXPAND, 5);
|
||||||
|
|
||||||
|
auto usernameInput =
|
||||||
|
new wxTextCtrlWithPlaceholder(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
usernameInput->SetPlaceholderText(_("Username"));
|
||||||
|
usernameInput->SetValue(settings.lastfm.username);
|
||||||
|
usernameInput->Bind(wxEVT_TEXT, [this](wxCommandEvent& event) {
|
||||||
|
auto settings = utils::getSettings();
|
||||||
|
std::string data = event.GetString().ToStdString();
|
||||||
|
settings.lastfm.username = data;
|
||||||
|
utils::saveSettings(settings);
|
||||||
|
});
|
||||||
|
auto passwordInput = new wxTextCtrlWithPlaceholder(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
||||||
|
wxDefaultSize, wxTE_PASSWORD);
|
||||||
|
passwordInput->SetPlaceholderText(_("Password"));
|
||||||
|
passwordInput->SetValue(settings.lastfm.password);
|
||||||
|
passwordInput->Bind(wxEVT_TEXT, [this](wxCommandEvent& event) {
|
||||||
|
auto settings = utils::getSettings();
|
||||||
|
std::string data = event.GetString().ToStdString();
|
||||||
|
settings.lastfm.password = data;
|
||||||
|
utils::saveSettings(settings);
|
||||||
|
});
|
||||||
|
auto apikeyInput =
|
||||||
|
new wxTextCtrlWithPlaceholder(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
apikeyInput->SetPlaceholderText(_("API-Key"));
|
||||||
|
apikeyInput->SetValue(settings.lastfm.api_key);
|
||||||
|
apikeyInput->Bind(wxEVT_TEXT, [this](wxCommandEvent& event) {
|
||||||
|
auto settings = utils::getSettings();
|
||||||
|
std::string data = event.GetString().ToStdString();
|
||||||
|
settings.lastfm.api_key = data;
|
||||||
|
utils::saveSettings(settings);
|
||||||
|
});
|
||||||
|
auto apisecretInput = new wxTextCtrlWithPlaceholder(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
||||||
|
wxDefaultSize, wxTE_PASSWORD);
|
||||||
|
apisecretInput->SetPlaceholderText(_("API-Secret"));
|
||||||
|
apisecretInput->SetValue(settings.lastfm.api_secret);
|
||||||
|
apisecretInput->Bind(wxEVT_TEXT, [this](wxCommandEvent& event) {
|
||||||
|
auto settings = utils::getSettings();
|
||||||
|
std::string data = event.GetString().ToStdString();
|
||||||
|
settings.lastfm.api_secret = data;
|
||||||
|
utils::saveSettings(settings);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto checkButton = new wxButton(this, wxID_ANY, _("Check credentials"));
|
||||||
|
checkButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { initLastFM(true); });
|
||||||
|
mainContainer->Add(lastFMContainer, 0, 0, 5);
|
||||||
|
|
||||||
|
mainContainer->Add(usernameInput, 0, wxEXPAND | wxALL, 5);
|
||||||
|
mainContainer->Add(passwordInput, 0, wxEXPAND | wxALL, 5);
|
||||||
|
mainContainer->Add(apikeyInput, 0, wxEXPAND | wxALL, 5);
|
||||||
|
mainContainer->Add(apisecretInput, 0, wxEXPAND | wxALL, 5);
|
||||||
|
mainContainer->Add(checkButton, 0, wxEXPAND | wxALL, 10);
|
||||||
|
|
||||||
|
// Last FM End
|
||||||
|
|
||||||
|
// settings start
|
||||||
|
auto appsDivider = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
|
||||||
mainContainer->Add(appsDivider, 0, wxEXPAND | wxALL, 5);
|
mainContainer->Add(appsDivider, 0, wxEXPAND | wxALL, 5);
|
||||||
|
|
||||||
wxBoxSizer* settingsContainer;
|
wxBoxSizer* settingsContainer;
|
||||||
settingsContainer = new wxBoxSizer(wxHORIZONTAL);
|
settingsContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
startupText = new wxStaticText(this, wxID_ANY, _("Startup:"), wxDefaultPosition, wxDefaultSize, 0);
|
auto startupText = new wxStaticText(this, wxID_ANY, _("Startup:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
startupText->Wrap(-1);
|
startupText->Wrap(-1);
|
||||||
settingsContainer->Add(startupText, 0, wxALL, 5);
|
settingsContainer->Add(startupText, 0, wxALL, 5);
|
||||||
|
|
||||||
autostartCheckbox = new wxCheckBox(this, wxID_ANY, _("Launch at login"), wxDefaultPosition, wxDefaultSize, 0);
|
auto autostartCheckbox =
|
||||||
|
new wxCheckBox(this, wxID_ANY, _("Launch at login"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
autostartCheckbox->SetValue(settings.autoStart);
|
autostartCheckbox->SetValue(settings.autoStart);
|
||||||
autostartCheckbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) {
|
autostartCheckbox->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& event) {
|
||||||
bool isChecked = this->autostartCheckbox->IsChecked();
|
bool isChecked = autostartCheckbox->IsChecked();
|
||||||
auto settings = utils::getSettings();
|
auto settings = utils::getSettings();
|
||||||
settings.autoStart = isChecked;
|
settings.autoStart = isChecked;
|
||||||
backend::toggleAutostart(isChecked);
|
backend::toggleAutostart(isChecked);
|
||||||
|
@ -259,7 +381,7 @@ public:
|
||||||
|
|
||||||
settingsContainer->Add(autostartCheckbox, 0, wxALL, 5);
|
settingsContainer->Add(autostartCheckbox, 0, wxALL, 5);
|
||||||
mainContainer->Add(settingsContainer, 0, wxEXPAND, 5);
|
mainContainer->Add(settingsContainer, 0, wxEXPAND, 5);
|
||||||
|
// settings end
|
||||||
this->SetSizerAndFit(mainContainer);
|
this->SetSizerAndFit(mainContainer);
|
||||||
|
|
||||||
wxSize currentSize = this->GetSize();
|
wxSize currentSize = this->GetSize();
|
||||||
|
|
|
@ -90,11 +90,14 @@ namespace utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string getURLEncodedPostBody(const std::map<std::string, std::string>& parameters) {
|
inline std::string getURLEncodedPostBody(const std::map<std::string, std::string>& parameters) {
|
||||||
|
if (parameters.empty())
|
||||||
|
return "";
|
||||||
|
|
||||||
std::string encodedPostBody = "";
|
std::string encodedPostBody = "";
|
||||||
for (const auto& parameter : parameters) {
|
for (const auto& parameter : parameters) {
|
||||||
encodedPostBody += parameter.first;
|
encodedPostBody += parameter.first;
|
||||||
encodedPostBody += "=";
|
encodedPostBody += "=";
|
||||||
encodedPostBody += parameter.second;
|
encodedPostBody += urlEncode(parameter.second);
|
||||||
encodedPostBody += "&";
|
encodedPostBody += "&";
|
||||||
}
|
}
|
||||||
return encodedPostBody.erase(encodedPostBody.length() - 1);
|
return encodedPostBody.erase(encodedPostBody.length() - 1);
|
||||||
|
|
Loading…
Reference in New Issue