Mercurial > minori
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 |
