diff --git a/Makefile b/Makefile index 868d8fb..a78b479 100644 --- a/Makefile +++ b/Makefile @@ -22,19 +22,26 @@ VERSION = 0.2 CFLAGS =\ -I$(INCDIR)\ - `python-config --cflags` + -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 -I/usr/local/include\ + -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector\ + --param=ssp-buffer-size=4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O2 -Wall LDFLAGS =\ `python-config --ldflags`\ - -lX11 + -lX11\ + -lcurl\ + -llavid_base\ + -llavid_io -HEADERS = \ +HEADERS =\ py_tradutor.h\ - core_plugin.h + core_plugin.h\ + property.h SOURCES = \ $(SRCDIR)/py_tradutor.cpp\ - $(SRCDIR)/core_plugin.cpp + $(SRCDIR)/core_plugin.cpp\ + $(SRCDIR)/property.cpp .SUFFIXES: .cpp .o .h diff --git a/Makefile.build b/Makefile.build index ae13822..0414b4a 100644 --- a/Makefile.build +++ b/Makefile.build @@ -6,9 +6,10 @@ all: shared shared: @mkdir $(PLUGINDIR) > /dev/null 2>&1 && \ echo "Create directory $(PLUGINDIR)... $(OK)" || echo -n "" + @echo -n Compiling $(LIB) ... + @$(CXX) -shared -fPIC $(CFLAGS) $(SOURCES) -o $(PLUGINDIR)/$(LIB) $(LDFLAGS) &&\ + echo " $(OK)" || (echo " $(FAILED)"; exit 1;) @echo -n Linking $(LIB) ... - @$(CXX) -shared -fPIC $(CFLAGS) $(SOURCES) $(LDFLAGS) -o $(PLUGINDIR)/$(LIB) || \ - (echo " $(FAILED)"; exit 1;) @cd $(PLUGINDIR); \ ln -f -s $(LIB) lib$(LIBNAME).so; \ cd .. && echo " $(OK)" || (echo " $(FAILED)"; exit 1;) @@ -17,3 +18,8 @@ clean: @echo -n Cleaning... @rm -rf $(addprefix $(SRCDIR),$(OBJS)) $(PLUGINDIR) 2> /dev/null && \ echo " $(OK)" || (echo " $(FAILED)"; exit 1;) + +vlibras_test: + @echo -n Compiling source test file... + @$(CXX) $(CFLAGS) $(SOURCES) $(TESTSDIR)/main.cpp $(LDFLAGS) -o $(TESTSDIR)/vlibras_test && \ + echo " $(OK)" || (echo " $(FAILED)"; exit 1;) \ No newline at end of file diff --git a/Makefile.top b/Makefile.top index 5401f13..dd02600 100644 --- a/Makefile.top +++ b/Makefile.top @@ -5,7 +5,7 @@ CXX = g++ INCDIR = ./include SRCDIR = ./src -TESTSDIR = ./tests +TESTSDIR = ./test PLUGINDIR = ./plugin DOCDIR = ./doc diff --git a/config/vlibras.conf b/config/vlibras.conf new file mode 100644 index 0000000..20f80e1 --- /dev/null +++ b/config/vlibras.conf @@ -0,0 +1 @@ +endpoint_update=http://vlibras.lavid.ufpb.br/api/dicionario/ diff --git a/include/core_plugin.h b/include/core_plugin.h index 7e31c15..6eae61d 100644 --- a/include/core_plugin.h +++ b/include/core_plugin.h @@ -17,17 +17,47 @@ #define COREPLUGIN_H_ #include -#include +#include +#include +#include +#include +#include +#include +#include +#include + +// install libjson +// sudo apt-get install libjson0 libjson0-dev + #include "py_tradutor.h" +#include "property.h" + +#define SCRIPT_UPDATE_VLIBRAS "gksudo -m \"Para continuar, você precisa se autenticar.\" \"gnome-terminal --hide-menubar -x bash -c '/./opt/vlibras_desktop/script/update_vlibras.sh;'\"" +#define SCRIPT_UPDATE_DICT "gksudo -m \"Para continuar, você precisa se autenticar.\" \"gnome-terminal --hide-menubar -x bash -c '/./opt/vlibras_desktop/script/update_dict.sh;'\"" +#define SCRIPT_INSTALL_DICT "gksudo -m \"Para continuar, você precisa se autenticar.\" \"gnome-terminal --hide-menubar -x bash -c '/./opt/vlibras_desktop/script/dict_install.sh;'\"" + + +// TODO +#define FILEPATH_CONFIG "config/vlibras.conf" + +// TODO +#define ENDPOINT_UPDATE_ID "endpoint_update" + +// TODO +#define DIC_PACKAGE "dicionario-vlibras" + +// TODO +#define APP_PACKAGE "vlibras-desktop" #define MAX_BUFFER_SELECTION 1024 - #define REPLACE_CHARACTERS "\r\n" +#define REPLACE_CHARACTERS "\r\n" #ifdef __cplusplus extern "C" { #endif - PyTradutor *tradutor; + //PyTradutor *tradutor; + //int app_current_version, dict_current_version; /** \brief Inicializa o ambiente core * @@ -53,8 +83,77 @@ extern "C" { */ int coreFinalize(); + + /** \brief ? + * + * \return ? + */ + int coreUpdateInstall_player(); + + + /** \brief ? + * + * \return ? + */ + int coreUpdateInstall_dict(); + + + /** \brief ? + * + * \return ? + */ + int coreUpdateCheck(); + + + /** \brief ? + * + * \return ? + */ char * get_text_selection(); - void remove_special_chars(std::string *_word, std::string _chars); + + + /** \brief ? + * + * \return ? + */ + void remove_special_chars(std::string *_word, std::string _chars, char* new_char); + + + /** \brief ? + * + * \return ? + */ + static size_t writeDataCallback( + char *contents, size_t size, size_t nmemb, std::string *writer_data); + + + /** \brief ? + * + * \return ? + */ + std::string request_current_versions(); + + + /** \brief ? + * + * \return ? + */ + int get_version_from_json(std::string json_message, std::string _key); + + + /** \brief ? + * + * \return ? + */ + int get_installed_version_deb_package(std::string _package_id); + + + /** \brief ? + * + * \return ? + */ + int get_version_from_string(std::string json_message, std::string _key); + #ifdef __cplusplus } diff --git a/include/property.h b/include/property.h new file mode 100644 index 0000000..eaa385c --- /dev/null +++ b/include/property.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Universidade Federal da Paraíba * + * Copyright (C) 2013 by Laboratório de Aplicações de Vídeo Digital * + * * + * Centro de Informática - UFPB - Campus I * + * João Pessoa - PB - Brasil * + * * + * Author: Leonardo de Araújo Domingues (leonardo.araujo@lavid.ufpb.br) * + * Date: Qui Nov 28 14:05:39 BRT 2013 * + * * + **************************************************************************/ + + #ifndef PROPERTYHANDLER_H + #define PROPERTYHANDLER_H + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + using namespace lavidlib; + + namespace util { + + class PropertyHandler { + + public: + PropertyHandler(std::string filename); + virtual ~PropertyHandler(); + std::string getAttributeValue(std::string attr); + + private: + BufferedReader* rbuffer; + FileIO* file_property; + int checkFileExtension(std::string &filename); + + }; + + } + + #endif /* PROPERTYHANDLER_H */ \ No newline at end of file diff --git a/script/depends_vlibras.sh b/script/depends_vlibras.sh new file mode 100644 index 0000000..6d4bbcb --- /dev/null +++ b/script/depends_vlibras.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +sudo apt-get install libcurl4-openssl-dev gksu libjsoncpp-dev \ No newline at end of file diff --git a/script/update_vlibras.sh b/script/update_vlibras.sh new file mode 100755 index 0000000..6653f73 --- /dev/null +++ b/script/update_vlibras.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# +#-------------------- IMPORTANT ------------------------ +# -> To run this script you need to be a sudo user | +#------------------------------------------------------- + +# Update the list of repositories +apt-get update + +if [ $1 == "vlibras-desktop" ]; then + # Install the new version of vlibras-desktop + notify-send -u critical "O VLibras está sendo atualizado! Aguarde..." + #apt-get install --only-upgrade vlibras-desktop +else + if [ $1 == "dicionario-vlibras" ]; then + # Install the new version of dicionario-vlibras + notify-send -u critical "O Dicionário de sinais do VLibras está sendo atualizado..." + #apt-get install --only-upgrade dicionario-vlibras + fi +fi + +/./opt/vlibras_desktop/script/launcher.sh \ No newline at end of file diff --git a/src/core_plugin.cpp b/src/core_plugin.cpp index 9292a78..7f8e43a 100644 --- a/src/core_plugin.cpp +++ b/src/core_plugin.cpp @@ -16,7 +16,13 @@ #include "core_plugin.h" +/* Variables */ +PyTradutor *tradutor; +int app_current_version, dict_current_version; + + +/* Functions */ int coreInitialize() { @@ -24,27 +30,227 @@ int coreInitialize() return 1; } + const char* coreExecute() { return tradutor->convertStringToGlosa((const char*) get_text_selection()); } + int coreFinalize() { if (!tradutor) return -1; delete tradutor; - return 1; + return 1; +} + + +int coreUpdateInstall_player() +{ + system(SCRIPT_UPDATE_VLIBRAS); + return system("/./opt/vlibras_desktop/script/launcher.sh &"); } + -char * get_text_selection() +int coreUpdateInstall_dict() { + dict_current_version = get_installed_version_deb_package(DIC_PACKAGE); + if (dict_current_version == 0) + return system(SCRIPT_INSTALL_DICT); + return system(SCRIPT_UPDATE_DICT); +} - FILE *comm_file_p = popen("xsel -o ", "r"); - if (!comm_file_p) + +int coreUpdateCheck() +{ + app_current_version = get_installed_version_deb_package(APP_PACKAGE); + dict_current_version = get_installed_version_deb_package(DIC_PACKAGE); + + std::string response_api_str = request_current_versions().c_str(); + if (response_api_str.compare("null") == 0) + return -1; + + if (get_version_from_string(response_api_str, "playerVersion") > app_current_version) + return 1; + else + if (get_version_from_string(response_api_str, "dictionaryVersion") > dict_current_version) + return 2; + return 0; +} + + +int get_installed_version_deb_package(std::string _package_id) +{ + std::string _deb_package_name = "dpkg -s "; + _deb_package_name.append(_package_id); + + FILE *comm_file_p = popen(_deb_package_name.c_str(), "r"); + + char line_buff [MAX_BUFFER_SELECTION]; + std::string version_str = ""; + bool found_flag = false; + + if (comm_file_p == NULL) perror ("Error opening file"); + else + { + while ( ! feof (comm_file_p) ) + { + if ( fgets (line_buff , (int) sizeof(line_buff) , comm_file_p) == NULL ) break; + + version_str = (std::string) line_buff; + if ( version_str.find("Version:") != std::string::npos ) + { + found_flag = true; + break; + } + } + fclose (comm_file_p); + } + + if (!found_flag) return 0; + + char *line_version_ptr = strtok ((char*) version_str.c_str(), " "); + + if (line_version_ptr == NULL) { - return NULL; + printf("Version of the deb package is null!\n"); + return 0; } + + line_version_ptr = strtok (NULL, " "); + version_str = (std::string) line_version_ptr; + remove_special_chars(&version_str, ".", (char*) ""); + + printf("%s installed version: %s\n", _package_id.c_str(), version_str.c_str()); + + return atoi(version_str.c_str()); + +} + + + +int get_version_from_string(std::string json_message, std::string _key) +{ + int position = json_message.find(_key); + if (position == -1) + return position; + + std::string version_str_cpy = json_message.substr(position, json_message.find(",")); + + remove_special_chars(&version_str_cpy, ".\":,", (char*) ""); + char *tokens_ptr; + if ( version_str_cpy.find("_") != std::string::npos ) + { + tokens_ptr = strtok ((char*) version_str_cpy.c_str(), "_"); + if (tokens_ptr == NULL) + printf("[Error] Cannot handler the version of dictionary.\n"); + version_str_cpy = (std::string) tokens_ptr; + } + + tokens_ptr = strtok ((char*) version_str_cpy.c_str(), " "); + if (tokens_ptr == NULL) + { + printf("[Error] Cannot split string with versions.\n"); + return -1; + } + tokens_ptr = strtok (NULL, " "); + version_str_cpy = (std::string) tokens_ptr; + + return atoi(version_str_cpy.c_str()); +} + + +//@Deprecated +int get_version_from_json(std::string json_message, std::string _key) +{ + + return -1; + + /*//Code to JsonCpp + Json::Value parsed_from_str; + Json::Reader json_reader; + bool parsing_flag = json_reader.parse(json_message, parsed_from_str); + + if (!parsing_flag) + throw new RuntimeException("Cannot convert the json message to string."); + + std::string version_str = parsed_from_str[_key].asString(); + + // Check if the version of dictionary contains '_' token. + if ( version_str.find("_") != std::string::npos ) + { + char *tokens_ptr = strtok ((char*) version_str.c_str(), "_"); + if (tokens_ptr == NULL) + throw new RuntimeException("Cannot handler the version of dictionary."); + version_str = (std::string) tokens_ptr; + } + + remove_special_chars(&version_str, ".", (char*) ""); + return atoi(version_str.c_str()); + */ +} + + + +std::string request_current_versions() +{ + CURL *curl_ptr; + CURLcode curl_response; + std::string data_str; + + util::PropertyHandler *property_handler_ptr; + property_handler_ptr = new util::PropertyHandler((std::string) FILEPATH_CONFIG); + + curl_ptr = curl_easy_init(); + if(curl_ptr) + { + std::string url_endpoint = property_handler_ptr->getAttributeValue(ENDPOINT_UPDATE_ID); + + std::stringstream ss_convert; + ss_convert << dict_current_version; + url_endpoint.append(ss_convert.str()); + + if (url_endpoint.size() <= 0) + throw new RuntimeException("The URL for this Endpoint is not available on the file config."); + + curl_easy_setopt(curl_ptr, CURLOPT_URL, (char*) url_endpoint.c_str()); + curl_easy_setopt(curl_ptr, CURLOPT_WRITEFUNCTION, writeDataCallback); + curl_easy_setopt(curl_ptr, CURLOPT_WRITEDATA, (char*) &data_str); + + curl_response = curl_easy_perform(curl_ptr); + + if(curl_response != CURLE_OK) + { + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(curl_response)); + return "null"; + } + + /* always cleanup */ + curl_easy_cleanup(curl_ptr); + + } + return data_str; +} + + +static size_t writeDataCallback( + char *contents, size_t size, size_t nmemb, std::string *writer_data) +{ + if (writer_data == NULL) + return 0; + + writer_data->append(contents, (size * nmemb)); + return (size * nmemb); +} + + +char* get_text_selection() +{ + + FILE *comm_file_p = popen("xsel -o ", "r"); + char line_buff [MAX_BUFFER_SELECTION]; std::string line_str = ""; @@ -58,20 +264,20 @@ char * get_text_selection() } fclose (comm_file_p); } - remove_special_chars(&line_str, (std::string) REPLACE_CHARACTERS); + remove_special_chars(&line_str, (std::string) REPLACE_CHARACTERS, (char*) " "); return (char*) line_str.c_str(); } -void remove_special_chars(std::string *_word, std::string _chars) +void remove_special_chars(std::string *_word, std::string _chars, char* new_char) { int index = -1; - for (int i = 0; i < _chars.size(); i++) + for (int i = 0; i < (int) _chars.size(); i++) { - while ( (index = (int) _word->find(_chars[i])) != std::string::npos) + while ( (index = (int) _word->find(_chars[i])) != (int) std::string::npos) { - _word->replace(index, 1, " "); // remove chars replacing your position by " " + _word->replace(index, 1, new_char); } } } \ No newline at end of file diff --git a/src/property.cpp b/src/property.cpp new file mode 100644 index 0000000..fc1237d --- /dev/null +++ b/src/property.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Universidade Federal da Paraíba * + * Copyright (C) 2013 by Laboratório de Aplicações de Vídeo Digital * + * * + * Centro de Informática - UFPB - Campus I * + * João Pessoa - PB - Brasil * + * * + * Author: Leonardo de Araújo Domingues (leonardo.araujo@lavid.ufpb.br) * + * Date: Qui Nov 28 14:06:10 BRT 2013 * + * * + **************************************************************************/ + + #include "property.h" + + + namespace util { + + + PropertyHandler::PropertyHandler(std::string filename) { + try { + if (checkFileExtension(filename) != 1) + throw new RuntimeException("Format file not is recognized!"); + file_property = new FileIO(filename, FileIO::MODE_READ); + } catch (lavidlib::IOException &ex) { + printf("[FAILED] Cannot open file %s.\n%s\n", filename.c_str(), + ex.getMessage().c_str()); + } + } + + + PropertyHandler::~PropertyHandler() { + if (rbuffer) + delete rbuffer; + if (file_property) + delete file_property; + } + + + std::string PropertyHandler::getAttributeValue(std::string attr) { + + rbuffer = new BufferedReader(file_property); + std::string fline; + try { + int target_pos = -1, begin = 0; + std::string attr_t, value_t; + + while((fline = rbuffer->readLine()).size() > 0) { + target_pos = fline.find("="); + if (target_pos < 2) + throw new RuntimeException("The assignment symbol was not found."); + + attr_t = fline.substr(begin, target_pos); + begin = target_pos+1; + value_t = fline.substr(begin, fline.size()); + if (attr.compare(attr_t) == 0) { + file_property->seek(0); + return value_t; + } + target_pos = -1; + begin = 0; + } + } catch (lavidlib::EOFException &ex) { + printf("[INFO] File is completed.\n%s\n", ex.getMessage().c_str()); + } + file_property->seek(0); + //FIXME: throw new exception + return fline; + } + + #define EXTENSION ".conf" + + int PropertyHandler::checkFileExtension(std::string &filename) { + + return (filename.find(EXTENSION) > 0 && + (filename.size() == (filename.find(EXTENSION) + strlen(EXTENSION)))) ? 1 : -1; + + } + + + } \ No newline at end of file diff --git a/test/main.cpp b/test/main.cpp index 628377b..96480ad 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -13,8 +13,7 @@ * \date Janeiro 2015 */ -#include -//#include +#include #include #include @@ -22,21 +21,46 @@ int main() { + + if (coreInitialize() != 1) + { + printf("Cannot initialize the CorePlugin.\n"); + exit(-1); + } + int result_check = coreUpdateCheck(); + switch (result_check) + { + case 0: + printf("The VLibras is up-to-date!\n"); + break; + case 1: + printf("The VLibras is outdated! Upgrading...\n"); + break; + case 2: + printf("Only the dictionary is outdated! Upgrading...\n"); + break; + case -1: + printf("Error!\n"); + break; + default: + printf("Option not found! Try again.\n"); + } + // Inicializa o tradutor - PyTradutor *tradutorTest; - tradutorTest = new PyTradutor(); + //PyTradutor *tradutorTest; + //tradutorTest = new PyTradutor(); // Pega o conteúdo do clipboard e salva em `pasteboardContent` //std::string pasteboardContent = Pasteboard::getGeneralContent(); // Traduz o conteúdo do clipboard em `pasteboardContent` para a string `traducao` - char* str = new char[10]; - strcpy(str, "o gato comeu o rato"); - std::string traducao = tradutorTest->convertStringToGlosa(str); + //char* str = new char[10]; + //strcpy(str, "o gato comeu o rato"); + //std::string traducao = tradutorTest->convertStringToGlosa(str); // [LOG] Exibe o conteudo do buffer de clipboard em `pasteboardContent` e traduz para glosa salvando seu resultado em `traducao` - std::cout << "[[ Conteudo em memoria ]]\n" << str << std::endl; - std::cout << "[[ Tradução ]]\n" << traducao << std::endl; + //std::cout << "[[ Conteudo em memoria ]]\n" << str << std::endl; + //std::cout << "[[ Tradução ]]\n" << traducao << std::endl; //std::cout << "\n##### ##### #####" << std::endl; @@ -49,5 +73,6 @@ int main() // Exclui o que foi utilizado // delete tradutorTest; + return 0; -} +} \ No newline at end of file -- libgit2 0.21.2