Checkpoint commit for LastFm integration -- URL signing and working

`auth.getToken` call.
This commit is contained in:
casey langen 2018-04-29 23:01:29 -07:00
parent a4c0056a07
commit e4a92dae4d
5 changed files with 176 additions and 15 deletions

View File

@ -62,17 +62,10 @@ namespace musik { namespace core { namespace io {
HttpClient<T>& Decorator(DecoratorCallback decoratorCb);
HttpClient<T>& Canceled(CanceledCallback canceledCb);
const T& Stream() {
return this->ostream;
}
const HttpHeaders& ResponseHeaders() {
return this->responseHeaders;
}
const HttpHeaders& RequestHeaders() {
return this->requestHeaders;
}
const T& Stream() const { return this->ostream; }
const HttpHeaders& ResponseHeaders() const { return this->responseHeaders; }
const HttpHeaders& RequestHeaders() const { return this->requestHeaders; }
const std::string& Url() const { return this->url; }
HttpClient<T>& Run(Callback callback = Callback());
void Wait();
@ -190,6 +183,7 @@ namespace musik { namespace core { namespace io {
}
this->curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
@ -204,6 +198,11 @@ namespace musik { namespace core { namespace io {
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3000);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 7500);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 500);
if (this->decoratorCb) {
this->decoratorCb(this->curl);
}
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlWriteCallback);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this);
@ -211,10 +210,6 @@ namespace musik { namespace core { namespace io {
curl_easy_setopt(curl, CURLOPT_HEADERDATA, this);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &CurlHeaderCallback);
if (this->decoratorCb) {
this->decoratorCb(this->curl);
}
if (this->requestHeaders.size()) {
struct curl_slist* slist = nullptr;
for (auto it : this->requestHeaders) {

View File

@ -0,0 +1,117 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2017 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include "stdafx.h"
#include "LastFm.h"
#include <curl/curl.h>
#include <openssl/md5.h>
#include <core/io/HttpClient.h>
#include <json.hpp>
#include <sstream>
#include <map>
/* http://www.last.fm/group/Last.fm+Web+Services/forum/21604/_/522900 -- it's ok to
put our key in the code */
static const std::string API_KEY = "502c69bd3f9946e8e0beee4fcb28c4cd";
static const std::string URL_BASE = "http://ws.audioscrobbler.com/2.0/";
static const std::string GET_TOKEN = "auth.gettoken";
static const std::string ACCOUNT_LINK_URL_BASE = "http://www.last.fm/api/auth/?api_key=" + API_KEY + "&token=";
using LastFmClient = musik::core::io::HttpClient<std::stringstream>;
static std::unique_ptr<LastFmClient> createClient() {
return LastFmClient::Create(std::stringstream());
}
static std::string generateSignedUrl(
const std::string& method,
std::map<std::string, std::string>&& params = { })
{
params["format"] = "json";
params["method"] = method;
params["api_key"] = API_KEY;
std::string toHash;
std::string url = URL_BASE;
bool first = true;
for (auto it : params) {
toHash += it.first + it.second;
url += (first ? "?" : "&") + it.first + "=" + it.second;
first = false;
}
/* compute the sum */
unsigned char rawDigest[MD5_DIGEST_LENGTH];
MD5((const unsigned char*)toHash.c_str(), toHash.length(), rawDigest);
/* convert to hex */
char hexDigest[33];
for (size_t i = 0; i < 16; i++) {
snprintf(&(hexDigest[i * 2]), 16 * 2, "%02x", (unsigned int)rawDigest[i]);
}
hexDigest[32] = 0;
url += "&api_sig=" + std::string(hexDigest);
return url;
}
namespace musik { namespace cube { namespace lastfm {
const std::string InitiateLink() {
std::string url = generateSignedUrl(GET_TOKEN);
std::string token;
auto client = createClient();
client->Url(url)
.Run([&token](LastFmClient* client, int statusCode, CURLcode curlCode) {
if (statusCode == 200) {
try {
auto json = nlohmann::json::parse(client->Stream().str());
token = json.value("token", "");
}
catch (...) {
/* not much we can do... */
}
}
})
.Wait();
return token.size() ? (ACCOUNT_LINK_URL_BASE + token) : "";
}
} } }

View File

@ -0,0 +1,41 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2017 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include "stdafx.h"
namespace musik { namespace cube { namespace lastfm {
extern const std::string InitiateLink();
} } }

View File

@ -165,6 +165,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\font\*.ttf" "$(TargetDir)fonts\" /Y
<ClCompile Include="app\overlay\VisualizerOverlay.cpp" />
<ClCompile Include="app\util\GlobalHotkeys.cpp" />
<ClCompile Include="app\util\Hotkeys.cpp" />
<ClCompile Include="app\util\LastFm.cpp" />
<ClCompile Include="app\util\Playback.cpp" />
<ClCompile Include="app\util\PreferenceKeys.cpp" />
<ClCompile Include="app\util\UpdateCheck.cpp" />
@ -224,6 +225,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\font\*.ttf" "$(TargetDir)fonts\" /Y
<ClInclude Include="app\overlay\VisualizerOverlay.h" />
<ClInclude Include="app\util\GlobalHotkeys.h" />
<ClInclude Include="app\util\Hotkeys.h" />
<ClInclude Include="app\util\LastFm.h" />
<ClInclude Include="app\util\Messages.h" />
<ClInclude Include="app\util\Playback.h" />
<ClInclude Include="app\util\PreferenceKeys.h" />

View File

@ -156,6 +156,9 @@
<ClCompile Include="app\layout\CategorySearchLayout.cpp">
<Filter>app\layout</Filter>
</ClCompile>
<ClCompile Include="app\util\LastFm.cpp">
<Filter>app\util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
@ -361,6 +364,9 @@
<ClInclude Include="app\layout\CategorySearchLayout.h">
<Filter>app\layout</Filter>
</ClInclude>
<ClInclude Include="app\util\LastFm.h">
<Filter>app\util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="cursespp">