diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..9fc229b9323ef5f102dfdacf322aba488e74a8a6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "libdap"] + path = libdap + url = https://github.com/cellframe/libdap.git +[submodule "libdap-crypto"] + path = libdap-crypto + url = https://github.com/cellframe/libdap-crypto.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4f197d5c8850d37cc3c98973831acdd70e8346bc --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,44 @@ +project(dap_python_module C) +cmake_minimum_required(VERSION 2.8) + +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_COLOR_MAKEFILE ON) +set(CMAKE_C_STANDARD 11) +set(SUBMODULES_NO_BUILD ON) + +add_subdirectory(libdap) +add_subdirectory(libdap-crypto) + +file(GLOB CORE_SRCS src/*.c) +file(GLOB CORE_HEADERS src/*.h) + +set(Python_ADDITIONAL_VERSIONS 3.7) +find_package (PythonLibs REQUIRED) +#find_package(PkgConfig) +#pkg_check_modules(PC_JSON-C REQUIRED json-c) +include_directories(${PYTHON_INCLUDE_DIR}) + +add_library(${PROJECT_NAME} SHARED ${CORE_SRCS} ${CORE_UNIX_SRCS}) + +target_link_libraries(${PROJECT_NAME} ${PYTHON_LIBRARIES}) + +target_compile_options( + dap_core PRIVATE + "-fpic" +) + +target_link_libraries(${PROJECT_NAME} dap_core dap_crypto) + +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/libdapConnector.py + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/main_test.py + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + +if(BUILD_DAP_TESTS) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/main_test.py + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + enable_testing() + #add_subdirectory(test) +endif() + diff --git a/libdap b/libdap new file mode 160000 index 0000000000000000000000000000000000000000..d37b2aa26d2a7cc068529db343a87fd728904d33 --- /dev/null +++ b/libdap @@ -0,0 +1 @@ +Subproject commit d37b2aa26d2a7cc068529db343a87fd728904d33 diff --git a/libdap-crypto b/libdap-crypto new file mode 160000 index 0000000000000000000000000000000000000000..ff63d762657f9687173db825705b8bf4b958abee --- /dev/null +++ b/libdap-crypto @@ -0,0 +1 @@ +Subproject commit ff63d762657f9687173db825705b8bf4b958abee diff --git a/src/libdap-python.c b/src/libdap-python.c new file mode 100644 index 0000000000000000000000000000000000000000..79bb87ebae28dc1c0580e32a75f8a79ce60434f6 --- /dev/null +++ b/src/libdap-python.c @@ -0,0 +1,149 @@ +#include "libdap-python.h" + +static PyObject *dap_init(PyObject *self, PyObject *args){ + const char *data; + char *system_configs_dir; + char *dap_app_name; + char *dap_app_name_logs; + if (!PyArg_ParseTuple(args, "s", &data)) + return NULL; + int lenSystemConfigDir=0; + int lenDapAppName=0; + int countSeparators=0; + int lenMassives = 0; + while (*(data+lenMassives) != '\0'){ + if (*(data+lenMassives)=='\n'){ + countSeparators += 1; + }else { + if (countSeparators == 0) + lenSystemConfigDir++; + if (countSeparators == 1) + lenDapAppName++; + } + lenMassives++; + } + system_configs_dir = calloc(lenSystemConfigDir, sizeof(char)); + dap_app_name = calloc(lenDapAppName, sizeof(char)); + dap_app_name_logs = calloc((lenDapAppName+9), sizeof(char)); + memcpy(system_configs_dir,data,lenSystemConfigDir); + memcpy(dap_app_name, data+lenSystemConfigDir+1, lenDapAppName); + memcpy(dap_app_name_logs, dap_app_name, lenDapAppName); + const char* log = "_logs.txt"; + memcpy(dap_app_name_logs+lenDapAppName, log,9); + dap_config_init(system_configs_dir); + if ((g_config = dap_config_open(dap_app_name) ) == NULL){ + log_it(L_CRITICAL, "Can't init general configurations"); + return PyLong_FromLong(-1); + } + if (dap_common_init(dap_app_name_logs)!=0){ + log_it(L_CRITICAL, "Can't init common functions module"); + return PyLong_FromLong(-2); + } + dap_log_level_set( dap_config_get_item_bool_default(g_config,"general","debug_mode", false)? L_DEBUG: L_NOTICE ); + return PyLong_FromLong(0); +} + +static PyObject *dap_deinit(PyObject *self){ + dap_config_deinit(); + dap_common_deinit(); + return PyLong_FromLong(0); +} + +static PyObject *dap_set_log_level(PyObject *self, PyObject *args){ + const char *data; + if (!PyArg_ParseTuple(args, "s", &data)) + return NULL; + dap_log_level_t new_log_level = convert_const_char_to_dap_log_level(data); + if (new_log_level == -1) { + return PyLong_FromLong(-1); + } else { + dap_log_level_set(new_log_level); + return PyLong_FromLong(0); + } +} + +static dap_log_level_t convert_const_char_to_dap_log_level(const char* string){ + if (strcmp(string,"DEBUG") == 0){ + return L_DEBUG; + } + if (strcmp(string, "INFO") == 0){ + return L_INFO; + } + if (strcmp(string, "NOTICE") == 0){ + return L_NOTICE; + } + if (strcmp(string, "WARNING") == 0){ + return L_WARNING; + } + if (strcmp(string, "ERROR") == 0){ + return L_ERROR; + } + if (strcmp(string, "CRITICAL") == 0){ + return L_CRITICAL; + } + return -1; +} + +static PyObject* dap_log_it(PyObject* self, PyObject* args){ + const char *data; + if (!PyArg_ParseTuple(args, "s", &data)) + return NULL; + char* dap_log_leve_char; + char* string_output; + int len_log_level_char=0; + int len_string_output=0; + int countSeparators=0; + int lenMassives = 0; + while (*(data+lenMassives) != '\0'){ + if (*(data+lenMassives)=='\n'){ + countSeparators += 1; + }else { + if (countSeparators == 0) + len_log_level_char++; + if (countSeparators == 1) + len_string_output++; + } + lenMassives++; + } + if (len_log_level_char == 0 || len_string_output == 0) + return PyLong_FromLong(-1); + dap_log_leve_char = calloc(len_log_level_char, sizeof(char)); + string_output = calloc(len_string_output, sizeof(char)); + memcpy(dap_log_leve_char, data, len_log_level_char); + memcpy(string_output, data+len_log_level_char+1, len_string_output); + dap_log_level_t log_level = convert_const_char_to_dap_log_level(dap_log_leve_char); + if (log_level == -1) + return PyLong_FromLong(-1); + log_it(log_level, string_output); + + return PyLong_FromLong(0); +} + +PyMODINIT_FUNC PyInit_libdap_python_module(void){ + return PyModule_Create(&dapmodule); +} + +int main(int argc, char **argv) { + wchar_t *program = Py_DecodeLocale(argv[0], NULL); + if (program == NULL) { + fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); + exit(1); + } + + /* Add a built-in module, before Py_Initialize */ + PyImport_AppendInittab("libdap_python_module", PyInit_libdap_python_module); + + /* Pass argv[0] to the Python interpreter */ + Py_SetProgramName(program); + + /* Initialize the Python interpreter. Required. */ + Py_Initialize(); + + /* Optionally import the module; alternatively, + import can be deferred until the embedded script + imports it. */ + PyImport_ImportModule("libdap_python_module"); + + PyMem_RawFree(program); + return 0; +} diff --git a/src/libdap-python.h b/src/libdap-python.h new file mode 100644 index 0000000000000000000000000000000000000000..f43a70d79bc48e1357c94fc849c27a3ae851474c --- /dev/null +++ b/src/libdap-python.h @@ -0,0 +1,43 @@ +#define PY_SSIZE_T_CLEAN +#include <python3.7/Python.h> +#include "dap_config.h" +#include "dap_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOG_TAG "libdap-python" + +static PyObject *dap_init(PyObject *self, PyObject *args); + +static PyObject *dap_deinit(PyObject *self); + +static PyObject *dap_set_log_level(PyObject *self, PyObject *args); + +static PyObject* dap_log_it(PyObject* self, PyObject* args); + +static dap_log_level_t convert_const_char_to_dap_log_level(const char* string); + +static PyMethodDef DapMethods[] = { + {"init", dap_init, METH_VARARGS, "Initialization of the DAP (Deus Applicaions Prototypes) library"}, + {"deinit", dap_deinit, METH_NOARGS, "Deinitialization of the DAP (Deus Applicaions Prototypes) library"}, + {"setLogLevel", dap_set_log_level, METH_VARARGS, "Setting the logging level"}, + {"logIt", dap_log_it, METH_VARARGS, "The wrapper of the log_it function for the libdap library"}, + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef dapmodule = { + PyModuleDef_HEAD_INIT, + "libdap_python_module", /* name of module */ + NULL, /* module documentation, may be NULL */ + -1, /* size of per-interpreter state of the module, + or -1 if the module keeps state in global variables. */ + DapMethods +}; + +PyMODINIT_FUNC PyInit_libdap_python_module(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/libdapConnector.py b/src/libdapConnector.py new file mode 100644 index 0000000000000000000000000000000000000000..ddcd081a3e7cda40a21564afb92cd0d0cb2a4d9c --- /dev/null +++ b/src/libdapConnector.py @@ -0,0 +1,30 @@ +import json +import libdap_python_module + +class DapIniException(Exception): + pass + +class Dap: + def __init__(self, data): + res = json.loads(data) + self.modules=res['modules'] + self.config_dir=res['dap']['config_dir'] + self.log_level=res['dap']['log_level'] + self.application_name=res['dap']['application_name'] + res_init = libdap_python_module.init(res['dap']['config_dir']+"\n"+res['dap']['application_name']+"\n") + if res_init == -1 or res_init == -2: + raise DapIniException("Initialization erorr") + def __del__(self): + libdap_python_module.deinit() + def setLogLevel(self, data): + self.log_level=data + res_setLogLevel = libdap_python_module.setLogLevel(data) + if res_setLogLevel == -1: + raise DapIniException("Failed to set the logging level, perhaps you did not correctly specify the name of the level") + def logIt(self, data): + parse_data = json.loads(data) + res_log_it = libdap_python_module.logIt(parse_data['level']+"\n"+parse_data['data']) + if res_log_it == -1: + raise DapIniException("Could not execute log_it function. Perhaps you did not correctly specify the name of the logging level or did not leave the information that needs to be displayed") + + diff --git a/test/main_test.py b/test/main_test.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbb113e94c03371acf3a12b555fa07b4d9a8987 --- /dev/null +++ b/test/main_test.py @@ -0,0 +1,20 @@ +import libdapConnector + +json_string = """{ + "modules": "libdap", + "dap": { + "config_dir": "/opt/dap/etc/", + "log_level": "Debug", + "application_name": "TestAPP" + } + }""" +print("Standard Configuration \n"+json_string) +daptest = libdapConnector.Dap(json_string) +print("Initialization of the DAP") +daptest.setLogLevel("DEBUG") +print("Level logging ""DEBUG"" done") +daptest.logIt("""{ + "level": "DEBUG", + "data": "Test. Outputting a string using the log_it function in the libdap library" +}""") +print("Outputting a string using the log_it function done")