Skip to content

Commit ec50f11

Browse files
committed
re-organize the source code
1 parent bed7a41 commit ec50f11

File tree

6 files changed

+253
-0
lines changed

6 files changed

+253
-0
lines changed

oobt/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
all: build run
2+
3+
build:
4+
5+
run:

oobt/main.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <cstdint>
2+
#include <iostream>
3+
#include <memory>
4+
#include <string>
5+
#include <curl/curl.h>
6+
#include <serpapi.hpp>
7+
8+
#include "rapidjson/document.h"
9+
#include "rapidjson/writer.h"
10+
#include "rapidjson/stringbuffer.h"
11+
#include "rapidjson/prettywriter.h"
12+
#include "rapidjson/pointer.h"
13+
14+
using namespace rapidjson;
15+
using namespace std;
16+
17+
void info(string msg) {
18+
cout << "\nINFO: " << msg << endl;
19+
}
20+
void info(double msg) {
21+
cout << "\nINFO: " << msg << endl;
22+
}
23+
24+
void info(const Document& document) {
25+
StringBuffer buffer;
26+
PrettyWriter<StringBuffer> writer(buffer);
27+
document.Accept(writer);
28+
cout << "\nINFO: " << buffer.GetString();
29+
}
30+
31+
// RapidJSON parser documentation is available: https://rapidjson.org
32+
int main()
33+
{
34+
// initialize a client
35+
const char* env_p = std::getenv("API_KEY");
36+
std::string apiKey(env_p);
37+
std::map<string, string> default_parameter;
38+
default_parameter["api_key"] = apiKey;
39+
default_parameter["engine"] = "google";
40+
41+
// using namespace serpapi;
42+
serpapi::Client client(default_parameter);
43+
44+
// execute search
45+
std::map<string, string> parameter;
46+
parameter["q"] = "coffee";
47+
parameter["location"] = "Austin,TX";
48+
// using namespace rapidjson;
49+
rapidjson::Document d = client.search(parameter);
50+
info("document loaded");
51+
assert(d.HasMember("search_metadata"));
52+
assert(d["search_metadata"]["status"] == "Success");
53+
assert(d["search_metadata"]["id"].IsString());
54+
55+
string id = d["search_metadata"]["id"].GetString();
56+
client.searchArchive(id);
57+
assert(d["search_metadata"]["status"] == "Success");
58+
info(d);
59+
}

src/callback.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <cstdint>
2+
#include <iostream>
3+
#include <memory>
4+
#include <string>
5+
6+
using namespace std;
7+
8+
namespace serpapi
9+
{
10+
size_t callback(const char* in, size_t size, size_t num, string* out)
11+
{
12+
const size_t totalBytes(size*num);
13+
out->append(in, totalBytes);
14+
return totalBytes;
15+
}
16+
}

src/callback.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <cstdint>
2+
#include <iostream>
3+
#include <memory>
4+
#include <string>
5+
6+
using namespace std;
7+
8+
namespace serpapi
9+
{
10+
size_t callback(const char* in, size_t size, size_t num, string* out);
11+
}

src/serpapi.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/***
2+
* Run search engine powered by SerpApi
3+
*/
4+
5+
#include <serpapi.hpp>
6+
7+
namespace serpapi
8+
{
9+
10+
const static string JSON_FORMAT = "json";
11+
const static string HTML_FORMAT = "html";
12+
const static string HOST = "https://serpapi.com";
13+
14+
using namespace rapidjson;
15+
using namespace std;
16+
17+
Client::Client(map<string, string> parameter)
18+
{
19+
this->parameter = parameter;
20+
}
21+
22+
/***
23+
* Get HTML search results
24+
*/
25+
string Client::html(map<string, string> parameter)
26+
{
27+
return Client::get("/search", HTML_FORMAT, parameter);
28+
}
29+
30+
Document Client::search(map<string, string> parameter)
31+
{
32+
return Client::json("/search", parameter);
33+
}
34+
35+
Document Client::searchArchive(string searchID)
36+
{
37+
return Client::json("/searches/" + searchID + ".json", map<string, string>());
38+
}
39+
40+
Document Client::account(map<string, string> parameter)
41+
{
42+
return Client::json("/account.json", parameter);
43+
}
44+
45+
Document Client::location(map<string, string> parameter)
46+
{
47+
return Client::json("/locations.json", parameter);
48+
}
49+
50+
Document Client::json(string uri, map<string, string> parameter)
51+
{
52+
string buf = get(uri, JSON_FORMAT, parameter);
53+
const char* json = buf.c_str();
54+
Document d;
55+
d.Parse(json);
56+
return d;
57+
}
58+
59+
string Client::url(string output, map<string, string> parameter)
60+
{
61+
map<string, string> param(parameter);
62+
string s = "";
63+
map<string,string>::iterator it;
64+
for (it = param.begin(); it != param.end(); ++it)
65+
{
66+
if (s != "")
67+
{
68+
s += "&";
69+
}
70+
// encode each value in case of special character
71+
s += it->first + "=" + it->second;
72+
}
73+
74+
// append output format
75+
s += "&output=" + output;
76+
77+
// append source language
78+
s += "&source=serpapi-cpp:1.0.0";
79+
80+
return s;
81+
}
82+
83+
string Client::get(string uri, string output, map<string, string> parameter)
84+
{
85+
curl_global_init(CURL_GLOBAL_DEFAULT);
86+
curl = curl_easy_init();
87+
const string url = HOST + uri + "?" + this->url(output, parameter);
88+
cout << "url: " + url << endl;
89+
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
90+
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
91+
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
92+
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
93+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
94+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
95+
96+
long httpCode(0);
97+
unique_ptr<string> httpData(new string());
98+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
99+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
100+
101+
// execute search
102+
curl_easy_perform(curl);
103+
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
104+
curl_easy_cleanup(curl);
105+
106+
if(httpCode != 200) {
107+
// TODO what is the best solution in C++
108+
return nullptr;
109+
}
110+
curl_global_cleanup();
111+
return *httpData.get();
112+
}
113+
114+
}
115+

src/serpapi.hpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/***
2+
* Run search engine powered by SerpApi
3+
*/
4+
#ifndef SERPAPI
5+
#define SERPAPI
6+
7+
#include <iostream>
8+
#include <map>
9+
#include <string>
10+
#include <curl/curl.h>
11+
#include <callback.hpp>
12+
#include "rapidjson/document.h"
13+
14+
namespace serpapi
15+
{
16+
using namespace rapidjson;
17+
using namespace std;
18+
19+
class Client {
20+
21+
map<string, string> parameter;
22+
CURL *curl;
23+
int timeout = 60;
24+
25+
public:
26+
27+
Client(map<string, string> parameter);
28+
29+
Document search(map<string, string> parameter);
30+
31+
string html(map<string, string> parameter);
32+
33+
Document searchArchive(string searchID);
34+
35+
Document account(map<string, string> parameter);
36+
37+
Document location(map<string, string> parameter);
38+
39+
Document json(string uri, map<string, string> parameter);
40+
41+
string url(string output, map<string, string> parameter);
42+
43+
string get(string uri, string output, map<string, string> parameter);
44+
};
45+
}
46+
47+
#endif

0 commit comments

Comments
 (0)