Upload the nlp daemon 20/183820/5
authorXie Ligang <ligang0.xie@samsung.com>
Wed, 11 Jul 2018 08:21:10 +0000 (16:21 +0800)
committerXie Ligang <ligang0.xie@samsung.com>
Fri, 13 Jul 2018 09:04:35 +0000 (17:04 +0800)
Change-Id: Iccf4c453e82c8fc6a894a07df37ab87967003b1d
Signed-off-by: Xie Ligang <ligang0.xie@samsung.com>
CMakeLists.txt
packaging/nlp.spec
service/CMakeLists.txt [new file with mode: 0644]
service/inc/service.h [new file with mode: 0644]
service/org.tizen.nlp.service.manifest [new file with mode: 0644]
service/org.tizen.nlp.service.xml [new file with mode: 0644]
service/shared/res/service.png [new file with mode: 0644]
service/src/service.c [new file with mode: 0644]

index 28cc708635a27e1adb9f828ba9622860858745a4..5fb9567739d02fdb6bbb20a6c0177257440ee040 100755 (executable)
@@ -1,3 +1,5 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
 ADD_SUBDIRECTORY(client)
+
+ADD_SUBDIRECTORY(service)
index 4c63b210ceeb90cd3657d8e58c2f201ff7f98288..5564c1f527c6335b1642e97a2415088ed5169f93 100755 (executable)
@@ -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 (file)
index 0000000..f105f4e
--- /dev/null
@@ -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 (file)
index 0000000..f2f234d
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __service_H__
+#define __service_H__
+
+#include <dlog.h>
+#include <Python.h>
+
+#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 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/service/org.tizen.nlp.service.xml b/service/org.tizen.nlp.service.xml
new file mode 100644 (file)
index 0000000..3b046c7
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="4.0" package="org.tizen.nlp.service" version="1.0.0">
+    <profile name="mobile"/>
+    <service-application appid="org.tizen.nlp.service" auto-restart="true" exec="/usr/apps/org.tizen.nlp.service/bin/org.tizen.nlp.service" multiple="false" nodisplay="true" on-boot="true" type="capp">
+        <label>service</label>
+        <icon>service.png</icon>
+    </service-application>
+</manifest>
diff --git a/service/shared/res/service.png b/service/shared/res/service.png
new file mode 100644 (file)
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 (file)
index 0000000..9109f63
--- /dev/null
@@ -0,0 +1,394 @@
+#include <tizen.h>
+#include <message_port.h>
+#include <dlfcn.h>
+#include <service_app.h>
+#include "service.h"
+#include <dlog.h>
+
+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;
+    }
+}
+