diff --git a/README.md b/README.md index 785de47..95f11fd 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ __powered by [PircBotX](https://github.com/pircbotx/pircbotx)__ 12. Поиск Google _____ +### 2018-04-11 + +* Добавлена статистика по сообщениям + ### 2018-03-29 * Добавлена возможность администрирования бота из чата канала diff --git a/jircbot.service b/jircbot.service index 1474296..9fd6071 100644 --- a/jircbot.service +++ b/jircbot.service @@ -5,7 +5,7 @@ After=network.target [Service] User=bvn13 WorkingDirectory=/srv/jircbot -ExecStart=/usr/bin/java -jar /srv/jircbot/jircbot-2.0.5.jar +ExecStart=/usr/bin/java -jar /srv/jircbot/jircbot-2.0.6.jar SuccessExitStatus=143 [Install] diff --git a/pom.xml b/pom.xml index 66db307..a5f6438 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ - 2.0.5 + 2.0.6 1.8 diff --git a/src/main/java/ru/bvn13/jircbot/bot/JircBot.java b/src/main/java/ru/bvn13/jircbot/bot/JircBot.java index d6b57df..ec27a42 100644 --- a/src/main/java/ru/bvn13/jircbot/bot/JircBot.java +++ b/src/main/java/ru/bvn13/jircbot/bot/JircBot.java @@ -97,6 +97,10 @@ public class JircBot extends ListenerAdapter { @Autowired private AdminListener adminListener; + @Autowired + private StatisticsListener statisticsListener; + + @PostConstruct public void postConstruct() { logger.warn("VERSION: "+version); @@ -143,6 +147,7 @@ public class JircBot extends ListenerAdapter { .setRealName("JIrcBot v"+getVersion()+" | github.com/bvn13/JIrcBot") .setName(c.getBotName()) .addListener(adminListener) + .addListener(statisticsListener) .addListener(pingPongListener) .addListener(calculatorListener) .addListener(regexCheckerListener) diff --git a/src/main/java/ru/bvn13/jircbot/database/entities/dto/StatisticsDTO.java b/src/main/java/ru/bvn13/jircbot/database/entities/dto/StatisticsDTO.java new file mode 100644 index 0000000..53917a3 --- /dev/null +++ b/src/main/java/ru/bvn13/jircbot/database/entities/dto/StatisticsDTO.java @@ -0,0 +1,17 @@ +package ru.bvn13.jircbot.database.entities.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Created by bvn13 on 11.04.2018. + */ +@Getter @Setter +@AllArgsConstructor +public class StatisticsDTO { + + private String username; + private Integer count; + +} diff --git a/src/main/java/ru/bvn13/jircbot/database/services/IrcMessageService.java b/src/main/java/ru/bvn13/jircbot/database/services/IrcMessageService.java index c27953d..f91f0d1 100644 --- a/src/main/java/ru/bvn13/jircbot/database/services/IrcMessageService.java +++ b/src/main/java/ru/bvn13/jircbot/database/services/IrcMessageService.java @@ -3,14 +3,16 @@ package ru.bvn13.jircbot.database.services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import ru.bvn13.jircbot.database.entities.IrcMessage; +import ru.bvn13.jircbot.database.entities.dto.StatisticsDTO; import ru.bvn13.jircbot.database.repositories.IrcMessageRepository; import ru.bvn13.jircbot.utilities.DateTimeUtility; import java.time.LocalDateTime; import java.time.LocalTime; -import java.time.ZoneId; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -26,6 +28,10 @@ public class IrcMessageService { @Autowired private IrcMessageRepository ircMessageRepository; + @Autowired + private JdbcTemplate jdbcTemplate; + + public void save(IrcMessage message) { try { ircMessageRepository.save(message); @@ -57,4 +63,45 @@ public class IrcMessageService { } + public List getStatistics(String serverHost, String channelName) { + + String query = "" + + " SELECT " + + " username, COUNT(message) AS count" + + " FROM public.irc_messages" + + " WHERE server_host=? AND channel_name=? AND NOT username = ''" + + " GROUP BY username" + + " ORDER BY count DESC"; + + List statistics = new ArrayList<>(); + + jdbcTemplate.query( + query, new Object[] { serverHost, channelName }, + (rs, rowNum) -> new StatisticsDTO(rs.getString("username"), rs.getInt("count")) + ).forEach(stat -> statistics.add(stat)); + + return statistics; + } + + public List getStatistics(String serverHost, String channelName, Date from) { + + String query = "" + + " SELECT " + + " username, COUNT(message) AS count" + + " FROM public.irc_messages" + + " WHERE server_host=? AND channel_name=? AND NOT username = '' AND dt_created >= ?" + + " GROUP BY username" + + " ORDER BY count DESC"; + + List statistics = new ArrayList<>(); + + jdbcTemplate.query( + query, new Object[] { serverHost, channelName, from }, + (rs, rowNum) -> new StatisticsDTO(rs.getString("username"), rs.getInt("count")) + ).forEach(stat -> statistics.add(stat)); + + return statistics; + } + + } diff --git a/src/main/java/ru/bvn13/jircbot/listeners/StatisticsListener.java b/src/main/java/ru/bvn13/jircbot/listeners/StatisticsListener.java new file mode 100644 index 0000000..86086ad --- /dev/null +++ b/src/main/java/ru/bvn13/jircbot/listeners/StatisticsListener.java @@ -0,0 +1,158 @@ +package ru.bvn13.jircbot.listeners; + +import org.pircbotx.hooks.events.MessageEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import ru.bvn13.jircbot.bot.ImprovedListenerAdapter; +import ru.bvn13.jircbot.bot.JircBot; +import ru.bvn13.jircbot.database.entities.dto.StatisticsDTO; +import ru.bvn13.jircbot.database.services.IrcMessageService; +import ru.bvn13.jircbot.utilities.DateTimeUtility; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; + +/** + * Created by bvn13 on 11.04.2018. + */ +@Component +public class StatisticsListener extends ImprovedListenerAdapter { + + private static final String COMMAND = "?stats"; + + private static class PeriodInfo { + String period; + Date dateStart; + } + + @Autowired + private IrcMessageService ircMessageService; + + @Override + public void onMessage(MessageEvent event) throws Exception { + + if (!event.getMessage().startsWith(COMMAND)) { + return; + } + + String commands[] = event.getMessage().toLowerCase().split(" ", 2); + + if (commands.length > 3) { + sendHelp(event); + return; + } + + List statistics = null; + + if (commands.length == 1) { + + statistics = ircMessageService.getStatistics(event.getBot().getServerHostname(), event.getChannel().getName()); + if (statistics.size() == 0) { + event.respondChannel("Statistics is empty now"); + return; + } + event.respondChannel("TOP 5 for all over time:"); + + for (int i = 0; i < 5 && i < statistics.size(); i++) { + StatisticsDTO stats = statistics.get(i); + event.respondChannel("" + (i + 1) + ". " + stats.getUsername() + " - " + stats.getCount()); + } + + } else if (commands.length == 2 && !commands[1].equals("all")) { + + PeriodInfo periodInfo = null; + try { + periodInfo = parseDateStart(commands[1]); + } catch (IllegalArgumentException e) { + sendHelp(event); + return; + } + + statistics = ircMessageService.getStatistics(event.getBot().getServerHostname(), event.getChannel().getName(), periodInfo.dateStart); + if (statistics.size() == 0) { + event.respondChannel("Statistics for "+periodInfo.period+" is empty now"); + return; + } + event.respondChannel("TOP 5 for "+periodInfo.period+":"); + + for (int i = 0; i < 5 && i < statistics.size(); i++) { + StatisticsDTO stats = statistics.get(i); + event.respondChannel("" + (i + 1) + ". " + stats.getUsername() + " - " + stats.getCount()); + } + + } else if (commands.length == 2 && commands[1].equals("all")) { + + statistics = ircMessageService.getStatistics(event.getBot().getServerHostname(), event.getChannel().getName()); + if (statistics.size() == 0) { + event.respondChannel("Statistics is empty now"); + return; + } + event.respondChannel("TOP for all over time:"); + + for (int i = 0; i < statistics.size(); i++) { + StatisticsDTO stats = statistics.get(i); + event.respondChannel("" + (i + 1) + ". " + stats.getUsername() + " - " + stats.getCount()); + } + + } else if (commands.length == 3) { + + if (commands[2].equals("all")) { + + PeriodInfo periodInfo = null; + try { + periodInfo = parseDateStart(commands[1]); + } catch (IllegalArgumentException e) { + sendHelp(event); + return; + } + + statistics = ircMessageService.getStatistics(event.getBot().getServerHostname(), event.getChannel().getName(), periodInfo.dateStart); + if (statistics.size() == 0) { + event.respondChannel("Statistics for "+periodInfo.period+" is empty now"); + return; + } + event.respondChannel("TOP for "+periodInfo.period+":"); + + for (int i = 0; i < statistics.size(); i++) { + StatisticsDTO stats = statistics.get(i); + event.respondChannel("" + (i + 1) + ". " + stats.getUsername() + " - " + stats.getCount()); + } + + } else { + sendHelp(event); + } + } + + } + + private PeriodInfo parseDateStart(String command) { + PeriodInfo info = new PeriodInfo(); + + LocalDateTime ldt = DateTimeUtility.dateToLocalDateTime(new Date()); + if (command.equals("d") || command.equals("day")) { + info.dateStart = DateTimeUtility.localDateTimeToDate( + ldt.withHour(0).withMinute(0).withSecond(0).withNano(0) + ); + info.period = "day"; + } else if (command.equals("m") || command.equals("month")) { + info.dateStart = DateTimeUtility.localDateTimeToDate( + ldt.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0) + ); + info.period = "month"; + } else if (command.equals("y") || command.equals("year")) { + info.dateStart = DateTimeUtility.localDateTimeToDate( + ldt.withMonth(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0) + ); + info.period = "year"; + } else { + throw new IllegalArgumentException(""); + } + return info; + } + + private void sendHelp(MessageEvent event) { + event.respond("syntax: ?stats [d(ay)|m(onth)|y(ear)|a(ll)] [all]"); + } +}