From fa0a3623692b86b2513ba2e73f0b8c8850147d59 Mon Sep 17 00:00:00 2001 From: John Shkarin Date: Wed, 8 Mar 2017 14:08:03 +0500 Subject: [PATCH] Guess Country Guess Country gh571_prediction_country add guess country fixes after merge fix query cleaning and return String check style check style fixes fixes fixes remarks style add try togglz for link SuggestionController add HasAuthority remarks rename remarks remarks fixes remarks remarks fixes --- src/main/java/ru/mystamps/web/Url.java | 5 +- .../web/config/ControllersConfig.java | 10 +++- .../web/controller/SuggestionController.java | 46 +++++++++++++++++++ .../java/ru/mystamps/web/dao/CountryDao.java | 3 ++ .../mystamps/web/dao/impl/JdbcCountryDao.java | 31 ++++++++++++- .../mystamps/web/service/CountryService.java | 2 + .../web/service/CountryServiceImpl.java | 14 +++++- .../spring/security/SecurityConfig.java | 1 + .../mystamps/web/support/togglz/Features.java | 6 ++- src/main/javascript/series/add.js | 21 ++++++++- .../liquibase/sql/test-add-series.sql | 18 ++++++++ .../ru/mystamps/i18n/Messages.properties | 1 + .../ru/mystamps/i18n/Messages_ru.properties | 1 + .../sql/country_dao_queries.properties | 14 ++++++ src/main/webapp/WEB-INF/views/series/add.html | 6 ++- 15 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 src/main/java/ru/mystamps/web/controller/SuggestionController.java create mode 100644 src/main/resources/liquibase/sql/test-add-series.sql diff --git a/src/main/java/ru/mystamps/web/Url.java b/src/main/java/ru/mystamps/web/Url.java index 66df10de7b..d8af9ae75a 100644 --- a/src/main/java/ru/mystamps/web/Url.java +++ b/src/main/java/ru/mystamps/web/Url.java @@ -52,6 +52,8 @@ public final class Url { public static final String ADD_IMAGE_SERIES_PAGE = "/series/{id}/image"; public static final String SEARCH_SERIES_BY_CATALOG = "/series/search/by_catalog"; + public static final String SUGGEST_SERIES_COUNTRY = "/suggest/series_country"; + public static final String ADD_CATEGORY_PAGE = "/category/add"; public static final String LIST_CATEGORIES_PAGE = "/category/list"; public static final String INFO_CATEGORY_PAGE = "/category/{slug}"; @@ -77,7 +79,7 @@ public final class Url { public static final String ADD_SERIES_WITH_COUNTRY_PAGE = "/series/add/country/{slug}"; // MUST be updated when any of our resources were modified - public static final String RESOURCES_VERSION = "v0.3.0"; + public static final String RESOURCES_VERSION = "v0.3.1"; // CheckStyle: ignore LineLength for next 4 lines public static final String MAIN_CSS = "/static/" + RESOURCES_VERSION + "/styles/main.min.css"; @@ -125,6 +127,7 @@ public static Map asMap(boolean serveContentFromSingleHost) { map.put("INFO_SERIES_PAGE", INFO_SERIES_PAGE); map.put("ADD_IMAGE_SERIES_PAGE", ADD_IMAGE_SERIES_PAGE); map.put("SEARCH_SERIES_BY_CATALOG", SEARCH_SERIES_BY_CATALOG); + map.put("SUGGEST_SERIES_COUNTRY", SUGGEST_SERIES_COUNTRY); map.put("ADD_CATEGORY_PAGE", ADD_CATEGORY_PAGE); map.put("INFO_CATEGORY_PAGE", INFO_CATEGORY_PAGE); map.put("LIST_CATEGORIES_PAGE", LIST_CATEGORIES_PAGE); diff --git a/src/main/java/ru/mystamps/web/config/ControllersConfig.java b/src/main/java/ru/mystamps/web/config/ControllersConfig.java index 382358d1e9..879972a985 100644 --- a/src/main/java/ru/mystamps/web/config/ControllersConfig.java +++ b/src/main/java/ru/mystamps/web/config/ControllersConfig.java @@ -110,5 +110,13 @@ public SiteController getSiteController() { public SitemapController getSitemapController() { return new SitemapController(servicesConfig.getSeriesService()); } - + + @Bean + public SuggestionController getSuggestionController() { + return new SuggestionController( + servicesConfig.getCountryService() + ); + } + } + diff --git a/src/main/java/ru/mystamps/web/controller/SuggestionController.java b/src/main/java/ru/mystamps/web/controller/SuggestionController.java new file mode 100644 index 0000000000..13e332e42b --- /dev/null +++ b/src/main/java/ru/mystamps/web/controller/SuggestionController.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009-2017 Slava Semushin + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package ru.mystamps.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import lombok.RequiredArgsConstructor; + +import ru.mystamps.web.Url; +import ru.mystamps.web.controller.converter.annotation.CurrentUser; +import ru.mystamps.web.service.CountryService; + +@Controller +@RequiredArgsConstructor +public class SuggestionController { + + private final CountryService countryService; + + /** + * @author John Shkarin + */ + @ResponseBody + @GetMapping(Url.SUGGEST_SERIES_COUNTRY) + public String suggestCountryForUser(@CurrentUser Integer currentUserId) { + return countryService.suggestCountryForUser(currentUserId); + } + +} + diff --git a/src/main/java/ru/mystamps/web/dao/CountryDao.java b/src/main/java/ru/mystamps/web/dao/CountryDao.java index 6f3718ba57..84930cc7b1 100644 --- a/src/main/java/ru/mystamps/web/dao/CountryDao.java +++ b/src/main/java/ru/mystamps/web/dao/CountryDao.java @@ -23,6 +23,7 @@ import ru.mystamps.web.dao.dto.AddCountryDbDto; import ru.mystamps.web.dao.dto.LinkEntityDto; +@SuppressWarnings("PMD.TooManyMethods") public interface CountryDao { Integer add(AddCountryDbDto country); long countAll(); @@ -35,4 +36,6 @@ public interface CountryDao { List getStatisticsOf(Integer collectionId, String lang); List findAllAsLinkEntities(String lang); LinkEntityDto findOneAsLinkEntity(String slug, String lang); + + String suggestCountryForUser(Integer userId); } diff --git a/src/main/java/ru/mystamps/web/dao/impl/JdbcCountryDao.java b/src/main/java/ru/mystamps/web/dao/impl/JdbcCountryDao.java index 1ed330b38d..7cb8f59f0d 100644 --- a/src/main/java/ru/mystamps/web/dao/impl/JdbcCountryDao.java +++ b/src/main/java/ru/mystamps/web/dao/impl/JdbcCountryDao.java @@ -39,7 +39,7 @@ import ru.mystamps.web.dao.dto.LinkEntityDto; @RequiredArgsConstructor -@SuppressWarnings("PMD.AvoidDuplicateLiterals") +@SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods"}) public class JdbcCountryDao implements CountryDao { private final NamedParameterJdbcTemplate jdbcTemplate; @@ -76,6 +76,12 @@ public class JdbcCountryDao implements CountryDao { @Value("${country.find_country_link_info_by_slug}") private String findCountryLinkEntityBySlugSql; + + @Value("${country.find_last_country_by_id}") + private String findLastCountryByIdSql; + + @Value("${country.find_popular_country}") + private String findPopularCountrySql; @Override public Integer add(AddCountryDbDto country) { @@ -206,5 +212,26 @@ public LinkEntityDto findOneAsLinkEntity(String slug, String lang) { return null; } } - + + @Override + public String suggestCountryForUser(Integer userId) { + + try { + return jdbcTemplate.queryForObject( + findLastCountryByIdSql, + Collections.singletonMap("created_by", userId), + String.class); + } catch (EmptyResultDataAccessException ignored) { + try { + return jdbcTemplate.queryForObject( + findPopularCountrySql, + Collections.emptyMap(), + String.class + ); + + } catch (EmptyResultDataAccessException ex) { + return null; + } + } + } } diff --git a/src/main/java/ru/mystamps/web/service/CountryService.java b/src/main/java/ru/mystamps/web/service/CountryService.java index 4bb4c07e0d..822c87b3fc 100644 --- a/src/main/java/ru/mystamps/web/service/CountryService.java +++ b/src/main/java/ru/mystamps/web/service/CountryService.java @@ -23,8 +23,10 @@ import ru.mystamps.web.dao.dto.LinkEntityDto; import ru.mystamps.web.service.dto.AddCountryDto; +@SuppressWarnings("PMD.TooManyMethods") public interface CountryService { String add(AddCountryDto dto, Integer userId); + String suggestCountryForUser(Integer userId); List findAllAsLinkEntities(String lang); LinkEntityDto findOneAsLinkEntity(String slug, String lang); long countAll(); diff --git a/src/main/java/ru/mystamps/web/service/CountryServiceImpl.java b/src/main/java/ru/mystamps/web/service/CountryServiceImpl.java index 52c784d46e..d9f1c188af 100644 --- a/src/main/java/ru/mystamps/web/service/CountryServiceImpl.java +++ b/src/main/java/ru/mystamps/web/service/CountryServiceImpl.java @@ -42,6 +42,7 @@ import ru.mystamps.web.util.SlugUtils; @RequiredArgsConstructor +@SuppressWarnings("PMD.TooManyMethods") public class CountryServiceImpl implements CountryService { private static final Logger LOG = LoggerFactory.getLogger(CountryServiceImpl.class); @@ -162,5 +163,16 @@ public List getStatisticsOf(Integer collectionId, String lang) { return countryDao.getStatisticsOf(collectionId, lang); } - + + /** + * @author Shkarin John + */ + @Override + @Transactional(readOnly = true) + @PreAuthorize(HasAuthority.CREATE_SERIES) + public String suggestCountryForUser(Integer userId) { + Validate.isTrue(userId != null, "User id must be non null"); + + return countryDao.suggestCountryForUser(userId); + } } diff --git a/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java b/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java index 66a2c433d6..c27ae48789 100644 --- a/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java +++ b/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java @@ -75,6 +75,7 @@ protected void configure(HttpSecurity http) throws Exception { .mvcMatchers(Url.ADD_COUNTRY_PAGE).hasAuthority(StringAuthority.CREATE_COUNTRY) .mvcMatchers(Url.ADD_SERIES_PAGE).hasAuthority(StringAuthority.CREATE_SERIES) .mvcMatchers(Url.SITE_EVENTS_PAGE).hasAuthority(StringAuthority.VIEW_SITE_EVENTS) + .mvcMatchers(Url.SUGGEST_SERIES_COUNTRY).hasAuthority(StringAuthority.CREATE_SERIES) .regexMatchers(HttpMethod.POST, "/series/[0-9]+") .hasAnyAuthority( StringAuthority.UPDATE_COLLECTION, diff --git a/src/main/java/ru/mystamps/web/support/togglz/Features.java b/src/main/java/ru/mystamps/web/support/togglz/Features.java index ee7e8936b1..75b881e063 100644 --- a/src/main/java/ru/mystamps/web/support/togglz/Features.java +++ b/src/main/java/ru/mystamps/web/support/togglz/Features.java @@ -74,7 +74,11 @@ public enum Features implements Feature { @Label("View site events") @EnabledByDefault - VIEW_SITE_EVENTS; + VIEW_SITE_EVENTS, + + @Label("/series/add: show link with auto-suggestions") + @EnabledByDefault + INFO_COUNTRY_SERIES; public boolean isActive() { return FeatureContext.getFeatureManager().isActive(this); diff --git a/src/main/javascript/series/add.js b/src/main/javascript/series/add.js index c0c504d022..f72767a249 100644 --- a/src/main/javascript/series/add.js +++ b/src/main/javascript/series/add.js @@ -2,7 +2,7 @@ // IMPORTANT: // You have to update Url.RESOURCES_VERSION each time whenever you're modified this file! // -function initPage() { +function initPage(suggestCountryUrl) { $('#country').selectize(); $('.js-catalog-numbers').on('blur', function() { @@ -21,4 +21,23 @@ function initPage() { $('.js-with-tooltip').tooltip({ 'placement': 'right' }); + + if (suggestCountryUrl == null) { + return; + } + + $.get(suggestCountryUrl, function (slug) { + if (slug == null) + return; + + var country = $("#guess_country"); + country.show(); + country.click(function() { + $(this).hide(); + + var select_country = $("#country").selectize(); + var selectize = select_country[0].selectize; + selectize.setValue(slug); + }); + }); } diff --git a/src/main/resources/liquibase/sql/test-add-series.sql b/src/main/resources/liquibase/sql/test-add-series.sql new file mode 100644 index 0000000000..15401a2445 --- /dev/null +++ b/src/main/resources/liquibase/sql/test-add-series.sql @@ -0,0 +1,18 @@ +-- +-- Auto-generated by Maven, based on values from src/main/resources/test/spring/test-data.properties +-- + +INSERT INTO series(id, quantity, perforated, country_id, created_at, created_by, updated_at, updated_by, category_id) VALUES + (2, 1, 1, 2, NOW() + 1, 1, NOW(), 4, 1); + +INSERT INTO series(id, quantity, perforated, country_id, created_at, created_by, updated_at, updated_by, category_id) VALUES + (3, 1, 1, 2, NOW() + 2, 1, NOW(), 4, 1); + +INSERT INTO series(id, quantity, perforated, country_id, created_at, created_by, updated_at, updated_by, category_id) VALUES + (4, 1, 1, 2, NOW() + 3, 1, NOW(), 4, 1); + +INSERT INTO series(id, quantity, perforated, country_id, created_at, created_by, updated_at, updated_by, category_id) VALUES + (5, 1, 1, 2, NOW() + 4, 1, NOW(), 4, 1); + +INSERT INTO series(id, quantity, perforated, country_id, created_at, created_by, updated_at, updated_by, category_id) VALUES + (6, 1, 1, 4, NOW() + 5, 1, NOW(), 4, 1); diff --git a/src/main/resources/ru/mystamps/i18n/Messages.properties b/src/main/resources/ru/mystamps/i18n/Messages.properties index 2bc1645681..569d5796bc 100644 --- a/src/main/resources/ru/mystamps/i18n/Messages.properties +++ b/src/main/resources/ru/mystamps/i18n/Messages.properties @@ -121,6 +121,7 @@ t_add_more_images_hint = Later you will be able to add additional images t_not_chosen = Not chosen t_create_category_hint = You can also add a new category t_create_country_hint = You can also add a new country +t_guess_country = Guess a country # series/info.html t_series_info = Info about series diff --git a/src/main/resources/ru/mystamps/i18n/Messages_ru.properties b/src/main/resources/ru/mystamps/i18n/Messages_ru.properties index 67a3ae6ec1..98dc5f14d7 100644 --- a/src/main/resources/ru/mystamps/i18n/Messages_ru.properties +++ b/src/main/resources/ru/mystamps/i18n/Messages_ru.properties @@ -121,6 +121,7 @@ t_add_more_images_hint = Вы сможете добавить дополните t_not_chosen = Не выбрана t_create_category_hint = Вы также можете добавить новую категорию t_create_country_hint = Вы также можете добавить новую страну +t_guess_country = Угадать страну # series/info.html t_series_info = Информация о серии diff --git a/src/main/resources/sql/country_dao_queries.properties b/src/main/resources/sql/country_dao_queries.properties index c80cacdf84..8997d32b81 100644 --- a/src/main/resources/sql/country_dao_queries.properties +++ b/src/main/resources/sql/country_dao_queries.properties @@ -81,3 +81,17 @@ country.find_country_link_info_by_slug = \ FROM countries c \ WHERE c.slug = :slug \ ORDER BY CASE WHEN 'ru' = :lang THEN COALESCE(c.name_ru, c.name) ELSE c.name END + +country.find_last_country_by_id = \ + SELECT c.slug \ + FROM series s \ +LEFT JOIN countries c ON c.id = s.country_id \ + WHERE s.created_by = :created_by \ + ORDER BY s.created_at DESC LIMIT 1 + +country.find_popular_country = \ + SELECT c.slug \ + FROM series s \ +LEFT JOIN countries c ON c.id = s.country_id \ + GROUP BY country_id \ + ORDER BY COUNT(*) DESC LIMIT 1 diff --git a/src/main/webapp/WEB-INF/views/series/add.html b/src/main/webapp/WEB-INF/views/series/add.html index 6dd6288a76..844c4097c0 100644 --- a/src/main/webapp/WEB-INF/views/series/add.html +++ b/src/main/webapp/WEB-INF/views/series/add.html @@ -15,7 +15,7 @@ - +