diff options
Diffstat (limited to 'src/pke-at-data-parser.cpp')
| -rw-r--r-- | src/pke-at-data-parser.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/src/pke-at-data-parser.cpp b/src/pke-at-data-parser.cpp new file mode 100644 index 0000000..da70e4e --- /dev/null +++ b/src/pke-at-data-parser.cpp @@ -0,0 +1,218 @@ + +#include "pke-at-data-parser.hpp" +#include "pke-at-common.hpp" + +#include <ctime> +#include <nlohmann/json.hpp> +#include <sstream> + +using json = nlohmann::json; + +pk_arr_t<di_service_type> pke_at_data_parser_service_types(char *data) { + PK_STN_RES stn_res; + pk_arr_t<di_service_type> 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<char>(obj.details.name.reserved); + std::strncpy(val, s.c_str(), obj.details.name.reserved); + obj.details.name.val = val; + pk_arr_append_t<di_service_type>(&ret, obj); + } + return ret; +} + +pk_arr_t<di_plan> pke_at_data_parser_plans(char *data) { + PK_STN_RES stn_res; + pk_arr_t<di_plan> 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<char>(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<char>(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<di_plan>(&ret, obj); + } + return ret; +} + +pk_arr_t<di_plan_item> pke_at_data_parser_plan_items(char *data) { + PK_STN_RES stn_res; + pk_arr_t<di_plan_item> 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<char>(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<char>(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<PKE_AT_SECTION_TYPE_INDEX>(&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<di_plan_item>(&ret, obj); + } + return ret; +} |
