generated from obsproject/obs-plugintemplate
-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30 from obs-ai/roy.add_jsonpath_array_parsing
Add jsonpath and array parsing
- Loading branch information
Showing
21 changed files
with
471 additions
and
235 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
[submodule "vendor/curl"] | ||
path = vendor/curl | ||
url = https://github.com/curl/curl.git | ||
[submodule "vendor/jsoncons"] | ||
path = vendor/jsoncons | ||
url = https://github.com/danielaparker/jsoncons.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
set(JSONCONS_BUILD_TESTS OFF) | ||
add_subdirectory(${CMAKE_SOURCE_DIR}/vendor/jsoncons ${CMAKE_BINARY_DIR}/jsoncons EXCLUDE_FROM_ALL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
target_sources(${CMAKE_PROJECT_NAME} PRIVATE jsonpointer.cpp jsonpath.cpp regex.cpp xml.cpp errors.cpp) | ||
|
||
# on linux, disable conversion errors | ||
if(UNIX AND NOT APPLE) | ||
set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) | ||
add_compile_options(-Wno-error -Wno-conversion -Wno-shadow -Wno-unused-parameter) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#include "plugin-support.h" | ||
#include "errors.h" | ||
|
||
#include <obs-module.h> | ||
|
||
struct request_data_handler_response make_fail_parse_response(const std::string &error_message) | ||
{ | ||
obs_log(LOG_INFO, "Failed to parse response: %s", error_message.c_str()); | ||
// Build an error response | ||
struct request_data_handler_response responseFail; | ||
responseFail.error_message = error_message; | ||
responseFail.status_code = URL_SOURCE_REQUEST_PARSING_ERROR_CODE; | ||
return responseFail; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef PARSERS_ERRORS_H | ||
#define PARSERS_ERRORS_H | ||
|
||
#include "request-data.h" | ||
|
||
struct request_data_handler_response make_fail_parse_response(const std::string &error_message); | ||
|
||
#endif // PARSERS_ERRORS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#include "request-data.h" | ||
#include "errors.h" | ||
|
||
#include <jsoncons/basic_json.hpp> | ||
#include <jsoncons/json_parser.hpp> | ||
#include <jsoncons_ext/jsonpath/jsonpath.hpp> | ||
#include <obs-module.h> | ||
|
||
struct request_data_handler_response parse_json(struct request_data_handler_response response, | ||
const url_source_request_data *request_data) | ||
{ | ||
UNUSED_PARAMETER(request_data); | ||
|
||
// Parse the response as JSON | ||
jsoncons::json json; | ||
try { | ||
json = jsoncons::json::parse(response.body); | ||
} catch (jsoncons::json_exception &e) { | ||
return make_fail_parse_response(e.what()); | ||
} | ||
// Return the whole JSON object | ||
response.body_parts_parsed.push_back(json.as_string()); | ||
return response; | ||
} | ||
|
||
struct request_data_handler_response parse_json_path(struct request_data_handler_response response, | ||
const url_source_request_data *request_data) | ||
{ | ||
|
||
// Parse the response as JSON | ||
jsoncons::json json; | ||
try { | ||
json = jsoncons::json::parse(response.body); | ||
} catch (jsoncons::json_exception &e) { | ||
return make_fail_parse_response(e.what()); | ||
} | ||
std::vector<std::string> parsed_output = {}; | ||
// Get the output value | ||
if (request_data->output_json_path != "") { | ||
try { | ||
const auto value = jsoncons::jsonpath::json_query( | ||
json, request_data->output_json_path); | ||
if (value.is_array()) { | ||
// extract array items as strings | ||
for (const auto &item : value.array_range()) { | ||
parsed_output.push_back(item.as_string()); | ||
} | ||
} else { | ||
parsed_output.push_back(value.as_string()); | ||
} | ||
} catch (jsoncons::json_exception &e) { | ||
return make_fail_parse_response(e.what()); | ||
} | ||
} else { | ||
// Return the whole JSON object | ||
parsed_output.clear(); | ||
parsed_output.push_back(json.as_string()); | ||
} | ||
response.body_parts_parsed = parsed_output; | ||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#include "request-data.h" | ||
#include "errors.h" | ||
|
||
#include <nlohmann/json.hpp> | ||
|
||
struct request_data_handler_response | ||
parse_json_pointer(struct request_data_handler_response response, | ||
const url_source_request_data *request_data) | ||
{ | ||
// Parse the response as JSON | ||
nlohmann::json json; | ||
try { | ||
json = nlohmann::json::parse(response.body); | ||
} catch (nlohmann::json::parse_error &e) { | ||
return make_fail_parse_response(e.what()); | ||
} | ||
std::string parsed_output = ""; | ||
// Get the output value | ||
if (request_data->output_json_pointer != "") { | ||
try { | ||
const auto value = json.at(nlohmann::json::json_pointer( | ||
request_data->output_json_pointer)) | ||
.get<nlohmann::json>(); | ||
if (value.is_string()) { | ||
parsed_output = value.get<std::string>(); | ||
} else { | ||
parsed_output = value.dump(); | ||
} | ||
// remove potential prefix and postfix quotes, conversion from string | ||
if (parsed_output.size() > 1 && parsed_output.front() == '"' && | ||
parsed_output.back() == '"') { | ||
parsed_output = parsed_output.substr(1, parsed_output.size() - 2); | ||
} | ||
} catch (nlohmann::json::exception &e) { | ||
return make_fail_parse_response(e.what()); | ||
} | ||
} else { | ||
// Return the whole JSON object | ||
parsed_output = json.dump(); | ||
} | ||
response.body_parts_parsed.push_back(parsed_output); | ||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef PARSERS_H | ||
#define PARSERS_H | ||
|
||
#include "request-data.h" | ||
|
||
struct request_data_handler_response parse_json(struct request_data_handler_response response, | ||
const url_source_request_data *request_data); | ||
|
||
struct request_data_handler_response | ||
parse_json_pointer(struct request_data_handler_response response, | ||
const url_source_request_data *request_data); | ||
|
||
struct request_data_handler_response parse_json_path(struct request_data_handler_response response, | ||
const url_source_request_data *request_data); | ||
|
||
struct request_data_handler_response parse_regex(struct request_data_handler_response response, | ||
const url_source_request_data *request_data); | ||
|
||
struct request_data_handler_response parse_xml(struct request_data_handler_response response, | ||
const url_source_request_data *request_data); | ||
|
||
struct request_data_handler_response | ||
parse_xml_by_xquery(struct request_data_handler_response response, | ||
const url_source_request_data *request_data); | ||
|
||
#endif // PARSERS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
|
||
#include "request-data.h" | ||
#include "plugin-support.h" | ||
|
||
#include <regex> | ||
#include <obs-module.h> | ||
|
||
struct request_data_handler_response parse_regex(struct request_data_handler_response response, | ||
const url_source_request_data *request_data) | ||
{ | ||
std::string parsed_output = ""; | ||
if (request_data->output_regex == "") { | ||
// Return the whole response body | ||
parsed_output = response.body; | ||
} else { | ||
// Parse the response as a regex | ||
std::regex regex(request_data->output_regex, | ||
std::regex_constants::ECMAScript | std::regex_constants::optimize); | ||
std::smatch match; | ||
if (std::regex_search(response.body, match, regex)) { | ||
if (match.size() > 1) { | ||
parsed_output = match[1].str(); | ||
} else { | ||
parsed_output = match[0].str(); | ||
} | ||
} else { | ||
obs_log(LOG_INFO, "Failed to match regex"); | ||
// Return an error response | ||
struct request_data_handler_response responseFail; | ||
responseFail.error_message = "Failed to match regex"; | ||
responseFail.status_code = URL_SOURCE_REQUEST_PARSING_ERROR_CODE; | ||
return responseFail; | ||
} | ||
} | ||
response.body_parts_parsed.push_back(parsed_output); | ||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
|
||
#include "request-data.h" | ||
#include "plugin-support.h" | ||
|
||
#include <pugixml.hpp> | ||
#include <obs-module.h> | ||
|
||
struct request_data_handler_response parse_xml(struct request_data_handler_response response, | ||
const url_source_request_data *request_data) | ||
{ | ||
// Parse the response as XML using pugixml | ||
pugi::xml_document doc; | ||
pugi::xml_parse_result result = doc.load_string(response.body.c_str()); | ||
if (!result) { | ||
obs_log(LOG_INFO, "Failed to parse XML response: %s", result.description()); | ||
// Return an error response | ||
struct request_data_handler_response responseFail; | ||
responseFail.error_message = result.description(); | ||
responseFail.status_code = URL_SOURCE_REQUEST_PARSING_ERROR_CODE; | ||
return responseFail; | ||
} | ||
std::string parsed_output = ""; | ||
// Get the output value | ||
if (request_data->output_xpath != "") { | ||
pugi::xpath_node_set nodes = doc.select_nodes(request_data->output_xpath.c_str()); | ||
if (nodes.size() > 0) { | ||
parsed_output = nodes[0].node().text().get(); | ||
} else { | ||
obs_log(LOG_INFO, "Failed to get XML value"); | ||
// Return an error response | ||
struct request_data_handler_response responseFail; | ||
responseFail.error_message = "Failed to get XML value"; | ||
responseFail.status_code = URL_SOURCE_REQUEST_PARSING_ERROR_CODE; | ||
return responseFail; | ||
} | ||
} else { | ||
// Return the whole XML object | ||
parsed_output = response.body; | ||
} | ||
response.body_parts_parsed.push_back(parsed_output); | ||
return response; | ||
} | ||
|
||
struct request_data_handler_response | ||
parse_xml_by_xquery(struct request_data_handler_response response, | ||
const url_source_request_data *request_data) | ||
{ | ||
// Parse the response as XML using pugixml | ||
pugi::xml_document doc; | ||
pugi::xml_parse_result result = doc.load_string(response.body.c_str()); | ||
if (!result) { | ||
obs_log(LOG_INFO, "Failed to parse XML response: %s", result.description()); | ||
// Return an error response | ||
struct request_data_handler_response responseFail; | ||
responseFail.error_message = result.description(); | ||
responseFail.status_code = URL_SOURCE_REQUEST_PARSING_ERROR_CODE; | ||
return responseFail; | ||
} | ||
std::string parsed_output = ""; | ||
// Get the output value | ||
if (request_data->output_xquery != "") { | ||
pugi::xpath_query query_entity(request_data->output_xquery.c_str()); | ||
std::string s = query_entity.evaluate_string(doc); | ||
parsed_output = s; | ||
} else { | ||
// Return the whole XML object | ||
parsed_output = response.body; | ||
} | ||
response.body_parts_parsed.push_back(parsed_output); | ||
return response; | ||
} |
Oops, something went wrong.