From: Xie Ligang Date: Wed, 11 Jul 2018 08:21:10 +0000 (+0800) Subject: Upload the nlp daemon X-Git-Tag: submit/tizen/20180821.231644~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4e337e51e40e7251fc5c482cff4c9ce9583ef37e;p=platform%2Fcore%2Fuifw%2Fnlp.git Upload the nlp daemon Change-Id: Iccf4c453e82c8fc6a894a07df37ab87967003b1d Signed-off-by: Xie Ligang --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 28cc708..5fb9567 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,5 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) ADD_SUBDIRECTORY(client) + +ADD_SUBDIRECTORY(service) diff --git a/packaging/nlp.spec b/packaging/nlp.spec index 4c63b21..5564c1f 100755 --- a/packaging/nlp.spec +++ b/packaging/nlp.spec @@ -1,4 +1,4 @@ -Name: nlp +Name: org.tizen.nlp.service Summary: NLTK Version: 0.1.0 @@ -8,8 +8,17 @@ License: Apache-2.0 Source0: %{name}-%{version}.tar.gz BuildRequires: cmake BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(capi-message-port) +BuildRequires: pkgconfig(capi-appfw-service-application) +BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(python) +# runtime requires +Requires(post): /sbin/ldconfig +Requires(post): coreutils +Requires(postun): /sbin/ldconfig + %description Natural Language Processing library. @@ -17,6 +26,9 @@ Natural Language Processing library. %setup -q %build +%define _app_home_dir %{TZ_SYS_RO_APP}/%{name} +%define _app_bin_dir %{_app_home_dir}/bin + MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} @@ -26,12 +38,25 @@ rm -rf %{buildroot} %make_install -%post +%define tizen_sign 1 +%define tizen_sign_base /usr/apps/%{name} +%define tizen_sign_level public +%define tizen_author_sign 1 +%define tizen_dist_sign 1 + +#%post +#/sbin/ldconfig + +%post -n org.tizen.nlp.service +/usr/bin/signing-client/hash-signer-client.sh -a -d -p platform org.tizen.nlp.service -%postun +%postun -p /sbin/ldconfig %files +%manifest service/org.tizen.nlp.service.manifest %{_libdir}/*.so %{_includedir}/*.h +%{_app_bin_dir}/* +%{TZ_SYS_RO_PACKAGES}/org.tizen.nlp.service.xml %license LICENSE diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt new file mode 100644 index 0000000..f105f4e --- /dev/null +++ b/service/CMakeLists.txt @@ -0,0 +1,48 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_name "org.tizen.nlp.service") +PROJECT(${fw_name} C) + +INCLUDE(FindPkgConfig) + +EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE CMAKE_SYSTEM_VERSION) +message("Building by ${CMAKE_SYSTEM_VERSION} machine") + +SET(SERVICE_SRC + src/service.c + ) + +#include +set(INC_DIRS + inc + ) +message("INC_DIRS:${INC_DIRS}") +INCLUDE_DIRECTORIES( ${INC_DIRS} ) + + +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE "Debug") +ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") +MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") + +pkg_check_modules(pkgs REQUIRED + capi-base-common + capi-message-port + capi-appfw-service-application + bundle + python + ) +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror-implicit-function-declaration -Wl,--unresolved-symbols=ignore-in-shared-libs -Wl,-zdefs") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +ADD_EXECUTABLE(${fw_name} ${SERVICE_SRC}) +TARGET_LINK_LIBRARIES(${fw_name} ${pkgs_LDFLAGS} -lm) + +INSTALL(TARGETS ${fw_name} DESTINATION /usr/apps/org.tizen.nlp.service/bin/) +INSTALL(FILES inc/service.h DESTINATION /usr/include) +INSTALL(FILES org.tizen.nlp.service.xml DESTINATION /usr/share/packages) diff --git a/service/inc/service.h b/service/inc/service.h new file mode 100644 index 0000000..f2f234d --- /dev/null +++ b/service/inc/service.h @@ -0,0 +1,30 @@ +#ifndef __service_H__ +#define __service_H__ + +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "nltk_service" + +// This method is exported from nltk_native_library.so +void nltk_initialize(); +void nltk_finalize(); +PyObject* nltk_getModule(char* m_name); +PyObject* nltk_getFunctionHandle(PyObject* m_module , char * f_name); +PyObject* nltk_makeArgsFromPyObject(PyObject* pyobj); +PyObject* nltk_makeArgsFromString(char* info); +PyObject* nltk_callFunctionWithArgs(PyObject* m_func, PyObject* args); +int nltk_getSizeFromList(PyObject* list); +int nltk_getSizeFromTuple(PyObject* tuple); +PyObject* nltk_getElementFromTupleByIndex(PyObject* tuple , int index ); +PyObject* nltk_getElementFromListByIndex(PyObject* list, int index); +char* nltk_getStringFromElement(PyObject* elm); +char* nltk_getattrib(int z); +PyObject* globe_nltk; +PyObject* globe_lemm; +PyObject* globe_lang; +int globe_id = 0; +#endif /* __service_H__ */ diff --git a/service/org.tizen.nlp.service.manifest b/service/org.tizen.nlp.service.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/service/org.tizen.nlp.service.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/service/org.tizen.nlp.service.xml b/service/org.tizen.nlp.service.xml new file mode 100644 index 0000000..3b046c7 --- /dev/null +++ b/service/org.tizen.nlp.service.xml @@ -0,0 +1,8 @@ + + + + + + service.png + + diff --git a/service/shared/res/service.png b/service/shared/res/service.png new file mode 100644 index 0000000..9765b1b Binary files /dev/null and b/service/shared/res/service.png differ diff --git a/service/src/service.c b/service/src/service.c new file mode 100644 index 0000000..9109f63 --- /dev/null +++ b/service/src/service.c @@ -0,0 +1,394 @@ +#include +#include +#include +#include +#include "service.h" +#include + +void +message_port_cb(int local_port_id, const char *remote_app_id, const char *remote_port, + bool trusted_remote_port, bundle *message, void *user_data) +{ + const char *command = NULL; + bundle *reply = bundle_create(); + bundle_get_str(message, "command", &command); + //dlog_print(DLOG_INFO, LOG_TAG, "service get message from client, remote port is %s",remote_port); + char *info = NULL; + PyObject* args = NULL; + PyObject* lists = NULL; + unsigned static int len = 0; + PyObject* postag_module = NULL; + PyObject* postag_result = NULL; + PyObject* ne_module = NULL; + PyObject* ne_result = NULL; + PyObject* lv_module = NULL; + PyObject* lv_result = NULL; + PyObject* lm_module = NULL; + PyObject* lm_result = NULL; + PyObject* lm_object = NULL; + PyObject* ld_module = NULL; + PyObject* ld_result = NULL; + PyObject* pos_elm_tuple = NULL; + bundle_get_str(message, "info", &info); + dlog_print(DLOG_INFO, LOG_TAG, "service get message from client, remote command is %s , remote info is %s",command ,info); + int static i = -1; + if (!strcmp(command, "word_tokenize")) + {i = 1;dlog_print(DLOG_INFO, LOG_TAG, "service get a command is: %s", command);} + else if (!strcmp(command, "pos_tag" )) + {i = 2;dlog_print(DLOG_INFO, LOG_TAG, "service get a command is: %s", command);} + else if (!strcmp(command, "ne_chunk")) + {i = 3;dlog_print(DLOG_INFO, LOG_TAG, "service get a command is: %s", command);} + else if (!strcmp(command, "lemmatize")) + {i = 4;dlog_print(DLOG_INFO, LOG_TAG, "service get a command is: %s", command);} + else if (!strcmp(command, "langdetect")) + {i = 5;dlog_print(DLOG_INFO, LOG_TAG, "service get a command is: %s", command);} + switch (i) { + case 1: + { + args = nltk_makeArgsFromString(info); + lists = nltk_callFunctionWithArgs(nltk_getFunctionHandle(globe_nltk,"word_tokenize"), args); + len = nltk_getSizeFromList(lists); + char *s_token[128] = {NULL,}; + for(int i = 0 ;i < len ;i++) + { + s_token[i] = (char*)malloc(128*sizeof(char)); + strcpy(s_token[i] ,nltk_getStringFromElement(nltk_getElementFromListByIndex(lists, i))); + } + bundle_add_str(reply, "command", "word_tokenize"); + bundle_add_str_array(reply, "return", s_token, len); + dlog_print(DLOG_INFO, LOG_TAG, "word_tokenize process done"); + } + break; + case 2: + { + char *s_tag[128] = {NULL,}; + char *s_token[128] = {NULL,}; + args = nltk_makeArgsFromString(info); + lists = nltk_callFunctionWithArgs(nltk_getFunctionHandle(globe_nltk,"word_tokenize"), args); + postag_module = nltk_getFunctionHandle(globe_nltk,"pos_tag"); + args = nltk_makeArgsFromPyObject(lists); + postag_result = nltk_callFunctionWithArgs(postag_module, args); + len = nltk_getSizeFromList(postag_result); + for(int i = 0 ;i < len ;i++) + { + s_token[i] = (char*)malloc(128*sizeof(char)); + s_tag[i] = (char*)malloc(128*sizeof(char)); + pos_elm_tuple = nltk_getElementFromListByIndex(postag_result, i); + strcpy(s_tag[i] , nltk_getStringFromElement(nltk_getElementFromTupleByIndex(pos_elm_tuple, 0))); + strcpy(s_token[i] , nltk_getStringFromElement(nltk_getElementFromTupleByIndex(pos_elm_tuple, 1))); + } + bundle_add_str(reply, "command", "pos_tag"); + bundle_add_str_array(reply, "return_tag", s_tag, len); + bundle_add_str_array(reply, "return_token", s_token, len); + dlog_print(DLOG_INFO, LOG_TAG, "pos_tag process done"); + } + break; + case 3: + { + char *s_tag[128] = {NULL,}; + char *s_token[128] = {NULL,}; + args = nltk_makeArgsFromString(info); + lists = nltk_callFunctionWithArgs(nltk_getFunctionHandle(globe_nltk,"word_tokenize"), args); + postag_module = nltk_getFunctionHandle(globe_nltk,"pos_tag"); + args = nltk_makeArgsFromPyObject(lists); + postag_result = nltk_callFunctionWithArgs(postag_module, args); + args = nltk_makeArgsFromPyObject(postag_result); + ne_module = nltk_getFunctionHandle(globe_nltk,"ne_chunk"); + ne_result = nltk_callFunctionWithArgs(ne_module, args); + lv_module = nltk_getFunctionHandle(ne_result, "leaves"); + lv_result = nltk_callFunctionWithArgs(lv_module, NULL); + len = nltk_getSizeFromList(lv_result); + for(int i = 0 ;i < len ;i++) + { + s_token[i] = (char*)malloc(128*sizeof(char)); + s_tag[i] = (char*)malloc(128*sizeof(char)); + pos_elm_tuple = nltk_getElementFromListByIndex(lv_result, i); + strcpy(s_tag[i] , nltk_getStringFromElement(nltk_getElementFromTupleByIndex(pos_elm_tuple, 0))); + strcpy(s_token[i] , nltk_getStringFromElement(nltk_getElementFromTupleByIndex(pos_elm_tuple, 1))); + } + bundle_add_str(reply, "command", "ne_chunk"); + bundle_add_str_array(reply, "return_tag", s_tag, len); + bundle_add_str_array(reply, "return_token", s_token, len); + dlog_print(DLOG_INFO, LOG_TAG, "ne_chunk process done"); + } + break; + case 4: + { + char *buf[1] = {NULL,}; + buf[0] = (char*)malloc(128*sizeof(char)); + args = nltk_makeArgsFromString(info); + lm_module = nltk_getFunctionHandle(globe_lemm,"WordNetLemmatizer"); + lm_object = nltk_callFunctionWithArgs(lm_module, NULL); + lm_module = nltk_getFunctionHandle(lm_object, "lemmatize"); + lm_result = nltk_callFunctionWithArgs(lm_module, args); + strcpy(buf[0] , nltk_getStringFromElement(lm_result)); + bundle_add_str(reply, "command", "lemmatize"); + bundle_add_str_array(reply, "return_token", buf, 1); + dlog_print(DLOG_INFO, LOG_TAG, "lemmatize process done"); + } + break; + case 5: + { + char *buf[1] = {NULL,}; + buf[0] = (char*)malloc(128*sizeof(char)); + args = nltk_makeArgsFromString(info); + ld_module = nltk_getFunctionHandle(globe_lang,"detect"); + ld_result = nltk_callFunctionWithArgs(ld_module, args); + strcpy(buf[0] , nltk_getStringFromElement(ld_result)); + bundle_add_str(reply, "command", "langdetect"); + bundle_add_str_array(reply, "return_token", buf, 1); + dlog_print(DLOG_INFO, LOG_TAG, "langdetect process done"); + } + break; + default: + bundle_add_str(reply, "command", "Exception happens"); + break; + } + int ret = message_port_send_message(remote_app_id, remote_port, reply ); + if (ret != MESSAGE_PORT_ERROR_NONE) { + dlog_print(DLOG_INFO, LOG_TAG, "Port send message error: %d", ret); + } else + { + dlog_print(DLOG_INFO, LOG_TAG, "service send message to client: %s", remote_port); + } + bundle_free(reply); + dlog_print(DLOG_INFO, LOG_TAG, "bundle released"); +} + + +bool service_app_create(void *data) +{ + // Todo: add your code here. + int port_id = message_port_register_local_port("6666", message_port_cb, NULL); + if (port_id < 0) + { + dlog_print(DLOG_INFO, LOG_TAG, "NLTK ####Port register error: %d", port_id); + } + else + { + dlog_print(DLOG_INFO, LOG_TAG, "NLTK ####Port register success: %d", port_id); + nltk_initialize(); + globe_nltk = nltk_getModule("nltk"); + dlog_print(DLOG_INFO, LOG_TAG, "nltk library loaded success: "); + globe_lemm = nltk_getModule("nltk.stem"); + dlog_print(DLOG_INFO, LOG_TAG, "nltk stem library loaded success: "); + globe_lang = nltk_getModule("langdetect"); + dlog_print(DLOG_INFO, LOG_TAG, "langdetect library loaded success: "); + } + + return true; +} + +void service_app_terminate(void *data) +{ + // Todo: add your code here. + nltk_finalize(); + return; +} + +void service_app_control(app_control_h app_control, void *data) +{ + // Todo: add your code here. + return; +} + +static void +service_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LANGUAGE_CHANGED*/ + return; +} + +static void +service_app_region_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_REGION_FORMAT_CHANGED*/ +} + +static void +service_app_low_battery(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_BATTERY*/ +} + +static void +service_app_low_memory(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_MEMORY*/ +} + + +int main(int argc, char* argv[]) +{ + char ad[50] = {0,}; + service_app_lifecycle_callback_s event_callback; + app_event_handler_h handlers[5] = {NULL, }; + + event_callback.create = service_app_create; + event_callback.terminate = service_app_terminate; + event_callback.app_control = service_app_control; + service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad); + + return service_app_main(argc, argv, &event_callback, ad); +} + +void nltk_initialize() +{ + Py_Initialize(); +} + +void nltk_finalize() +{ + Py_Finalize(); +} + +PyObject* nltk_getModule(char* m_name) +{ + return PyImport_ImportModuleNoBlock(m_name); +} + +int nltk_getSizeFromList(PyObject* list) +{ + if PyList_Check(list) + { + return PyList_Size(list); + } + else + { + return -1; + } +} + +int nltk_getSizeFromTuple(PyObject* tuple) +{ + if PyTuple_Check(tuple) + { + return PyTuple_Size(tuple); + } + else + { + return -1; + } +} + +PyObject* nltk_getElementFromListByIndex(PyObject* list, int index) +{ + PyObject* element; + if PyList_Check(list) + { + if (index > (PyList_Size(list)-1) || (index < 0 )) + { + element = NULL; + } + else + { + PyObject *item = PyList_GetItem(list, index); + element = item; + } + } + else + { + element = NULL; + } + return element; +} + +char* nltk_getStringFromListElement(PyObject* elm) +{ + return PyString_AsString(elm); +} + +PyObject* nltk_getElementFromTupleByIndex(PyObject* tuple, int index) +{ + PyObject* element; + if PyTuple_Check(tuple) + { + if (index > (PyTuple_Size(tuple)-1) || (index < 0 )) + { + element = NULL; + } + else + { + PyObject *item = PyTuple_GetItem(tuple, index); + element = item; + } + } + else + { + element = NULL; + } + return element; +} + +char* nltk_getStringFromElement(PyObject* elm) +{ + char* ch = (char*) malloc(255); + strcpy(ch, PyString_AsString(elm)); + return ch; +} + +PyObject* nltk_getFunctionHandle(PyObject* m_module, char * f_name) +{ + return PyObject_GetAttrString(m_module, f_name); +} + +PyObject* nltk_makeArgsFromString(char* info) +{ + PyObject *pArgs; + //create args tuple struct to fill the arg one by one ,here , only create one string with 1 + pArgs = PyTuple_New(1); + PyTuple_SetItem(pArgs, 0, PyString_FromString(info)); + return pArgs; +} + +PyObject* nltk_makeArgsFromPyObject(PyObject* pyobj) +{ + PyObject *pArgs; + //create args tuple struct to fill the arg one by one ,here ,only create one python object with 1 + pArgs = PyTuple_New(1); + //set a string for item 0 of tuple + PyTuple_SetItem(pArgs, 0, pyobj); + return pArgs; +} + +PyObject* nltk_callFunctionWithArgs(PyObject* m_func, PyObject* args) +{ + return PyObject_CallObject(m_func, args); +} + +// This is an example of an method to get attribute of module. +char* nltk_getattrib(int z) +{ + PyObject *pModule, *pFunc; + PyObject *pArgs; + char* ch = (char*) malloc(255); + if (ch != NULL) + { + pModule = PyImport_ImportModule("site"); + if (pModule != NULL) + { + //create args tuple struct to fill the arg one by one ,here ,only create one param with 1 + pArgs = PyTuple_New(1); + //set a string for item 0 of tuple + PyTuple_SetItem(pArgs, 0, PyString_FromString("Hello World")); + //call word_tokenize func with args + pFunc = PyObject_GetAttrString(pModule, "USER_SITE"); + if (pFunc != NULL) { + strcpy(ch, PyString_AsString(pFunc)); + } else { + strcpy(ch, "attribute get error\n"); + } + } else { + strcpy(ch, "nltk module import error\n"); + } + return ch; + } + else + { + return NULL; + } +} +