This is an automated email from the git hooks/post-receive script. New change to branch develop in repository coselmar. See http://git.forge.codelutin.com/coselmar.git from 9e65d6f remove non wanted annotation new bd2a079 move CloudWord class to persistence module new d84fffe refs-60 #7974 Add service with *postgresql* request to get top words from project and associated documents new e496b61 refs-90 #7974 Add words cloud on project page new 097bc5f Merge branch 'feature/7974-cloud-tag-on-project' into develop The 4 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 097bc5fa8f56615d80d68080467d61902c800781 Merge: 9e65d6f e496b61 Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 17:44:47 2016 +0100 Merge branch 'feature/7974-cloud-tag-on-project' into develop commit e496b6125047a37c3a62ee573740ab434ae528ba Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 17:44:39 2016 +0100 refs-90 #7974 Add words cloud on project page commit d84fffe330a8261abfe8f1d7f7cd4d9c8b33813b Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 17:25:37 2016 +0100 refs-60 #7974 Add service with *postgresql* request to get top words from project and associated documents commit bd2a079b03e947abad43168e2f55856a7864e9eb Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 15:34:03 2016 +0100 move CloudWord class to persistence module Summary of changes: .../java/fr/ifremer/coselmar/beans/CloudWord.java | 0 .../coselmar/config/CoselmarServicesConfig.java | 7 +++ .../persistence/entity/QuestionTopiaDao.java | 63 ++++++++++++++++++++++ ...ts.sql => V1_5_0_1__7974_add_pg_dictionary.sql} | 22 ++++---- .../coselmar/services/v1/QuestionsWebService.java | 29 ++++++++++ coselmar-rest/src/main/resources/mapping | 1 + coselmar-ui/src/main/webapp/i18n/en.js | 1 + coselmar-ui/src/main/webapp/i18n/fr.js | 1 + .../src/main/webapp/js/coselmar-controllers.js | 14 +++++ .../main/webapp/js/coselmar-questions-services.js | 8 +++ .../main/webapp/views/questions/viewquestion.html | 9 ++++ 11 files changed, 143 insertions(+), 12 deletions(-) rename {coselmar-rest => coselmar-persistence}/src/main/java/fr/ifremer/coselmar/beans/CloudWord.java (100%) copy coselmar-persistence/src/main/resources/db/migration/{V1_2_0_1__7867_add_list_links_in_projects.sql => V1_5_0_1__7974_add_pg_dictionary.sql} (67%) -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.forge.codelutin.com/coselmar.git commit bd2a079b03e947abad43168e2f55856a7864e9eb Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 15:34:03 2016 +0100 move CloudWord class to persistence module --- .../src/main/java/fr/ifremer/coselmar/beans/CloudWord.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/CloudWord.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/CloudWord.java similarity index 100% rename from coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/CloudWord.java rename to coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/CloudWord.java -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.forge.codelutin.com/coselmar.git commit d84fffe330a8261abfe8f1d7f7cd4d9c8b33813b Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 17:25:37 2016 +0100 refs-60 #7974 Add service with *postgresql* request to get top words from project and associated documents --- .../coselmar/config/CoselmarServicesConfig.java | 7 +++ .../persistence/entity/QuestionTopiaDao.java | 63 ++++++++++++++++++++++ .../migration/V1_5_0_1__7974_add_pg_dictionary.sql | 32 +++++++++++ .../coselmar/services/v1/QuestionsWebService.java | 29 ++++++++++ coselmar-rest/src/main/resources/mapping | 1 + 5 files changed, 132 insertions(+) diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/config/CoselmarServicesConfig.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/config/CoselmarServicesConfig.java index 8e72e04..9cde4b3 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/config/CoselmarServicesConfig.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/config/CoselmarServicesConfig.java @@ -37,6 +37,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.config.ApplicationConfig; import org.nuiton.config.ArgumentsParserException; +import org.nuiton.topia.persistence.TopiaApplicationContext; +import org.nuiton.topia.persistence.TopiaConfiguration; /** * @author ymartel <martel@codelutin.com> @@ -162,4 +164,9 @@ public class CoselmarServicesConfig { public String getVersion() { return applicationConfig.getOption(CoselmarServicesConfigOption.APPLICATION_VERSION.key); } + + public boolean isPostgresqlDatabase() { + String hibernateDriverClass = applicationConfig.getOption("hibernate.connection.driver_class"); + return hibernateDriverClass.toLowerCase().contains("postgresql"); + } } diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java index 0074d88..8c66d18 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java @@ -24,14 +24,20 @@ package fr.ifremer.coselmar.persistence.entity; * #L% */ +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; +import fr.ifremer.coselmar.beans.CloudWord; import fr.ifremer.coselmar.beans.QuestionSearchExample; import fr.ifremer.coselmar.persistence.DaoUtils; import org.apache.commons.lang3.StringUtils; import org.nuiton.topia.persistence.TopiaQueryBuilderAddCriteriaOrRunQueryStep; +import org.nuiton.topia.persistence.support.TopiaSqlQuery; import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; @@ -239,6 +245,15 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { return values; } + public List<CloudWord> findTopWords(String questionId) { + + forTopiaIdEquals(questionId).findAny(); + + List<CloudWord> values = topiaSqlSupport.findMultipleResult(new QuestionTermStatSqlQuery(questionId)); + + return values; + } + public String refineSearch(QuestionSearchExample searchExample, String alias, Map args) { StringBuilder finerHqlBuilder = new StringBuilder(" 1=1 "); @@ -349,4 +364,52 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { return finerHql; } + private static class QuestionTermStatSqlQuery extends TopiaSqlQuery<CloudWord> { + + private final String sql; + + private final String getSql(String questionId) { + return "SELECT word, nentry FROM ts_stat( ' select to_tsvector(''public.simple_english_conf'', q.title)" + + " || to_tsvector(''public.simple_english_conf'', q.summary)" + + " || to_tsvector(''public.simple_english_conf'', qt.theme)" + + " || COALESCE(to_tsvector(''public.simple_english_conf'', d.name),'''')" + + " || COALESCE(to_tsvector(''public.simple_english_conf'', dk.keywords),'''')" + + " || COALESCE(to_tsvector(''public.simple_english_conf'', d.summary),'''') FROM question q" + + " LEFT JOIN relateddocuments_relatedquestion ON" + + " relateddocuments_relatedquestion.relatedquestion = q.topiaid" + + " LEFT JOIN closingdocuments_relatedquestion ON" + + " closingdocuments_relatedquestion.relatedquestion = q.topiaid" + + " LEFT JOIN document d on" + + " d.topiaid = closingdocuments_relatedquestion.closingdocuments OR" + + " d.topiaid = relateddocuments_relatedquestion.relateddocuments" + + " LEFT JOIN question_theme qt ON" + + " qt.owner = q.topiaid" + + " LEFT JOIN document_keywords dk ON" + + " dk.owner = d.topiaid" + + " WHERE q.topiaid = ''" + questionId + "''" + + " ')" + + " WHERE char_length(word) > 3 " + + " ORDER BY nentry DESC " + + " LIMIT 30"; + } + + QuestionTermStatSqlQuery(String questionId) { + this.sql = getSql(questionId); + } + + @Override + public PreparedStatement prepareQuery(Connection connection) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement(sql); + return preparedStatement; + } + + @Override + public CloudWord prepareResult(ResultSet set) throws SQLException { + + CloudWord cloudWord = new CloudWord(set.getString(1), set.getLong(2)); + + return cloudWord; + + } + } } //QuestionTopiaDao diff --git a/coselmar-persistence/src/main/resources/db/migration/V1_5_0_1__7974_add_pg_dictionary.sql b/coselmar-persistence/src/main/resources/db/migration/V1_5_0_1__7974_add_pg_dictionary.sql new file mode 100644 index 0000000..2c1890d --- /dev/null +++ b/coselmar-persistence/src/main/resources/db/migration/V1_5_0_1__7974_add_pg_dictionary.sql @@ -0,0 +1,32 @@ +--- +-- #%L +-- Coselmar :: Persistence +-- %% +-- Copyright (C) 2014 - 2016 Ifremer, Code Lutin +-- %% +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as +-- published by the Free Software Foundation, either version 3 of the +-- License, or (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public +-- License along with this program. If not, see +-- <http://www.gnu.org/licenses/gpl-3.0.html>. +-- #L% +--- + +CREATE TEXT SEARCH DICTIONARY public.simple_english_dict ( + TEMPLATE = pg_catalog.simple, + STOPWORDS = english +); + +CREATE TEXT SEARCH CONFIGURATION public.simple_english_conf ( COPY = pg_catalog.english ); + +ALTER TEXT SEARCH CONFIGURATION simple_english_conf + ALTER MAPPING FOR asciiword, asciihword, hword_asciipart, word, hword, hword_part + WITH simple_english_dict; diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java index 7a8eaab..d4491f0 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java @@ -38,6 +38,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import fr.ifremer.coselmar.beans.CloudWord; import fr.ifremer.coselmar.beans.DocumentBean; import fr.ifremer.coselmar.beans.LinkBean; import fr.ifremer.coselmar.beans.QuestionBean; @@ -62,6 +63,7 @@ import fr.ifremer.coselmar.persistence.entity.QuestionImpl; import fr.ifremer.coselmar.persistence.entity.Status; import fr.ifremer.coselmar.services.CoselmarWebServiceSupport; import fr.ifremer.coselmar.services.errors.InvalidCredentialException; +import fr.ifremer.coselmar.services.errors.NoResultException; import fr.ifremer.coselmar.services.errors.UnauthorizedException; import fr.ifremer.coselmar.services.indexation.QuestionsIndexationService; import org.apache.commons.io.IOUtils; @@ -1078,6 +1080,33 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { } + public List<CloudWord> getTopWords(String questionId) throws InvalidCredentialException, UnauthorizedException, NoResultException { + + // Check authentication + String authorization = getContext().getHeader("Authorization"); + UserWebToken userWebToken = checkAuthentication(authorization); + + // Check current user + String fullCurrentUserId = getFullUserIdFromShort(userWebToken.getUserId()); + getCoselmarUserDao().forTopiaIdEquals(fullCurrentUserId).findAny(); + + List<CloudWord> topWords; + if (getCoselmarServicesConfig().isPostgresqlDatabase()) { + try { + topWords = getQuestionDao().findTopWords(getFullIdFromShort(Question.class, questionId)); + } catch (TopiaNoResultException e) { + if (log.isErrorEnabled()) { + log.error("Try to find top words for non existing questionId" + questionId, e); + } + throw new NoResultException("Question does not exist"); + } + } else { + topWords = Collections.EMPTY_LIST; + } + + return topWords; + } + //////////////////////////////////////////////////////////////////////////// /////////////////////// Internal Parts ///////////////////////////// //////////////////////////////////////////////////////////////////////////// diff --git a/coselmar-rest/src/main/resources/mapping b/coselmar-rest/src/main/resources/mapping index 7c9ac1b..b498a97 100644 --- a/coselmar-rest/src/main/resources/mapping +++ b/coselmar-rest/src/main/resources/mapping @@ -70,6 +70,7 @@ POST /v1/questions QuestionsWebService.addQuestion DELETE /v1/questions/{questionId} QuestionsWebService.deleteQuestion GET /v1/questions/{questionId}/ancestors QuestionsWebService.getAncestors depth=2 GET /v1/questions/{questionId}/descendants QuestionsWebService.getDescendants depth=2 +GET /v1/questions/{questionId}/topwords QuestionsWebService.getTopWords # Transverse Api -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.forge.codelutin.com/coselmar.git commit e496b6125047a37c3a62ee573740ab434ae528ba Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 17:44:39 2016 +0100 refs-90 #7974 Add words cloud on project page --- coselmar-ui/src/main/webapp/i18n/en.js | 1 + coselmar-ui/src/main/webapp/i18n/fr.js | 1 + coselmar-ui/src/main/webapp/js/coselmar-controllers.js | 14 ++++++++++++++ .../src/main/webapp/js/coselmar-questions-services.js | 8 ++++++++ .../src/main/webapp/views/questions/viewquestion.html | 9 +++++++++ 5 files changed, 33 insertions(+) diff --git a/coselmar-ui/src/main/webapp/i18n/en.js b/coselmar-ui/src/main/webapp/i18n/en.js index 1b4f6e3..0d6afcc 100644 --- a/coselmar-ui/src/main/webapp/i18n/en.js +++ b/coselmar-ui/src/main/webapp/i18n/en.js @@ -357,6 +357,7 @@ var translateEN = { </p>", "home.lastProjects" : "Last projects", "home.wordCloud" : "Most used words in the platform", +"project.wordCloud" : "Most used words on the project", "error.message.authentication.title" : "Error with authentication", "error.message.authentication.body" : "Error with authentication, please try to log again.", diff --git a/coselmar-ui/src/main/webapp/i18n/fr.js b/coselmar-ui/src/main/webapp/i18n/fr.js index 4be7333..88f8f0f 100644 --- a/coselmar-ui/src/main/webapp/i18n/fr.js +++ b/coselmar-ui/src/main/webapp/i18n/fr.js @@ -359,6 +359,7 @@ var translateFR = { </p>", "home.lastProjects" : "Derniers projets", "home.wordCloud" : "Mots les plus courants sur la plateforme", +"project.wordCloud" : "Mots les plus courants autour du projet", "error.message.authentication.title" : "Échec d'authentification", "error.message.authentication.body" : "Une erreur avec l'authentification est survenue, veuillez vous reconnecter svp.", diff --git a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js index b77ebf4..567d35d 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js @@ -1239,6 +1239,9 @@ coselmarControllers.controller("QuestionCtrl", ['$scope', '$route', '$routeParam 'clients' : [], 'relatedDocuments': [], 'newRelatedDocuments' : [], 'links' : []}; $scope.existing = {'types' : [], 'themes' : []}; + $scope.topWords = [{text:"coselmar", weight: 10}, {text: "Ifremer", weight: 5}]; + //FIXME Leo #CSS si tu veux trouver de belles couleurs pour le nuage, c'est là :) + $scope.cloudColors = []; // Preload exiting types and themes questionsService.findAllTypes(function(results) { @@ -1376,6 +1379,17 @@ coselmarControllers.controller("QuestionCtrl", ['$scope', '$route', '$routeParam }, errorService.defaultFailOnCall, function() { $scope.$emit('dataLoaded'); }); + + + questionsService.getTopWords($routeParams.questionId, function(result) { + $scope.topWords = result.data; + for (var i=0; i < $scope.topWords.length; i++) { + $scope.topWords[i].link = "#/referential?onDocuments&onQuestions&keywords=" + $scope.topWords[i].text; + } + }, function(fail) { + $scope.topWords = []; + }); + }; //Deletion diff --git a/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js b/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js index f0d0de1..e3f0613 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js @@ -176,4 +176,12 @@ function Question(resource, http, config){ questionResource.query().$promise.then(successFunction); }; + this.getTopWords = function(questionId, successFunction, failFunction) { + + var topWordsUrl = baseURL + "/" + questionId + "/topwords"; + + http.get(topWordsUrl).then(successFunction, failFunction); + + }; + }; \ No newline at end of file diff --git a/coselmar-ui/src/main/webapp/views/questions/viewquestion.html b/coselmar-ui/src/main/webapp/views/questions/viewquestion.html index cddf909..81f1c4b 100644 --- a/coselmar-ui/src/main/webapp/views/questions/viewquestion.html +++ b/coselmar-ui/src/main/webapp/views/questions/viewquestion.html @@ -145,6 +145,15 @@ <div class="form-group col-md-4 aside"> <div> + <!-- FIXME Leo #CSS --> + <dl class="cloud"> + <dt class="title">{{ "project.wordCloud" | translate }}</dt> + <dd> + <jqcloud words="topWords" width="350" height="150" + colors="{{cloudColors}}" + steps="21" font-size="{from:0.09, to:0.04}"></jqcloud> + </dd> + </dl> <dl> <dt>{{ 'question.metadata.privacy' | translate }}</dt> <dd>{{question.privacy | lowercase}}</dd> -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.forge.codelutin.com/coselmar.git commit 097bc5fa8f56615d80d68080467d61902c800781 Merge: 9e65d6f e496b61 Author: Yannick Martel <martel@©odelutin.com> Date: Tue Feb 16 17:44:47 2016 +0100 Merge branch 'feature/7974-cloud-tag-on-project' into develop .../java/fr/ifremer/coselmar/beans/CloudWord.java | 0 .../coselmar/config/CoselmarServicesConfig.java | 7 +++ .../persistence/entity/QuestionTopiaDao.java | 63 ++++++++++++++++++++++ .../migration/V1_5_0_1__7974_add_pg_dictionary.sql | 32 +++++++++++ .../coselmar/services/v1/QuestionsWebService.java | 29 ++++++++++ coselmar-rest/src/main/resources/mapping | 1 + coselmar-ui/src/main/webapp/i18n/en.js | 1 + coselmar-ui/src/main/webapp/i18n/fr.js | 1 + .../src/main/webapp/js/coselmar-controllers.js | 14 +++++ .../main/webapp/js/coselmar-questions-services.js | 8 +++ .../main/webapp/views/questions/viewquestion.html | 9 ++++ 11 files changed, 165 insertions(+) -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
participants (1)
-
codelutin.com scm