diff --git a/.gitignore b/.gitignore index 8f8104e..c2292b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ *.iml .idea/ -**/target/** \ No newline at end of file +**/target/** +.DS_Store +/vk-bot/src/main/resources/config.properties +*.log +*.properties diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml index 62c59bf..0763275 100644 --- a/pom.xml +++ b/pom.xml @@ -4,9 +4,57 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.sadtech - consultant - 0.1-SNAPSHOT + org.sadtech.autoresponder + core + 1.0 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + + 1.18.4 + 1.2.17 + 4.12 + 2.23.4 + + + + + + org.projectlombok + lombok + ${lombok.ver} + + + + log4j + log4j + ${log4j} + + + + + junit + junit + ${junit.ver} + test + + + org.mockito + mockito-core + ${mocito.ver} + test + + + \ No newline at end of file diff --git a/src/main/java/org/sadtech/autoresponder/Autoresponder.java b/src/main/java/org/sadtech/autoresponder/Autoresponder.java new file mode 100644 index 0000000..d30ea01 --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/Autoresponder.java @@ -0,0 +1,51 @@ +package org.sadtech.autoresponder; + +import com.sun.istack.internal.NotNull; +import lombok.AllArgsConstructor; +import org.sadtech.autoresponder.entity.Person; +import org.sadtech.autoresponder.entity.Unit; +import org.sadtech.autoresponder.service.PersonService; +import org.sadtech.autoresponder.service.UnitService; +import org.sadtech.autoresponder.submodule.parser.InsertWords; + +import java.util.List; + +@AllArgsConstructor +public class Autoresponder { + + private UnitService unitService; + private PersonService personService; + + public String answer(@NotNull Integer idPerson, @NotNull String message) { + Person person = CheckAndAddPerson(idPerson); + Unit unit; + if (person.getUnit() == null) { + unit = unitService.nextUnit(unitService.menuUnit(), message); + } else { + unit = unitService.nextUnit(person.getUnit(), message); + } + person.setUnit(unit); + return unit.getAnswer(); + } + + public String answer(@NotNull Integer idPerson, @NotNull String message, @NotNull List words) { + String answer = answer(idPerson, message); + InsertWords insertWords = new InsertWords(); + insertWords.setInText(answer); + insertWords.insert(words); + return insertWords.getOutText(); + } + + private Person CheckAndAddPerson(Integer idPerson) { + Person person; + if (personService.checkPerson(idPerson)) { + person = personService.getPersonById(idPerson); + } else { + person = new Person(); + person.setId(idPerson); + personService.addPerson(person); + } + return person; + } + +} diff --git a/src/main/java/org/sadtech/autoresponder/entity/Person.java b/src/main/java/org/sadtech/autoresponder/entity/Person.java new file mode 100644 index 0000000..ab4a6b3 --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/entity/Person.java @@ -0,0 +1,11 @@ +package org.sadtech.autoresponder.entity; + +import lombok.Data; + +@Data +public class Person { + + private Integer id; + private Unit unit; + +} diff --git a/src/main/java/org/sadtech/autoresponder/entity/Unit.java b/src/main/java/org/sadtech/autoresponder/entity/Unit.java new file mode 100644 index 0000000..18f408c --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/entity/Unit.java @@ -0,0 +1,19 @@ +package org.sadtech.autoresponder.entity; + +import lombok.Data; + +import java.util.List; +import java.util.Set; + +@Data +public class Unit { + + private Integer idUnit; + private List nextUnits; + private String answer; + private Integer priority; + private Set keyWords; + private Integer matchThreshold; + private Boolean level = false; + +} diff --git a/src/main/java/org/sadtech/autoresponder/repository/PersonRepository.java b/src/main/java/org/sadtech/autoresponder/repository/PersonRepository.java new file mode 100644 index 0000000..a9c668e --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/repository/PersonRepository.java @@ -0,0 +1,15 @@ +package org.sadtech.autoresponder.repository; + +import org.sadtech.autoresponder.entity.Person; + +import java.util.Collection; +import java.util.Map; + +public interface PersonRepository { + + void addPerson(Person person); + void removePerson(Person person); + void addPersonAll(Map personCollection); + Person getPersonById(Integer idPerson); + +} diff --git a/src/main/java/org/sadtech/autoresponder/repository/UnitRepository.java b/src/main/java/org/sadtech/autoresponder/repository/UnitRepository.java new file mode 100644 index 0000000..0f4679a --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/repository/UnitRepository.java @@ -0,0 +1,19 @@ +package org.sadtech.autoresponder.repository; + +import org.sadtech.autoresponder.entity.Unit; + +import java.util.Collection; +import java.util.List; + +public interface UnitRepository { + + Unit getUnitById(Integer idUnit); + + void addUnit(Unit unit); + + void addUnits(Collection units); + + void removeUnit(Unit idUnit); + + List menuUnits(); +} diff --git a/src/main/java/org/sadtech/autoresponder/repository/impl/PersonRepositoryMap.java b/src/main/java/org/sadtech/autoresponder/repository/impl/PersonRepositoryMap.java new file mode 100644 index 0000000..d831350 --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/repository/impl/PersonRepositoryMap.java @@ -0,0 +1,31 @@ +package org.sadtech.autoresponder.repository.impl; + +import org.sadtech.autoresponder.entity.Person; +import org.sadtech.autoresponder.repository.PersonRepository; + +import java.util.*; + +public class PersonRepositoryMap implements PersonRepository { + + private Map people = new HashMap<>(); + + @Override + public void addPerson(Person person) { + people.put(person.getId(), person); + } + + @Override + public void removePerson(Person person) { + people.remove(person); + } + + @Override + public void addPersonAll(Map personCollection) { + people.putAll(personCollection); + } + + @Override + public Person getPersonById(Integer idPerson) { + return people.get(idPerson); + } +} diff --git a/src/main/java/org/sadtech/autoresponder/repository/impl/UnitRepositoryMap.java b/src/main/java/org/sadtech/autoresponder/repository/impl/UnitRepositoryMap.java new file mode 100644 index 0000000..7ed7c7e --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/repository/impl/UnitRepositoryMap.java @@ -0,0 +1,42 @@ +package org.sadtech.autoresponder.repository.impl; + +import org.sadtech.autoresponder.entity.Unit; +import org.sadtech.autoresponder.repository.UnitRepository; + +import java.util.*; + +public class UnitRepositoryMap implements UnitRepository { + + private Map units = new HashMap<>(); + + @Override + public Unit getUnitById(Integer idUnit) { + return units.get(idUnit); + } + + @Override + public void addUnit(Unit unit) { + units.put(unit.getIdUnit(), unit); + } + + @Override + public void addUnits(Collection units) { + units.addAll(units); + } + + @Override + public void removeUnit(Unit idUnit) { + units.remove(idUnit.getIdUnit()); + } + + @Override + public List menuUnits() { + ArrayList unitsMenu = new ArrayList<>(); + for (Integer integer : units.keySet()) { + if (units.get(integer).getLevel()) { + unitsMenu.add(units.get(integer)); + } + } + return unitsMenu; + } +} diff --git a/src/main/java/org/sadtech/autoresponder/service/PersonService.java b/src/main/java/org/sadtech/autoresponder/service/PersonService.java new file mode 100644 index 0000000..ae963e4 --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/service/PersonService.java @@ -0,0 +1,13 @@ +package org.sadtech.autoresponder.service; + +import org.sadtech.autoresponder.entity.Person; + +public interface PersonService { + + Person getPersonById(Integer integer); + + void addPerson(Person person); + + boolean checkPerson(Integer idPerson); + +} diff --git a/src/main/java/org/sadtech/autoresponder/service/UnitService.java b/src/main/java/org/sadtech/autoresponder/service/UnitService.java new file mode 100644 index 0000000..c319e0e --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/service/UnitService.java @@ -0,0 +1,13 @@ +package org.sadtech.autoresponder.service; + +import org.sadtech.autoresponder.entity.Unit; + +public interface UnitService { + + Unit nextUnit(Unit unit, String message); + + Unit getUnitById(Integer idUnit); + + Unit menuUnit(); + +} diff --git a/src/main/java/org/sadtech/autoresponder/service/impl/PersonServiceImpl.java b/src/main/java/org/sadtech/autoresponder/service/impl/PersonServiceImpl.java new file mode 100644 index 0000000..5325b22 --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/service/impl/PersonServiceImpl.java @@ -0,0 +1,27 @@ +package org.sadtech.autoresponder.service.impl; + +import lombok.AllArgsConstructor; +import org.sadtech.autoresponder.entity.Person; +import org.sadtech.autoresponder.repository.PersonRepository; +import org.sadtech.autoresponder.service.PersonService; + +@AllArgsConstructor +public class PersonServiceImpl implements PersonService { + + private PersonRepository personRepository; + + @Override + public Person getPersonById(Integer integer) { + return personRepository.getPersonById(integer); + } + + @Override + public void addPerson(Person person) { + personRepository.addPerson(person); + } + + @Override + public boolean checkPerson(Integer idPerson) { + return personRepository.getPersonById(idPerson) != null; + } +} diff --git a/src/main/java/org/sadtech/autoresponder/service/impl/UnitServiceImpl.java b/src/main/java/org/sadtech/autoresponder/service/impl/UnitServiceImpl.java new file mode 100644 index 0000000..3d88777 --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/service/impl/UnitServiceImpl.java @@ -0,0 +1,54 @@ +package org.sadtech.autoresponder.service.impl; + +import com.sun.istack.internal.NotNull; +import lombok.AllArgsConstructor; +import lombok.extern.log4j.Log4j; +import org.sadtech.autoresponder.entity.Unit; +import org.sadtech.autoresponder.repository.UnitRepository; +import org.sadtech.autoresponder.service.UnitService; +import org.sadtech.autoresponder.submodule.parser.Parser; + +import java.util.ArrayList; +import java.util.Collections; + +@Log4j +@AllArgsConstructor +public class UnitServiceImpl implements UnitService { + + private UnitRepository unitRepository; + + public Unit nextUnit(Unit unit, @NotNull String message) { + ArrayList nextUnits = (ArrayList) unit.getNextUnits(); + if (nextUnits.size() > 0) { + Parser parser = new Parser(); + parser.setText(message); + parser.parse(); + Unit unitReturn = new Unit(); + unitReturn.setPriority(0); + for (Unit nextUnit : nextUnits) { + if (!Collections.disjoint(nextUnit.getKeyWords(), parser.getWords()) && (nextUnit.getPriority() > unitReturn.getPriority())) { + unitReturn = nextUnit; + } + } + return unitReturn; + } else { + return null; + } + + } + + @Override + public Unit getUnitById(@NotNull Integer idUnit) { + return unitRepository.getUnitById(idUnit); + } + + @Override + public Unit menuUnit() { + Unit menuUnit = new Unit(); + menuUnit.setNextUnits(unitRepository.menuUnits()); + return menuUnit; + } + + +} + diff --git a/src/main/java/org/sadtech/autoresponder/submodule/parser/InsertWords.java b/src/main/java/org/sadtech/autoresponder/submodule/parser/InsertWords.java new file mode 100644 index 0000000..f44889e --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/submodule/parser/InsertWords.java @@ -0,0 +1,33 @@ +package org.sadtech.autoresponder.submodule.parser; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InsertWords { + + @Setter + private String inText; + @Getter + private String outText; + + public void insert(List words) { + Pattern pattern = Pattern.compile("\\{(\\d+)}"); // Задаем шаблон + Matcher m = pattern.matcher(inText); // Инициализация Matcher + StringBuffer result = new StringBuffer(); // Буфер для конечного значения + while (m.find()) { // Проверка на совпадение + if (Integer.parseInt(m.group(1)) < words.size()) { + m.appendReplacement(result, words.get(Integer.parseInt(m.group(1)))); // Подставляем значение из HashMap + } else { + m.appendReplacement(result, m.group(0)); + } + } + m.appendTail(result); // Добавить остаток строки + outText = result.toString(); + } + +} + diff --git a/src/main/java/org/sadtech/autoresponder/submodule/parser/Parser.java b/src/main/java/org/sadtech/autoresponder/submodule/parser/Parser.java new file mode 100644 index 0000000..d0bb508 --- /dev/null +++ b/src/main/java/org/sadtech/autoresponder/submodule/parser/Parser.java @@ -0,0 +1,27 @@ +package org.sadtech.autoresponder.submodule.parser; + +import lombok.Getter; +import lombok.Setter; + +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Parser { + + @Getter + private Set words = new HashSet<>(); + + @Setter + private String text; + + public void parse() { + Pattern p = Pattern.compile("[а-яА-Я0-9]+"); + Matcher m = p.matcher(text); + while (m.find()) { + words.add(m.group().toLowerCase()); + } + } + +} diff --git a/src/test/java/org/sadtech/autoresponder/AutoresponderTest.java b/src/test/java/org/sadtech/autoresponder/AutoresponderTest.java new file mode 100644 index 0000000..7d79844 --- /dev/null +++ b/src/test/java/org/sadtech/autoresponder/AutoresponderTest.java @@ -0,0 +1,127 @@ +package org.sadtech.autoresponder; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.sadtech.autoresponder.entity.Person; +import org.sadtech.autoresponder.entity.Unit; +import org.sadtech.autoresponder.repository.impl.PersonRepositoryMap; +import org.sadtech.autoresponder.repository.impl.UnitRepositoryMap; +import org.sadtech.autoresponder.service.impl.PersonServiceImpl; +import org.sadtech.autoresponder.service.impl.UnitServiceImpl; + +import java.util.ArrayList; +import java.util.HashSet; + +public class AutoresponderTest { + + private Person person = new Person(); + private Unit unit = new Unit(); + private Unit unit2 = new Unit(); + private Unit unit3 = new Unit(); + private ArrayList units = new ArrayList<>(); + private UnitRepositoryMap unitRepository = new UnitRepositoryMap(); + private PersonRepositoryMap personRepository = new PersonRepositoryMap(); + + private UnitServiceImpl unitService = new UnitServiceImpl(unitRepository); + private PersonServiceImpl personService = new PersonServiceImpl(personRepository); + private Autoresponder autoresponder = new Autoresponder(unitService, personService); + + + @Before + public void before() { + HashSet words = new HashSet<>(); + HashSet words2 = new HashSet<>(); + words.add("тест"); + words2.add("тест"); + words2.add("привет"); + + unit.setIdUnit(1); + unit.setLevel(true); + unit.setPriority(50); + unit.setKeyWords(words); + unit.setAnswer("Здравствуйте, вы написали в нашу компанию!"); + unit.setMatchThreshold(100); + + units.add(unit2); + units.add(unit3); + + unit.setNextUnits(units); + + unit2.setIdUnit(2); + unit2.setAnswer("Ответ с {0} параметрами!"); + unit2.setPriority(60); + unit2.setKeyWords(words); + unit2.setMatchThreshold(100); + + unit3.setIdUnit(3); + unit3.setAnswer("Второй Ответ с {0} параметрами!"); + unit3.setPriority(50); + unit3.setKeyWords(words2); + unit3.setMatchThreshold(100); + + person.setUnit(unit); + person.setId(1); + + unitRepository.addUnit(unit); + unitRepository.addUnit(unit2); + personRepository.addPerson(person); + } + + @Test + public void usualAnswer() { + Assert.assertEquals(autoresponder.answer(person.getId(), "Привет это тест срабатывания"), "Ответ с {0} параметрами!"); + } + + @Test + public void answerOneParameter() { + ArrayList words = new ArrayList<>(); + words.add("одним"); + Assert.assertEquals(autoresponder.answer(person.getId(), "Привет это тест срабатывания", words), "Ответ с одним параметрами!"); + } + + @Test + public void NoAnswer() { + person.setUnit(null); + String test = autoresponder.answer(person.getId(), "Привет это срабатывания"); + Assert.assertNull(test); + } + + @Test + public void answerTwoParameter() { + ArrayList words = new ArrayList<>(); + words.add("одним"); + words.add("двумя"); + unit2.setAnswer("Ответ с {0} и {1}"); + Assert.assertEquals(autoresponder.answer(person.getId(), "Привет это тест срабатывания", words), "Ответ с одним и двумя"); + } + + @Test + public void incorrectSettingsWords() { + ArrayList words = new ArrayList<>(); + words.add("одним"); + words.add("двумя"); + unit2.setAnswer("Ответ с {1} и {3}"); + Assert.assertEquals(autoresponder.answer(person.getId(), "Привет это тест срабатывания", words), "Ответ с двумя и {3}"); + } + + @Test + public void answerRepeatSingleParameter() { + ArrayList words = new ArrayList<>(); + words.add("одним"); + words.add("двумя"); + unit2.setAnswer("Ответ с {1} и {1}"); + Assert.assertEquals(autoresponder.answer(person.getId(), "Привет это тест срабатывания", words), "Ответ с двумя и двумя"); + } + + @Test + public void answerByPriority() { + Assert.assertEquals(autoresponder.answer(person.getId(), "Привет это тест срабатывания"), "Ответ с {0} параметрами!"); + } + + @Test + public void answerNoPerson() { + Assert.assertEquals(autoresponder.answer(100, "Привет это тест срабатывания"), "Здравствуйте, вы написали в нашу компанию!"); + Assert.assertEquals(autoresponder.answer(100, "Привет это тест срабатывания"), "Ответ с {0} параметрами!"); + } +} \ No newline at end of file diff --git a/src/test/java/org/sadtech/autoresponder/submodule/parser/InsertWordsTest.java b/src/test/java/org/sadtech/autoresponder/submodule/parser/InsertWordsTest.java new file mode 100644 index 0000000..f0d74b5 --- /dev/null +++ b/src/test/java/org/sadtech/autoresponder/submodule/parser/InsertWordsTest.java @@ -0,0 +1,44 @@ +package org.sadtech.autoresponder.submodule.parser; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; + +public class InsertWordsTest { + + private ArrayList arrayList = new ArrayList<>(); + private InsertWords insertWords = new InsertWords(); + + @After + public void setUp() { + + } + + @Test + public void insert() { + insertWords.setInText("Проверка {0} теста"); + arrayList.add("первого"); + insertWords.insert(arrayList); + Assert.assertEquals(insertWords.getOutText(),"Проверка первого теста"); + } + + @Test + public void insert2() { + insertWords.setInText("Проверка {0} теста и {1} {теста}"); + arrayList.add("первого"); + arrayList.add("второго"); + insertWords.insert(arrayList); + Assert.assertEquals(insertWords.getOutText(),"Проверка первого теста и второго {теста}"); + } + + @Test + public void insert3() { + insertWords.setInText("Проверка {1} теста и {0} {теста}"); + arrayList.add("первого"); + arrayList.add("второго"); + insertWords.insert(arrayList); + Assert.assertEquals(insertWords.getOutText(),"Проверка второго теста и первого {теста}"); + } +} \ No newline at end of file diff --git a/src/test/java/org/sadtech/autoresponder/submodule/parser/ParserTest.java b/src/test/java/org/sadtech/autoresponder/submodule/parser/ParserTest.java new file mode 100644 index 0000000..402a24a --- /dev/null +++ b/src/test/java/org/sadtech/autoresponder/submodule/parser/ParserTest.java @@ -0,0 +1,26 @@ +package org.sadtech.autoresponder.submodule.parser; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.*; + +public class ParserTest { + + private Parser parser = new Parser(); + private Set words = new HashSet<>(); + + @Test + public void parse() { + parser.setText("Проверка парсера на правильность"); + parser.parse(); + words.add("проверка"); + words.add("парсера"); + words.add("на"); + words.add("правильность"); + Assert.assertEquals(parser.getWords(), words); + } +} \ No newline at end of file