comparison src/services/kitsu.cc @ 334:948955c3ba81

services: use fmt for setting the status bar this should make localization easier
author Paper <paper@paper.us.eu.org>
date Mon, 17 Jun 2024 20:35:31 -0400
parents b5d6c27c308f
children 5098387a3a46
comparison
equal deleted inserted replaced
333:5980a960f3e1 334:948955c3ba81
20 20
21 #include <chrono> 21 #include <chrono>
22 #include <exception> 22 #include <exception>
23 #include <string_view> 23 #include <string_view>
24 24
25 #include <fmt/core.h>
26
25 #include <iostream> 27 #include <iostream>
26 28
27 using namespace nlohmann::literals::json_literals; 29 using namespace nlohmann::literals::json_literals;
28 30
29 static constexpr std::string_view CLIENT_ID = "dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd"; 31 static constexpr std::string_view CLIENT_ID = "dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd";
41 {"Content-Type: application/json"} 43 {"Content-Type: application/json"}
42 }; 44 };
43 45
44 const std::string ret = Strings::ToUtf8String(HTTP::Request(std::string(OAUTH_PATH), headers, data.dump(), HTTP::Type::Post)); 46 const std::string ret = Strings::ToUtf8String(HTTP::Request(std::string(OAUTH_PATH), headers, data.dump(), HTTP::Type::Post));
45 if (ret.empty()) { 47 if (ret.empty()) {
46 session.SetStatusBar("Kitsu: Request returned empty data!"); 48 session.SetStatusBar(Strings::Translate("Kitsu: Request returned empty data!"));
47 return false; 49 return false;
48 } 50 }
49 51
50 nlohmann::json result; 52 nlohmann::json result;
51 try { 53 try {
52 result = nlohmann::json::parse(ret, nullptr, false); 54 result = nlohmann::json::parse(ret, nullptr, false);
53 } catch (const std::exception& ex) { 55 } catch (const std::exception& ex) {
54 session.SetStatusBar(std::string("Kitsu: Failed to parse authorization data with error \"") + ex.what() + "\"!"); 56 session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to parse authorization data with error \"{}\""), ex.what()));
55 return false; 57 return false;
56 } 58 }
57 59
58 if (result.contains("/error"_json_pointer)) { 60 if (result.contains("/error"_json_pointer)) {
59 std::string status = "Kitsu: Failed with error \""; 61 session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed with error \"{}\"!"), result["/error"_json_pointer].get<std::string>()));
60 status += result["/error"_json_pointer].get<std::string>();
61
62 if (result.contains("/error_description"_json_pointer)) {
63 status += "\" and description \"";
64 status += result["/error_description"_json_pointer].get<std::string>();
65 }
66
67 status += "\"!";
68
69 session.SetStatusBar(status);
70 return false; 62 return false;
71 } 63 }
72 64
73 const std::vector<nlohmann::json::json_pointer> required = { 65 const std::vector<nlohmann::json::json_pointer> required = {
74 "/access_token"_json_pointer, 66 "/access_token"_json_pointer,
79 "/token_type"_json_pointer 71 "/token_type"_json_pointer
80 }; 72 };
81 73
82 for (const auto& ptr : required) { 74 for (const auto& ptr : required) {
83 if (!result.contains(ptr)) { 75 if (!result.contains(ptr)) {
84 session.SetStatusBar("Kitsu: Authorization request returned bad data!"); 76 session.SetStatusBar(Strings::Translate("Kitsu: Authorization request returned bad data!"));
85 return false; 77 return false;
86 } 78 }
87 } 79 }
88 80
89 session.config.auth.kitsu.access_token = result["/access_token"_json_pointer].get<std::string>(); 81 session.config.auth.kitsu.access_token = result["/access_token"_json_pointer].get<std::string>();
185 177
186 nlohmann::json json; 178 nlohmann::json json;
187 try { 179 try {
188 json = nlohmann::json::parse(response); 180 json = nlohmann::json::parse(response);
189 } catch (const std::exception& ex) { 181 } catch (const std::exception& ex) {
190 session.SetStatusBar(std::string("Kitsu: Failed to parse response with error \"") + ex.what() + "\"!"); 182 session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to parse response with error \"{}\""), ex.what()));
191 return std::nullopt; 183 return std::nullopt;
192 } 184 }
193 185
194 if (json.contains("/errors"_json_pointer)) { 186 if (json.contains("/errors"_json_pointer)) {
195 for (const auto& item : json["/errors"]) 187 for (const auto& item : json["/errors"])
196 std::cerr << "Kitsu: API returned error \"" << json["/errors/title"_json_pointer] << "\" with detail \"" << json["/errors/detail"] << std::endl; 188 std::cerr << "Kitsu: API returned error \"" << json["/errors/title"_json_pointer] << "\" with detail \"" << json["/errors/detail"] << std::endl;
197 189
198 session.SetStatusBar("Kitsu: Request failed with errors!"); 190 session.SetStatusBar(Strings::Translate("Kitsu: Request failed with errors!"));
199 return std::nullopt; 191 return std::nullopt;
200 } 192 }
201 193
202 return json; 194 return json;
203 } 195 }
259 251
260 anime.SetAiringStatus(lookup.at(str)); 252 anime.SetAiringStatus(lookup.at(str));
261 } 253 }
262 254
263 static int ParseAnimeJson(const nlohmann::json& json) { 255 static int ParseAnimeJson(const nlohmann::json& json) {
264 static const std::string FAILED_TO_PARSE = "Kitsu: Failed to parse anime object!"; 256 const std::string FAILED_TO_PARSE = Strings::Translate("Kitsu: Failed to parse anime object! {}");
265 257
266 const std::string service_id = json["/id"_json_pointer].get<std::string>(); 258 const std::string service_id = json["/id"_json_pointer].get<std::string>();
267 if (service_id.empty()) { 259 if (service_id.empty()) {
268 session.SetStatusBar(FAILED_TO_PARSE + " (/id)"); 260 session.SetStatusBar(fmt::format(FAILED_TO_PARSE, "(/id)"));
269 return 0; 261 return 0;
270 } 262 }
271 263
272 if (!json.contains("/attributes"_json_pointer)) { 264 if (!json.contains("/attributes"_json_pointer)) {
273 session.SetStatusBar(FAILED_TO_PARSE + " (/attributes)"); 265 session.SetStatusBar(fmt::format(FAILED_TO_PARSE, "(/attributes)"));
274 return 0; 266 return 0;
275 } 267 }
276 268
277 const auto& attributes = json["/attributes"_json_pointer]; 269 const auto& attributes = json["/attributes"_json_pointer];
278 270
328 "/attributes"_json_pointer, 320 "/attributes"_json_pointer,
329 }; 321 };
330 322
331 for (const auto& ptr : required) { 323 for (const auto& ptr : required) {
332 if (!json.contains(ptr)) { 324 if (!json.contains(ptr)) {
333 session.SetStatusBar(std::string("Kitsu: Failed to parse library object! (missing ") + ptr.to_string() + ")"); 325 session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to parse library object! (missing {})"), ptr.to_string()));
334 return 0; 326 return 0;
335 } 327 }
336 } 328 }
337 329
338 std::string service_id = json["/relationships/anime/data/id"_json_pointer].get<std::string>(); 330 std::string service_id = json["/relationships/anime/data/id"_json_pointer].get<std::string>();
339 if (service_id.empty()) { 331 if (service_id.empty()) {
340 session.SetStatusBar("Kitsu: Failed to parse library object!"); 332 session.SetStatusBar(Strings::Translate("Kitsu: Failed to parse library object (missing service ID)!"));
341 return 0; 333 return 0;
342 } 334 }
343 335
344 int id = Anime::db.LookupServiceIdOrUnused(Anime::Service::Kitsu, service_id); 336 int id = Anime::db.LookupServiceIdOrUnused(Anime::Service::Kitsu, service_id);
345 337
427 } 419 }
428 420
429 static bool ParseAnyJson(const nlohmann::json& json) { 421 static bool ParseAnyJson(const nlohmann::json& json) {
430 static const nlohmann::json::json_pointer required = "/type"_json_pointer; 422 static const nlohmann::json::json_pointer required = "/type"_json_pointer;
431 if (!json.contains(required) && !json[required].is_string()) { 423 if (!json.contains(required) && !json[required].is_string()) {
432 session.SetStatusBar(std::string("Kitsu: Failed to parse generic object! (missing ") + required.to_string() + ")"); 424 session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to generic object! (missing {})"), required.to_string()));
433 return 0; 425 return 0;
434 } 426 }
435 427
436 std::string variant = json["/type"_json_pointer].get<std::string>(); 428 std::string variant = json["/type"_json_pointer].get<std::string>();
437 429
452 static constexpr int LIBRARY_MAX_SIZE = 500; 444 static constexpr int LIBRARY_MAX_SIZE = 500;
453 445
454 const auto& auth = session.config.auth.kitsu; 446 const auto& auth = session.config.auth.kitsu;
455 447
456 if (auth.user_id.empty()) { 448 if (auth.user_id.empty()) {
457 session.SetStatusBar("Kitsu: User ID is unavailable!"); 449 session.SetStatusBar(Strings::Translate("Kitsu: User ID is unavailable!"));
458 return 0; 450 return 0;
459 } 451 }
460 452
461 int page = 0; 453 int page = 0;
462 bool have_next_page = true; 454 bool have_next_page = true;
498 490
499 params["page[offset]"] = Strings::ToUtf8String(page); 491 params["page[offset]"] = Strings::ToUtf8String(page);
500 } 492 }
501 493
502 if (success) 494 if (success)
503 session.SetStatusBar("Kitsu: Successfully received library data!"); 495 session.SetStatusBar(Strings::Translate("Kitsu: Successfully received library data!"));
504 496
505 return 1; 497 return 1;
506 } 498 }
507 499
508 bool RetrieveAnimeMetadata(int id) { 500 bool RetrieveAnimeMetadata(int id) {
513 505
514 std::optional<std::string> service_id = anime.GetServiceId(Anime::Service::Kitsu); 506 std::optional<std::string> service_id = anime.GetServiceId(Anime::Service::Kitsu);
515 if (!service_id) 507 if (!service_id)
516 return false; 508 return false;
517 509
518 session.SetStatusBar("Kitsu: Retrieving anime metadata..."); 510 session.SetStatusBar(Strings::Translate("Kitsu: Retrieving anime metadata..."));
519 511
520 static const std::map<std::string, std::string> params = { 512 static const std::map<std::string, std::string> params = {
521 {"include", Strings::Implode({ 513 {"include", Strings::Implode({
522 "categories", 514 "categories",
523 "animeProductions", 515 "animeProductions",
530 return false; 522 return false;
531 523
532 const auto& json = response.value(); 524 const auto& json = response.value();
533 525
534 if (!json.contains("/included"_json_pointer) || !json["/included"_json_pointer].is_array()) { 526 if (!json.contains("/included"_json_pointer) || !json["/included"_json_pointer].is_array()) {
535 session.SetStatusBar("Kitsu: Server returned bad data when trying to retrieve anime metadata!"); 527 session.SetStatusBar(Strings::Translate("Kitsu: Server returned bad data when trying to retrieve anime metadata!"));
536 return false; 528 return false;
537 } 529 }
538 530
539 ParseMetadataJson(anime, json["/included"_json_pointer]); 531 ParseMetadataJson(anime, json["/included"_json_pointer]);
540 532
541 session.SetStatusBar("Kitsu: Successfully retrieved anime metadata!"); 533 session.SetStatusBar(Strings::Translate("Kitsu: Successfully retrieved anime metadata!"));
542 534
543 return true; 535 return true;
544 } 536 }
545 537
546 /* unimplemented for now */ 538 /* unimplemented for now */
575 return false; // whuh? 567 return false; // whuh?
576 568
577 const nlohmann::json& json = response.value(); 569 const nlohmann::json& json = response.value();
578 570
579 if (!json.contains("/data/0/id"_json_pointer)) { 571 if (!json.contains("/data/0/id"_json_pointer)) {
580 session.SetStatusBar("Kitsu: Failed to retrieve user ID!"); 572 session.SetStatusBar(Strings::Translate("Kitsu: Failed to retrieve user ID!"));
581 return false; 573 return false;
582 } 574 }
583 575
584 session.SetStatusBar("Kitsu: Successfully authorized user!"); 576 session.SetStatusBar(Strings::Translate("Kitsu: Successfully authorized user!"));
585 session.config.auth.kitsu.user_id = json["/data/0/id"_json_pointer].get<std::string>(); 577 session.config.auth.kitsu.user_id = json["/data/0/id"_json_pointer].get<std::string>();
586 578
587 return true; 579 return true;
588 } 580 }
589 581