#include "book_client.h" #include #include "boost/algorithm/string.hpp" #include "json/json.h" #include "book_json.h" BookClient::BookClient(const std::string& url, int timeout) : url_(url), session_(timeout) { // Default Content-Type for requests with a body. session_.SetContentType("application/json", "utf-8"); } bool BookClient::Query(std::list* books) { try { auto r = session_.Send(WEBCC_GET(url_).Path("books")()); if (!CheckStatus(r, webcc::Status::kOK)) { // Response HTTP status error. return false; } Json::Value json = StringToJson(r->data()); if (!json.isArray()) { return false; // Should be a JSON array of books. } for (Json::ArrayIndex i = 0; i < json.size(); ++i) { books->push_back(JsonToBook(json[i])); } return true; } catch (const webcc::Error& error) { std::cerr << error << std::endl; return false; } } bool BookClient::Create(const std::string& title, double price, std::string* id) { Json::Value req_json; req_json["title"] = title; req_json["price"] = price; try { auto r = session_.Send(WEBCC_POST(url_).Path("books"). Body(JsonToString(req_json))()); if (!CheckStatus(r, webcc::Status::kCreated)) { return false; } Json::Value rsp_json = StringToJson(r->data()); *id = rsp_json["id"].asString(); if (id->empty()) { return false; } return true; } catch (const webcc::Error& error) { std::cerr << error << std::endl; return false; } } bool BookClient::Get(const std::string& id, Book* book) { try { auto r = session_.Send(WEBCC_GET(url_).Path("books").Path(id)()); if (!CheckStatus(r, webcc::Status::kOK)) { return false; } return JsonStringToBook(r->data(), book); } catch (const webcc::Error& error) { std::cerr << error << std::endl; return false; } } bool BookClient::Set(const std::string& id, const std::string& title, double price) { Json::Value json; json["title"] = title; json["price"] = price; try { auto r = session_.Send(WEBCC_PUT(url_).Path("books").Path(id). Body(JsonToString(json))()); if (!CheckStatus(r, webcc::Status::kOK)) { return false; } return true; } catch (const webcc::Error& error) { std::cerr << error << std::endl; return false; } } bool BookClient::Delete(const std::string& id) { try { auto r = session_.Send(WEBCC_DELETE(url_).Path("books").Path(id)()); if (!CheckStatus(r, webcc::Status::kOK)) { return false; } return true; } catch (const webcc::Error& error) { std::cerr << error << std::endl; return false; } } bool BookClient::GetPhoto(const std::string& id, const webcc::fs::path& path) { try { auto r = session_.Send(WEBCC_GET(url_). Path("books").Path(id).Path("photo")(), true); // Save to temp file if (!CheckStatus(r, webcc::Status::kOK)) { return false; } r->file_body()->Move(path); return true; } catch (const webcc::Error& error) { std::cerr << error << std::endl; return false; } } bool BookClient::SetPhoto(const std::string& id, const webcc::fs::path& path) { try { if (!CheckPhoto(path)) { return false; } auto r = session_.Send(WEBCC_PUT(url_). Path("books").Path(id).Path("photo"). File(path)()); if (!CheckStatus(r, webcc::Status::kOK)) { return false; } return true; } catch (const webcc::Error& error) { std::cerr << error << std::endl; return false; } } bool BookClient::CheckPhoto(const webcc::fs::path& photo) { if (photo.empty()) { return false; } if (!webcc::fs::is_regular_file(photo) || !webcc::fs::exists(photo)) { return false; } auto ext = photo.extension().string(); if (!boost::iequals(ext, ".jpg") && !boost::iequals(ext, ".jpeg")) { return false; } return true; } bool BookClient::CheckStatus(webcc::ResponsePtr response, int expected_status) { if (response->status() != expected_status) { std::cerr << "HTTP status error (actual: " << response->status() << "expected: " << expected_status << ")." << std::endl; return false; } return true; }