3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "convert_json.h"
29 #include "httpfetch.h"
32 Json::Value fetchJsonValue(const std::string &url,
33 std::vector<std::string> *extra_headers)
35 HTTPFetchRequest fetch_request;
36 HTTPFetchResult fetch_result;
37 fetch_request.url = url;
38 fetch_request.caller = HTTPFETCH_SYNC;
40 if (extra_headers != NULL)
41 fetch_request.extra_headers = *extra_headers;
43 httpfetch_sync(fetch_request, fetch_result);
45 if (!fetch_result.succeeded) {
50 std::istringstream stream(fetch_result.data);
52 if (!reader.parse(stream, root)) {
53 errorstream << "URL: " << url << std::endl;
54 errorstream << "Failed to parse json data " << reader.getFormattedErrorMessages();
55 if (fetch_result.data.size() > 100) {
56 errorstream << "Data (" << fetch_result.data.size()
57 << " bytes) printed to warningstream." << std::endl;
58 warningstream << "data: \"" << fetch_result.data << "\"" << std::endl;
60 errorstream << "data: \"" << fetch_result.data << "\"" << std::endl;
68 std::vector<ModStoreMod> readModStoreList(Json::Value& modlist) {
69 std::vector<ModStoreMod> retval;
71 if (modlist.isArray()) {
72 for (unsigned int i = 0; i < modlist.size(); i++)
78 if (modlist[i]["id"].asString().size()) {
79 std::string id_raw = modlist[i]["id"].asString();
81 int numbervalue = strtol(id_raw.c_str(),&endptr,10);
83 if ((id_raw != "") && (*endptr == 0)) {
84 toadd.id = numbervalue;
87 errorstream << "readModStoreList: missing id" << std::endl;
92 errorstream << "readModStoreList: missing id" << std::endl;
97 if (modlist[i]["title"].asString().size()) {
98 toadd.title = modlist[i]["title"].asString();
101 errorstream << "readModStoreList: missing title" << std::endl;
106 if (modlist[i]["basename"].asString().size()) {
107 toadd.basename = modlist[i]["basename"].asString();
110 errorstream << "readModStoreList: missing basename" << std::endl;
121 retval.push_back(toadd);
128 ModStoreModDetails readModStoreModDetails(Json::Value& details) {
130 ModStoreModDetails retval;
135 if (details["version_set"].isArray()) {
136 for (unsigned int i = 0; i < details["version_set"].size(); i++)
138 ModStoreVersionEntry toadd;
140 if (details["version_set"][i]["id"].asString().size()) {
141 std::string id_raw = details["version_set"][i]["id"].asString();
143 int numbervalue = strtol(id_raw.c_str(),&endptr,10);
145 if ((id_raw != "") && (*endptr == 0)) {
146 toadd.id = numbervalue;
150 errorstream << "readModStoreModDetails: missing version_set id" << std::endl;
151 retval.valid = false;
155 if (details["version_set"][i]["date"].asString().size()) {
156 toadd.date = details["version_set"][i]["date"].asString();
160 if (details["version_set"][i]["file"].asString().size()) {
161 toadd.file = details["version_set"][i]["file"].asString();
164 errorstream << "readModStoreModDetails: missing version_set file" << std::endl;
165 retval.valid = false;
173 retval.versions.push_back(toadd);
181 if (retval.versions.size() < 1) {
182 infostream << "readModStoreModDetails: not a single version specified!" << std::endl;
183 retval.valid = false;
187 if (details["categories"].isObject()) {
188 for (unsigned int i = 0; i < details["categories"].size(); i++) {
189 ModStoreCategoryInfo toadd;
191 if (details["categories"][i]["id"].asString().size()) {
193 std::string id_raw = details["categories"][i]["id"].asString();
195 int numbervalue = strtol(id_raw.c_str(),&endptr,10);
197 if ((id_raw != "") && (*endptr == 0)) {
198 toadd.id = numbervalue;
202 errorstream << "readModStoreModDetails: missing categories id" << std::endl;
203 retval.valid = false;
205 if (details["categories"][i]["title"].asString().size()) {
206 toadd.name = details["categories"][i]["title"].asString();
209 errorstream << "readModStoreModDetails: missing categories title" << std::endl;
210 retval.valid = false;
214 retval.categories.push_back(toadd);
223 if (details["author"].isObject()) {
224 if (details["author"]["id"].asString().size()) {
226 std::string id_raw = details["author"]["id"].asString();
228 int numbervalue = strtol(id_raw.c_str(),&endptr,10);
230 if ((id_raw != "") && (*endptr == 0)) {
231 retval.author.id = numbervalue;
234 errorstream << "readModStoreModDetails: missing author id (convert)" << std::endl;
235 retval.valid = false;
239 errorstream << "readModStoreModDetails: missing author id" << std::endl;
240 retval.valid = false;
243 if (details["author"]["username"].asString().size()) {
244 retval.author.username = details["author"]["username"].asString();
247 errorstream << "readModStoreModDetails: missing author username" << std::endl;
248 retval.valid = false;
252 errorstream << "readModStoreModDetails: missing author" << std::endl;
253 retval.valid = false;
257 if (details["license"].isObject()) {
258 if (details["license"]["id"].asString().size()) {
260 std::string id_raw = details["license"]["id"].asString();
262 int numbervalue = strtol(id_raw.c_str(),&endptr,10);
264 if ((id_raw != "") && (*endptr == 0)) {
265 retval.license.id = numbervalue;
269 errorstream << "readModStoreModDetails: missing license id" << std::endl;
270 retval.valid = false;
273 if (details["license"]["short"].asString().size()) {
274 retval.license.shortinfo = details["license"]["short"].asString();
277 errorstream << "readModStoreModDetails: missing license short" << std::endl;
278 retval.valid = false;
281 if (details["license"]["link"].asString().size()) {
282 retval.license.url = details["license"]["link"].asString();
288 if (details["titlepic"].isObject()) {
289 if (details["titlepic"]["id"].asString().size()) {
291 std::string id_raw = details["titlepic"]["id"].asString();
293 int numbervalue = strtol(id_raw.c_str(),&endptr,10);
295 if ((id_raw != "") && (*endptr == 0)) {
296 retval.titlepic.id = numbervalue;
300 if (details["titlepic"]["file"].asString().size()) {
301 retval.titlepic.file = details["titlepic"]["file"].asString();
304 if (details["titlepic"]["desc"].asString().size()) {
305 retval.titlepic.description = details["titlepic"]["desc"].asString();
308 if (details["titlepic"]["mod"].asString().size()) {
310 std::string mod_raw = details["titlepic"]["mod"].asString();
312 int numbervalue = strtol(mod_raw.c_str(),&endptr,10);
314 if ((mod_raw != "") && (*endptr == 0)) {
315 retval.titlepic.mod = numbervalue;
321 if (details["id"].asString().size()) {
323 std::string id_raw = details["id"].asString();
325 int numbervalue = strtol(id_raw.c_str(),&endptr,10);
327 if ((id_raw != "") && (*endptr == 0)) {
328 retval.id = numbervalue;
332 errorstream << "readModStoreModDetails: missing id" << std::endl;
333 retval.valid = false;
337 if (details["title"].asString().size()) {
338 retval.title = details["title"].asString();
341 errorstream << "readModStoreModDetails: missing title" << std::endl;
342 retval.valid = false;
346 if (details["basename"].asString().size()) {
347 retval.basename = details["basename"].asString();
350 errorstream << "readModStoreModDetails: missing basename" << std::endl;
351 retval.valid = false;
355 if (details["desc"].asString().size()) {
356 retval.description = details["desc"].asString();
360 if (details["replink"].asString().size()) {
361 retval.repository = details["replink"].asString();
365 if (details["value"].isInt()) {
366 retval.rating = details["value"].asInt();
372 if (details["depends"].isArray()) {
377 if (details["softdep"].isArray()) {
382 if (details["screenshot_url"].asString().size()) {
383 retval.screenshot_url = details["screenshot_url"].asString();