Skip to content

Instantly share code, notes, and snippets.

@makomweb
Last active December 23, 2015 22:59
Show Gist options
  • Save makomweb/6707000 to your computer and use it in GitHub Desktop.
Save makomweb/6707000 to your computer and use it in GitHub Desktop.
Perform a login to Wunderlist's Wunder API using pure C++, parallel patterns library, boost 1.54 and Casablanca C++ REST library
#include <cpprest/json.h>
#include <sstream>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
#include <map>
using namespace std;
using namespace web::http;
using namespace web::http::client;
typedef web::json::value JsonValue;
typedef web::json::value::value_type JsonValueType;
typedef std::wstring String;
typedef std::wstringstream StringStream;
class Credentials
{
public:
Credentials(const String& email, const String& password)
: Email(email), Password(password) {}
String Email;
String Password;
JsonValue AsJson() const
{
JsonValue json;
json[L"email"] = JsonValue::string(Email);
json[L"password"] = JsonValue::string(Password);
return json;
}
};
class WunderUser
{
public:
String Id;
String Name;
String Token;
String AvatarAddress;
void Display() const
{
wcout << L"Id: " << Id << endl;
wcout << L"Name: " << Name << endl;
wcout << L"Token: " << Token << endl;
wcout << L"AvatarAddress: " << AvatarAddress << endl;
}
};
class WunderUserFactory
{
enum FieldId { Id, Name, Token, AvatarAddress };
map<String, FieldId> fieldMap_;
WunderUser user_;
void SetField(const String& name, const JsonValue& value)
{
auto pair = fieldMap_.find(name);
if (pair != fieldMap_.end())
{
switch (pair->second)
{
case FieldId::Id: user_.Id = value.as_string(); break;
case FieldId::Name: user_.Name = value.as_string(); break;
case FieldId::Token: user_.Token = value.as_string(); break;
case FieldId::AvatarAddress: user_.AvatarAddress = value.as_string(); break;
default: break;
}
}
}
public:
WunderUserFactory()
{
fieldMap_[L"id"] = FieldId::Id;
fieldMap_[L"name"] = FieldId::Name;
fieldMap_[L"token"] = FieldId::Token;
fieldMap_[L"avatar"] = FieldId::AvatarAddress;
}
WunderUser FromJson(const JsonValue& jsonValue)
{
for (auto it = jsonValue.cbegin(); it != jsonValue.cend(); ++it)
{
auto propertyName = it->first;
auto propertyValue = it->second;
SetField(propertyName.as_string(), propertyValue);
}
return user_;
}
};
String JsonValueTypeToString(const JsonValueType& type)
{
switch (type)
{
case JsonValueType::Array: return L"Array";
case JsonValueType::Boolean: return L"Boolean";
case JsonValueType::Null: return L"Null";
case JsonValueType::Number: return L"Number";
case JsonValueType::Object: return L"Object";
case JsonValueType::String: return L"String";
default: throw std::exception("unknown type");
}
}
void Externalize(const JsonValue& json)
{
for (auto iter = json.cbegin(); iter != json.cend(); ++iter)
{
auto k = iter->first;
auto v = iter->second;
auto key = k.as_string();
auto value = v.to_string();
wcout << key << L" : " << value << " (" << JsonValueTypeToString(v.type()) << ")" << endl;
}
}
pplx::task<void> LoginAsync(const String& loginAddress, const Credentials& credentials)
{
return pplx::create_task([loginAddress, credentials]
{
http_client client(loginAddress);
return client.request(methods::POST, L"", credentials.AsJson());
})
.then([](http_response response)
{
if (response.status_code() == status_codes::OK)
{
auto json = response.extract_json().get();
if (json.is_null())
return;
//Externalize(json); // <-- only for debugging!
auto user = WunderUserFactory().FromJson(json);
user.Display();
}
});
}
int main()
{
LoginAsync(L"http://api.wunderlist.com/login", Credentials(L"<enter-email-address>", L"<enter-password>")).wait();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment