summaryrefslogtreecommitdiff
path: root/src/pke-at-data-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pke-at-data-parser.cpp')
-rw-r--r--src/pke-at-data-parser.cpp218
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;
+}