some refactoring. grammar correction implemented

pull/2/head
Vyacheslav N. Boyko 2018-02-04 18:59:36 +03:00
parent 79744b6de0
commit 79091446dc
13 changed files with 329 additions and 35 deletions

View File

@ -6,7 +6,7 @@
<groupId>ru.bvn13</groupId>
<artifactId>jircbot</artifactId>
<version>1.1.0</version>
<version>1.1.1</version>
<packaging>jar</packaging>

View File

@ -74,6 +74,9 @@ public class JircBot extends ListenerAdapter {
@Autowired
private HelloOnJoinListener helloOnJoinListener;
@Autowired
private GrammarCorrectorListener grammarCorrectorListener;
@PostConstruct
public void postConstruct() {
this.executorService = Executors.newSingleThreadScheduledExecutor();
@ -112,10 +115,9 @@ public class JircBot extends ListenerAdapter {
.addListener(bashOrgListener)
.addListener(autoRejoinListener)
.addListener(deferredMessagesListener)
// disabled yet
.addListener(linkPreviewListener)
.addListener(helloOnJoinListener)
.addListener(grammarCorrectorListener)
// not tested
//.addListener(new GoogleDoodleListener(this.config))

View File

@ -1,5 +1,7 @@
package ru.bvn13.jircbot.database.entities;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import javax.persistence.*;
@ -15,22 +17,28 @@ public abstract class BaseModel implements Comparable<BaseModel>, Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@Getter
@Setter
private Long id;
@Column(nullable = false)
private Date createdAt;
@Getter
@Setter
private Date dtCreated;
@Column(nullable = false)
private Date updatedAt;
@Getter
@Setter
private Date dtUpdated;
@PrePersist
public void prePersist(){
createdAt = updatedAt = new Date();
dtCreated = dtUpdated = new Date();
}
@PreUpdate
public void preUpdate(){
updatedAt = new Date();
dtUpdated = new Date();
}
@Override
@ -43,28 +51,28 @@ public abstract class BaseModel implements Comparable<BaseModel>, Serializable {
}
public Long getId() {
return id;
}
public void setId(Long _id) {
id = _id;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
// public Long getId() {
// return id;
// }
//
// public void setId(Long _id) {
// id = _id;
// }
//
// public Date getDtCreated() {
// return dtCreated;
// }
//
// public void setDtCreated(Date dtCreated) {
// this.dtCreated = dtCreated;
// }
//
// public Date getDtUpdated() {
// return dtUpdated;
// }
//
// public void setDtUpdated(Date dtUpdated) {
// this.dtUpdated = dtUpdated;
// }
}

View File

@ -13,7 +13,7 @@ import javax.persistence.UniqueConstraint;
* Created by bvn13 on 31.01.2018.
*/
@Entity
@Table(name = "channel_settings", uniqueConstraints = {@UniqueConstraint(columnNames = {"channelName"}, name = "uniq_channel_name")})
@Table(name = "channel_settings", uniqueConstraints = {@UniqueConstraint(columnNames = {"channelName"}, name = "uniq_channel_settings_channel_name")})
public class ChannelSettings extends BaseModel {
@Getter
@ -66,4 +66,10 @@ public class ChannelSettings extends BaseModel {
@Column(nullable = false)
private Boolean deferredMessagesEnabled = false;
@Getter
@Setter
@Column(nullable = false, columnDefinition = "Boolean DEFAULT False")
private Boolean grammarCorrectionEnabled = false;
}

View File

@ -0,0 +1,46 @@
package ru.bvn13.jircbot.database.entities;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import java.util.Date;
/**
* Created by bvn13 on 03.02.2018.
*/
@Entity
@Table(name = "grammar_correction", uniqueConstraints = {@UniqueConstraint(columnNames = {"word"}, name = "uniq_grammar_correction_word")})
@NoArgsConstructor
@AllArgsConstructor
public class GrammarCorrection extends BaseModel {
@Getter
@Setter
@Column(nullable = false)
private String word;
@Getter
@Setter
@Column(nullable = false)
private String correction;
@Getter
@Setter
private String author;
public GrammarCorrection(Long id, Date dtCreated, Date dtUpdated, String word, String correction, String author) {
this.setId(id);
this.setDtCreated(dtCreated);
this.setDtUpdated(dtUpdated);
this.setWord(word);
this.setCorrection(correction);
this.setAuthor(author);
}
}

View File

@ -11,5 +11,5 @@ import java.util.List;
*/
@Repository
public interface DeferredMessageRepository extends JpaRepository<DeferredMessage, Long> {
List<DeferredMessage> getDeferredMessagesByChannelNameAndRecipientAndSentOrderByCreatedAt(String channelName, String recipient, Boolean sent);
List<DeferredMessage> getDeferredMessagesByChannelNameAndRecipientAndSentOrderByDtCreated(String channelName, String recipient, Boolean sent);
}

View File

@ -0,0 +1,19 @@
package ru.bvn13.jircbot.database.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import ru.bvn13.jircbot.database.entities.GrammarCorrection;
import java.util.List;
/**
* Created by bvn13 on 03.02.2018.
*/
@Repository
public interface GrammarCorrectionRepository extends JpaRepository<GrammarCorrection, Long> {
GrammarCorrection findFirstByWordAndCorrection(String word, String correction);
}

View File

@ -18,7 +18,7 @@ public class DeferredMessageService {
private DeferredMessageRepository deferredMessageRepository;
public List<DeferredMessage> getDeferredMessagesForUser(String channelName, String user) {
return deferredMessageRepository.getDeferredMessagesByChannelNameAndRecipientAndSentOrderByCreatedAt(channelName, user, false);
return deferredMessageRepository.getDeferredMessagesByChannelNameAndRecipientAndSentOrderByDtCreated(channelName, user, false);
}
public void saveDeferredMessage(String channelName, String sender, String recipient, String message) {

View File

@ -0,0 +1,102 @@
package ru.bvn13.jircbot.database.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import ru.bvn13.jircbot.database.entities.GrammarCorrection;
import ru.bvn13.jircbot.database.repositories.GrammarCorrectionRepository;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* Created by bvn13 on 03.02.2018.
*/
@Service
public class GrammarCorrectionService {
@Autowired
private DataSource dataSource;
@Autowired
private GrammarCorrectionRepository grammarCorrectionRepository;
public List<String> getCorrectionsForMessage(String message) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<String> result = new ArrayList<>();
try {
jdbcTemplate.query("" +
"SELECT ? as message, g.word, g.correction " +
"FROM public.grammar_correction AS g " +
"WHERE ? ~ g.word", new Object[]{ message, message },
row -> {
result.add(row.getString("correction"));
});
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public GrammarCorrection getLastCorrection(String word) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<GrammarCorrection> result = jdbcTemplate.query("" +
"SELECT gc.id, gc.dtcreated, gc.dtupdated, gc.word, gc.correction, gc.author " +
"FROM " +
" (SELECT gc.word, MAX(gc.dtupdated) AS dtupdated " +
" FROM grammar_correction AS gc " +
" WHERE word ~ ?) AS tmax " +
"INNER JOIN grammar_correction AS gc " +
"ON gc.word = tmax.word AND gc.dtupdated = tmax.dtupdated " +
"ORDER BY gc.dtupdated DESC",
new Object[]{word},
(rs, rsNum) -> new GrammarCorrection(
rs.getLong("id"),
rs.getDate("dtcreated"),
rs.getDate("dtupdated"),
rs.getString("word"),
rs.getString("correction"),
rs.getString("author")
));
if (result.size() > 0) {
return result.get(0);
}
return null;
}
public void saveGrammarCorrection(String word, String correction, String author) {
GrammarCorrection gc = grammarCorrectionRepository.findFirstByWordAndCorrection(word, correction);
if (gc == null) {
gc = new GrammarCorrection();
gc.setWord(word);
gc.setCorrection(correction);
}
gc.setAuthor(author);
grammarCorrectionRepository.save(gc);
}
public Boolean removeCorrection(String word, String correction) {
GrammarCorrection gc = grammarCorrectionRepository.findFirstByWordAndCorrection(word, correction);
if (gc != null) {
grammarCorrectionRepository.delete(gc);
return true;
}
return false;
}
public List<GrammarCorrection> getAllCorrections() {
List<GrammarCorrection> list = grammarCorrectionRepository.findAll(new Sort(Sort.Direction.DESC, "id"));
return list;
}
}

View File

@ -1,6 +1,5 @@
package ru.bvn13.jircbot.listeners;
import org.pircbotx.hooks.ListenerAdapter;
import org.pircbotx.hooks.events.JoinEvent;
import org.pircbotx.hooks.events.NoticeEvent;
import org.pircbotx.hooks.types.GenericMessageEvent;
@ -85,7 +84,7 @@ public class DeferredMessagesListener extends ImprovedListenerAdapter {
if (deferredMessages != null && deferredMessages.size() > 0) {
DeferredMessage msg = deferredMessages.get(0);
String more = "" + (deferredMessages.size() > 1 ? " ("+(deferredMessages.size()-1)+" message/-s more)" : "");
event.respond("User "+msg.getSender()+" at "+dt.format(msg.getCreatedAt())+" told you"+more+": "+msg.getMessage());
event.respond("User "+msg.getSender()+" at "+dt.format(msg.getDtCreated())+" told you"+more+": "+msg.getMessage());
deferredMessageService.markMessageWasSent(msg);
}

View File

@ -0,0 +1,108 @@
package ru.bvn13.jircbot.listeners;
import org.pircbotx.hooks.types.GenericMessageEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.bvn13.jircbot.bot.ImprovedListenerAdapter;
import ru.bvn13.jircbot.database.entities.GrammarCorrection;
import ru.bvn13.jircbot.database.services.ChannelSettingsService;
import ru.bvn13.jircbot.database.services.GrammarCorrectionService;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by bvn13 on 03.02.2018.
*/
@Component
public class GrammarCorrectorListener extends ImprovedListenerAdapter {
private static final String COMMAND = "?correct";
private static SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Autowired
private ChannelSettingsService channelSettingsService;
@Autowired
private GrammarCorrectionService grammarCorrectionService;
@Override
public void onGenericMessage(final GenericMessageEvent event) throws Exception {
if (!channelSettingsService.getChannelSettings(this.getChannelName(event)).getGrammarCorrectionEnabled()) {
return;
}
if (event.getUser().getUserId().equals(event.getBot().getUserBot().getUserId())) {
return;
}
if (event.getMessage().startsWith(COMMAND)) {
onCommand(event);
} else {
checkForCorrection(event);
}
}
private void checkForCorrection(final GenericMessageEvent event) throws Exception {
String message = event.getMessage().replace(COMMAND, "").trim();
List<String> corrections = grammarCorrectionService.getCorrectionsForMessage(message);
corrections.forEach(correct -> {
this.sendNotice(event,"*"+correct);
});
}
private void onCommand(final GenericMessageEvent event) throws Exception {
String message = event.getMessage().replace(COMMAND, "").trim();
String commands[] = message.split(" ", 2);
if (commands.length == 2) {
if (commands[0].trim().equalsIgnoreCase("add")) {
String params[] = commands[1].trim().split(">");
if (params.length != 2) {
event.respondWith(helpMessage());
} else {
grammarCorrectionService.saveGrammarCorrection(params[0].trim(), params[1].trim(), event.getUser().getNick());
event.respond("added correction: "+params[0].trim()+" > "+params[1].trim());
}
} else if (commands[1].trim().equalsIgnoreCase("remove")) {
String params[] = commands[1].trim().split(">");
if (grammarCorrectionService.removeCorrection(params[0].trim(), params[1].trim())) {
event.respond("added correction: "+params[0].trim()+" > "+params[1].trim());
} else {
event.respond("correction not found: "+params[0].trim()+" > "+params[1].trim());
}
} else {
event.respondWith(helpMessage());
}
} else if (commands.length == 1) {
if (commands[0].trim().equalsIgnoreCase("show")) {
List<GrammarCorrection> corrections = grammarCorrectionService.getAllCorrections();
if (corrections.size() > 0) {
event.respond("sent in private");
AtomicReference<Integer> i = new AtomicReference<>(0);
corrections.forEach(c -> {
i.set(i.get()+1);
event.respondPrivateMessage(""+i.get()+": "+c.getWord()+" > "+c.getCorrection()+" / by "+c.getAuthor()+" at "+dt.format(c.getDtUpdated()));
});
} else {
event.respond("correction table is empty");
}
}
} else {
event.respondWith(helpMessage());
}
}
private String helpMessage() {
return "syntax: \r\n ?correct add <REGEX-formatted word> > <full correction>\r\n ?correct remove <REGEX-formatted word> > <full correction>\r\n ?correct show";
}
}

View File

@ -27,6 +27,8 @@ public class RegexCheckerListener extends ImprovedListenerAdapter {
@Override
public void onGenericMessage(final GenericMessageEvent event) throws Exception {
//TODO: rework with FSM
if (!channelSettingsService.getChannelSettings(getChannelName(event)).getRegexCheckerEnabled()) {
return;
}

View File

@ -27,6 +27,8 @@
<logger name="org.springframework.core.env.PropertySourcesPropertyResolver" level="WARN"/>
<!--<logger name="org.springframework.jdbc" level="DEBUG" />-->
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>