Skip to content

Commit eb57501

Browse files
bodom91php-coder
authored andcommitted
/report/daily: add page where admin can see a daily statistics.
Fix #589
1 parent d68b752 commit eb57501

File tree

15 files changed

+117
-31
lines changed

15 files changed

+117
-31
lines changed

src/main/java/ru/mystamps/web/Url.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public final class Url {
3737
public static final String INDEX_PAGE = "/";
3838
public static final String ROBOTS_TXT = "/robots.txt";
3939
public static final String SITEMAP_XML = "/sitemap.xml";
40-
40+
41+
public static final String DAILY_STATISTICS = "/report/daily";
4142
public static final String SITE_EVENTS_PAGE = "/site/events";
4243

4344
public static final String REGISTRATION_PAGE = "/account/register";
@@ -141,6 +142,7 @@ public static Map<String, String> asMap(boolean serveContentFromSingleHost) {
141142
map.put("INFO_COLLECTION_PAGE", INFO_COLLECTION_PAGE);
142143
map.put("SITE_EVENTS_PAGE", SITE_EVENTS_PAGE);
143144
map.put("BOOTSTRAP_LANGUAGE", BOOTSTRAP_LANGUAGE);
145+
map.put("DAILY_STATISTICS", DAILY_STATISTICS);
144146

145147
if (serveContentFromSingleHost) {
146148
map.put("BOOTSTRAP_CSS", BOOTSTRAP_CSS);

src/main/java/ru/mystamps/web/config/ControllersConfig.java

+8
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ public ParticipantController getParticipantController() {
8787
public RobotsTxtController getRobotsTxtController() {
8888
return new RobotsTxtController();
8989
}
90+
91+
@Bean
92+
public ReportController getReportController() {
93+
return new ReportController(
94+
servicesConfig.getMailService(),
95+
servicesConfig.getCronService()
96+
);
97+
}
9098

9199
@Bean
92100
public SeriesController getSeriesController() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (C) 2009-2017 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.controller;
19+
20+
import org.springframework.stereotype.Controller;
21+
import org.springframework.web.bind.annotation.GetMapping;
22+
import org.springframework.web.bind.annotation.ResponseBody;
23+
24+
import lombok.RequiredArgsConstructor;
25+
26+
import ru.mystamps.web.Url;
27+
import ru.mystamps.web.service.CronService;
28+
import ru.mystamps.web.service.MailService;
29+
30+
/**
31+
* @author Maxim Shestakov
32+
*/
33+
@Controller
34+
@RequiredArgsConstructor
35+
public class ReportController {
36+
37+
private final MailService mailService;
38+
private final CronService cronService;
39+
40+
@GetMapping(path = Url.DAILY_STATISTICS, produces = "text/plain; charset=UTF-8")
41+
@ResponseBody
42+
public String showDailyReport() {
43+
return mailService.prepareDailyStatistics(
44+
cronService.getDailyReport()
45+
);
46+
}
47+
48+
}

src/main/java/ru/mystamps/web/service/CronService.java

+3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
*/
1818
package ru.mystamps.web.service;
1919

20+
import ru.mystamps.web.service.dto.AdminDailyReport;
21+
2022
public interface CronService {
2123
int PURGE_AFTER_DAYS = 3;
2224

2325
void sendDailyStatistics();
26+
AdminDailyReport getDailyReport();
2427
void purgeUsersActivations();
2528
}

src/main/java/ru/mystamps/web/service/CronServiceImpl.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@
3030
import org.springframework.scheduling.annotation.Scheduled;
3131
import org.springframework.transaction.annotation.Transactional;
3232

33+
import org.springframework.security.access.prepost.PreAuthorize;
34+
3335
import lombok.RequiredArgsConstructor;
3436

3537
import ru.mystamps.web.dao.dto.UsersActivationFullDto;
3638
import ru.mystamps.web.service.dto.AdminDailyReport;
39+
import ru.mystamps.web.support.spring.security.HasAuthority;
3740

3841
@RequiredArgsConstructor
3942
public class CronServiceImpl implements CronService {
@@ -55,6 +58,12 @@ public class CronServiceImpl implements CronService {
5558
@Scheduled(cron = EVERY_DAY_AT_00_00)
5659
@Transactional(readOnly = true)
5760
public void sendDailyStatistics() {
61+
mailService.sendDailyStatisticsToAdmin(getDailyReport());
62+
}
63+
64+
@Override
65+
@PreAuthorize(HasAuthority.VIEW_DAILY_STATS)
66+
public AdminDailyReport getDailyReport() {
5867
Date today = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);
5968
Date yesterday = DateUtils.addDays(today, -1);
6069

@@ -100,7 +109,7 @@ public void sendDailyStatistics() {
100109
);
101110
report.setInvalidCsrfCounter(invalidCsrfCounter);
102111

103-
mailService.sendDailyStatisticsToAdmin(report);
112+
return report;
104113
}
105114

106115
@Override

src/main/java/ru/mystamps/web/service/MailService.java

+1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@
2323
public interface MailService {
2424
void sendActivationKeyToUser(SendUsersActivationDto activation);
2525
void sendDailyStatisticsToAdmin(AdminDailyReport report);
26+
String prepareDailyStatistics(AdminDailyReport report);
2627
}

src/main/java/ru/mystamps/web/service/MailServiceImpl.java

+34-29
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@
3939
import org.springframework.mail.javamail.MimeMessagePreparator;
4040
import org.springframework.scheduling.annotation.Async;
4141

42+
import org.springframework.security.access.prepost.PreAuthorize;
43+
4244
import ru.mystamps.web.Url;
4345
import ru.mystamps.web.service.dto.AdminDailyReport;
4446
import ru.mystamps.web.service.dto.SendUsersActivationDto;
4547
import ru.mystamps.web.service.exception.EmailSendingException;
48+
import ru.mystamps.web.support.spring.security.HasAuthority;
4649

4750
public class MailServiceImpl implements MailService {
4851
private static final Logger LOG = LoggerFactory.getLogger(MailServiceImpl.class);
@@ -101,7 +104,7 @@ public void sendDailyStatisticsToAdmin(AdminDailyReport report) {
101104
sendMail(
102105
adminEmail,
103106
getSubjectOfDailyStatisticsMail(report),
104-
getTextOfDailyStatisticsMail(report),
107+
prepareDailyStatistics(report),
105108
"daily_statistics"
106109
);
107110

@@ -114,7 +117,37 @@ public void sendDailyStatisticsToAdmin(AdminDailyReport report) {
114117
adminLang
115118
);
116119
}
120+
121+
@Override
122+
@PreAuthorize(HasAuthority.VIEW_DAILY_STATS)
123+
public String prepareDailyStatistics(AdminDailyReport report) {
124+
String template = messageSource.getMessage("daily_stat.text", null, adminLang);
125+
String fromDate = shortDatePrinter.format(report.getStartDate());
126+
String tillDate = shortDatePrinter.format(report.getEndDate());
127+
128+
Map<String, String> ctx = new HashMap<>();
129+
ctx.put("from_date", fromDate);
130+
ctx.put("to_date", tillDate);
131+
132+
put(ctx, "added_countries_cnt", report.getAddedCountriesCounter());
133+
put(ctx, "untranslated_countries_cnt", report.getUntranslatedCountriesCounter());
134+
put(ctx, "added_categories_cnt", report.getAddedCategoriesCounter());
135+
put(ctx, "untranslated_categories_cnt", report.getUntranslatedCategoriesCounter());
136+
put(ctx, "added_series_cnt", report.getAddedSeriesCounter());
137+
put(ctx, "updated_series_cnt", report.getUpdatedSeriesCounter());
138+
put(ctx, "updated_collections_cnt", report.getUpdatedCollectionsCounter());
139+
put(ctx, "registration_requests_cnt", report.getRegistrationRequestsCounter());
140+
put(ctx, "registered_users_cnt", report.getRegisteredUsersCounter());
141+
put(ctx, "events_cnt", report.countEvents());
142+
put(ctx, "not_found_cnt", report.getNotFoundCounter());
143+
put(ctx, "failed_auth_cnt", report.getFailedAuthCounter());
144+
put(ctx, "missing_csrf_cnt", report.getMissingCsrfCounter());
145+
put(ctx, "invalid_csrf_cnt", report.getInvalidCsrfCounter());
146+
put(ctx, "bad_request_cnt", -1L); // TODO: #122
117147

148+
return new StrSubstitutor(ctx).replace(template);
149+
}
150+
118151
@SuppressWarnings("PMD.UseObjectForClearerAPI")
119152
private void sendMail(
120153
final String email,
@@ -183,34 +216,6 @@ private String getSubjectOfDailyStatisticsMail(AdminDailyReport report) {
183216
StrSubstitutor substitutor = new StrSubstitutor(ctx);
184217
return substitutor.replace(template);
185218
}
186-
187-
private String getTextOfDailyStatisticsMail(AdminDailyReport report) {
188-
String template = messageSource.getMessage("daily_stat.text", null, adminLang);
189-
String fromDate = shortDatePrinter.format(report.getStartDate());
190-
String tillDate = shortDatePrinter.format(report.getEndDate());
191-
192-
Map<String, String> ctx = new HashMap<>();
193-
ctx.put("from_date", fromDate);
194-
ctx.put("to_date", tillDate);
195-
196-
put(ctx, "added_countries_cnt", report.getAddedCountriesCounter());
197-
put(ctx, "untranslated_countries_cnt", report.getUntranslatedCountriesCounter());
198-
put(ctx, "added_categories_cnt", report.getAddedCategoriesCounter());
199-
put(ctx, "untranslated_categories_cnt", report.getUntranslatedCategoriesCounter());
200-
put(ctx, "added_series_cnt", report.getAddedSeriesCounter());
201-
put(ctx, "updated_series_cnt", report.getUpdatedSeriesCounter());
202-
put(ctx, "updated_collections_cnt", report.getUpdatedCollectionsCounter());
203-
put(ctx, "registration_requests_cnt", report.getRegistrationRequestsCounter());
204-
put(ctx, "registered_users_cnt", report.getRegisteredUsersCounter());
205-
put(ctx, "events_cnt", report.countEvents());
206-
put(ctx, "not_found_cnt", report.getNotFoundCounter());
207-
put(ctx, "failed_auth_cnt", report.getFailedAuthCounter());
208-
put(ctx, "missing_csrf_cnt", report.getMissingCsrfCounter());
209-
put(ctx, "invalid_csrf_cnt", report.getInvalidCsrfCounter());
210-
put(ctx, "bad_request_cnt", -1L); // TODO: #122
211-
212-
return new StrSubstitutor(ctx).replace(template);
213-
}
214219

215220
private static void put(Map<String, String> ctx, String key, long value) {
216221
ctx.put(key, String.valueOf(value));

src/main/java/ru/mystamps/web/support/spring/security/Authority.java

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public final class Authority {
3333
public static final GrantedAuthority UPDATE_COLLECTION = new SimpleGrantedAuthority(StringAuthority.UPDATE_COLLECTION);
3434
public static final GrantedAuthority VIEW_SITE_EVENTS = new SimpleGrantedAuthority(StringAuthority.VIEW_SITE_EVENTS);
3535
public static final GrantedAuthority VIEW_SERIES_SALES = new SimpleGrantedAuthority(StringAuthority.VIEW_SERIES_SALES);
36+
public static final GrantedAuthority VIEW_DAILY_STATS = new SimpleGrantedAuthority(StringAuthority.VIEW_DAILY_STATS);
3637

3738
private Authority() {
3839
}

src/main/java/ru/mystamps/web/support/spring/security/CustomUserDetailsService.java

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ private static Collection<? extends GrantedAuthority> getAuthorities(UserDetails
8181
authorities.add(Authority.ADD_SERIES_SALES);
8282
authorities.add(Authority.VIEW_SERIES_SALES);
8383
authorities.add(Authority.MANAGE_TOGGLZ);
84+
authorities.add(Authority.VIEW_DAILY_STATS);
8485
}
8586

8687
return authorities;

src/main/java/ru/mystamps/web/support/spring/security/HasAuthority.java

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public final class HasAuthority {
2424
public static final String CREATE_SERIES = "hasAuthority('" + StringAuthority.CREATE_SERIES + "')";
2525
public static final String CREATE_CATEGORY = "hasAuthority('" + StringAuthority.CREATE_CATEGORY + "')";
2626
public static final String CREATE_COUNTRY = "hasAuthority('" + StringAuthority.CREATE_COUNTRY + "')";
27+
public static final String VIEW_DAILY_STATS = "hasAuthority('" + StringAuthority.VIEW_DAILY_STATS + "')";
2728
public static final String UPDATE_COLLECTION = "hasAuthority('" + StringAuthority.UPDATE_COLLECTION + "')";
2829
public static final String VIEW_SITE_EVENTS = "hasAuthority('" + StringAuthority.VIEW_SITE_EVENTS + "')";
2930
public static final String VIEW_SERIES_SALES = "hasAuthority('" + StringAuthority.VIEW_SERIES_SALES + "')";

src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ protected void configure(HttpSecurity http) throws Exception {
7777
.mvcMatchers(Url.ADD_SERIES_PAGE).hasAuthority(StringAuthority.CREATE_SERIES)
7878
.mvcMatchers(Url.SITE_EVENTS_PAGE).hasAuthority(StringAuthority.VIEW_SITE_EVENTS)
7979
.mvcMatchers(Url.SUGGEST_SERIES_COUNTRY).hasAuthority(StringAuthority.CREATE_SERIES)
80+
.mvcMatchers(Url.DAILY_STATISTICS).hasAuthority(StringAuthority.VIEW_DAILY_STATS)
8081
.regexMatchers(HttpMethod.POST, "/series/[0-9]+")
8182
.hasAnyAuthority(
8283
StringAuthority.UPDATE_COLLECTION,

src/main/java/ru/mystamps/web/support/spring/security/StringAuthority.java

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public final class StringAuthority {
2929
public static final String UPDATE_COLLECTION = "UPDATE_COLLECTION";
3030
public static final String VIEW_SITE_EVENTS = "VIEW_SITE_EVENTS";
3131
public static final String VIEW_SERIES_SALES = "VIEW_SERIES_SALES";
32+
public static final String VIEW_DAILY_STATS = "VIEW_DAILY_STATS";
3233

3334
private StringAuthority() {
3435
}

src/main/resources/ru/mystamps/i18n/Messages.properties

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ t_example = Example
6767
t_catalog = Catalog
6868
t_search = Search
6969
t_view_suspicious_activities = view suspicious activities
70+
t_view_daily_statistics = view daily statistics
7071

7172
# account/register.html
7273
t_registration_on_site = Register on site

src/main/resources/ru/mystamps/i18n/Messages_ru.properties

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ t_example = Пример
6767
t_catalog = Каталог
6868
t_search = Найти
6969
t_view_suspicious_activities = посмотреть подозрительные события
70+
t_view_daily_statistics = посмотреть дневную статистику
7071

7172
# account/register.html
7273
t_registration_on_site = Регистрация на сайте

src/main/webapp/WEB-INF/views/site/index.html

+3
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@
117117
<li togglz:active="VIEW_SITE_EVENTS" sec:authorize="hasAuthority('VIEW_SITE_EVENTS')">
118118
<a th:href="@{${SITE_EVENTS_PAGE}}" th:text="#{t_view_suspicious_activities}" href="events.html">view suspicious activities</a>
119119
</li>
120+
<li sec:authorize="hasAuthority('VIEW_DAILY_STATS')">
121+
<a th:href="@{${DAILY_STATISTICS}}" th:text="#{t_view_daily_statistics}" href="javascript:void(0)">view daily statistics</a>
122+
</li>
120123
</ul>
121124
</nav>
122125
</div>

0 commit comments

Comments
 (0)