#include "pke-at-data-parser.hpp" #include "pke-at-common.hpp" #include #include #include using json = nlohmann::json; pk_arr_t pke_at_data_parser_service_types(char *data) { PK_STN_RES stn_res; pk_arr_t ret{}; json j = json::parse(data); char *val; std::string s; if (!j.contains("data") || j.at("data").is_null()) { fprintf(stderr, "[pke_at_data_parser_service_types] no 'data'\n"); return {}; } json dat = j.at("data"); for (json::iterator it = dat.begin(); it != dat.end(); ++it) { di_service_type obj{}; it->at("id").get_to(s); stn_res = pk_stn(&obj.details.id.id_long, s.c_str(), nullptr); if (stn_res != PK_STN_RES_SUCCESS) { fprintf(stderr, "[pke_at_data_parser_service_types] failed to parse id: %i\n", stn_res); return {}; } json attr = (*it).at("attributes"); attr.at("name").get_to(s); obj.details.name.length = s.length(); obj.details.name.reserved = s.length() + 1; val = pk_new_arr(obj.details.name.reserved); std::strncpy(val, s.c_str(), obj.details.name.reserved); obj.details.name.val = val; pk_arr_append_t(&ret, obj); } return ret; } pk_arr_t pke_at_data_parser_plans(char *data) { PK_STN_RES stn_res; pk_arr_t ret{}; json j = json::parse(data); char *val; std::string s; if (!j.contains("data") || j.at("data").is_null()) { fprintf(stderr, "[pke_at_data_parser_plans] no 'data'\n"); return {}; } json dat = j.at("data"); for (json::iterator it = dat.begin(); it != dat.end(); ++it) { di_plan obj{}; it->at("id").get_to(s); stn_res = pk_stn(&obj.details.id.id_long, s.c_str(), nullptr); if (stn_res != PK_STN_RES_SUCCESS) { fprintf(stderr, "[pke_at_data_parser_plans] failed to parse id: %i\n", stn_res); return {}; } json attr = (*it).at("attributes"); attr.at("sort_date").get_to(s); std::istringstream ss(s); std::tm t{}; ss >> std::get_time(&t, "%Y-%m-%dT%H:%M:%SZ"); obj.details.date = std::mktime(&t); if (attr.contains("title") && !attr.at("title").is_null()) { attr.at("title").get_to(s); obj.details.title.length = s.length(); obj.details.title.reserved = s.length() + 1; val = pk_new_arr(obj.details.title.reserved); std::strncpy(val, s.c_str(), obj.details.title.reserved); obj.details.title.val = val; } if (attr.contains("series_title") && !attr.at("series_title").is_null()) { attr.at("series_title").get_to(s); obj.details.series_title.length = s.length(); obj.details.series_title.reserved = s.length() + 1; val = pk_new_arr(obj.details.series_title.reserved); std::strncpy(val, s.c_str(), obj.details.series_title.reserved); obj.details.series_title.val = val; } pk_arr_append_t(&ret, obj); } return ret; } pk_arr_t pke_at_data_parser_plan_items(char *data) { PK_STN_RES stn_res; pk_arr_t ret{}; json j = json::parse(data); char *val; std::string s; long id, id_song, id_arrangement, id_key; if (!j.contains("data") || j.at("data").is_null()) { fprintf(stderr, "[pke_at_data_parser_plan_items] no 'data'\n"); return {}; } json dat = j.at("data"); if (!j.contains("included") || j.at("included").is_null()) { fprintf(stderr, "[pke_at_data_parser_plan_items] no 'included'\n"); return {}; } json incl = j.at("included"); for (json::iterator it = dat.begin(); it != dat.end(); ++it) { di_plan_item obj{}; id_song = -1; id_arrangement = -1; id_key = -1; json attr = it->at("attributes"); if (!attr.contains("item_type") || attr.at("item_type").is_null()) { continue; } attr.at("item_type").get_to(s); if (!case_insensitive_equal(s.c_str(), "song")) { continue; } it->at("id").get_to(s); stn_res = pk_stn(&obj.details.id.id_long, s.c_str(), nullptr); if (stn_res != PK_STN_RES_SUCCESS) { fprintf(stderr, "[pke_at_data_parser_plan_items] failed to parse id: %i\n", stn_res); return {}; } if (attr.contains("key_name") && !attr.at("key_name").is_null()) { attr.at("key_name").get_to(s); obj.details.key = parse_key_from_string(s.c_str()); } attr.at("sequence").get_to(obj.details.sequence); json rel_song = it->at("relationships").at("song").at("data"); json rel_arrangement = it->at("relationships").at("arrangement").at("data"); json rel_key = it->at("relationships").at("key").at("data"); rel_song.at("id").get_to(s); stn_res = pk_stn(&id_song, s.c_str(), nullptr); rel_arrangement.at("id").get_to(s); stn_res = pk_stn(&id_arrangement, s.c_str(), nullptr); rel_key.at("id").get_to(s); stn_res = pk_stn(&id_key, s.c_str(), nullptr); for (json::iterator incl_it = incl.begin(); incl_it != incl.end(); ++incl_it) { incl_it->at("type").get_to(s); if (case_insensitive_equal(s.c_str(), "song")) { attr = incl_it->at("attributes"); incl_it->at("id").get_to(s); pk_stn(&id, s.c_str(), nullptr); if (id != id_song) continue; obj.song.details.id.id_long = id; attr.at("ccli_number").get_to(obj.song.details.ccli); if (attr.contains("title") && !attr.at("title").is_null()) { attr.at("title").get_to(s); obj.song.details.title.length = s.length(); obj.song.details.title.reserved = s.length() + 1; val = pk_new_arr(obj.song.details.title.reserved); std::strncpy(val, s.c_str(), obj.song.details.title.reserved); obj.song.details.title.val = val; } continue; } if (case_insensitive_equal(s.c_str(), "arrangement")) { attr = incl_it->at("attributes"); incl_it->at("id").get_to(s); pk_stn(&id, s.c_str(), nullptr); if (id != id_arrangement) continue; obj.arrangement.details.id.id_long = id; if (attr.contains("bpm") && !attr.at("bpm").is_null()) { attr.at("bpm").get_to(obj.arrangement.details.beats_per_minute); } if (attr.contains("meter") && !attr.at("meter").is_null()) { attr.at("meter").get_to(s); char cc[2] = { s.at(0), '\0'}; pk_stn(&obj.arrangement.details.beats_per_bar, cc, nullptr); } if (attr.contains("chord_chart_key") && !attr.at("chord_chart_key").is_null()) { attr.at("chord_chart_key").get_to(s); obj.arrangement.details.chord_chart_key = parse_key_from_string(s.c_str()); } if (attr.contains("name") && !attr.at("name").is_null()) { attr.at("name").get_to(s); obj.arrangement.details.title.length = s.length(); obj.arrangement.details.title.reserved = s.length() + 1; val = pk_new_arr(obj.arrangement.details.title.reserved); std::strncpy(val, s.c_str(), obj.arrangement.details.title.reserved); obj.arrangement.details.title.val = val; } if (attr.contains("sequence_full") && !attr.at("sequence_full").is_null()) { for (json::iterator sec_it = attr.at("sequence_full").begin(); sec_it != attr.at("sequence_full").end(); ++sec_it) { sec_it->at("label").get_to(s); pk_arr_append_t(&obj.arrangement.details.sequence, parse_section_type_from_string(s.c_str())); } } continue; } if (case_insensitive_equal(s.c_str(), "key")) { attr = incl_it->at("attributes"); incl_it->at("id").get_to(s); pk_stn(&id, s.c_str(), nullptr); if (id != id_key) continue; obj.key.details.id.id_long = id; if (attr.contains("starting_key") && !attr.at("starting_key").is_null()) { attr.at("starting_key").get_to(s); obj.key.details.key = parse_key_from_string(s.c_str()); } continue; } fprintf(stderr, "[pke_at_data_parser_plan_items] unhandled include \"type\": '%s'\n", s.c_str()); } pk_arr_append_t(&ret, obj); } return ret; }