From 215ac188ffa14ad269a2c2b3b430bdd2dc45fa93 Mon Sep 17 00:00:00 2001 From: Struchkov Mark Date: Wed, 8 Feb 2023 01:34:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BA=D0=BE=D0=BD=D0=BA=D1=80=D0=B5=D1=82=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D1=83=D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=BE=20=D1=82=D1=80=D0=B5=D0=B4=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../context/domain/entity/Discussion.java | 3 + .../entity/MergeRequestForDiscussion.java | 3 + .../context/service/AppSettingService.java | 4 + .../service/impl/AppSettingServiceImpl.java | 6 + .../service/impl/DiscussionServiceImpl.java | 121 +++++++++++------- .../v.2.0.0/2022-12-03-create-tables.xml | 3 + .../notify/NewCommentNotifyGenerator.java | 28 +++- 7 files changed, 117 insertions(+), 51 deletions(-) diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Discussion.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Discussion.java index 2e144e4..d2634bb 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Discussion.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Discussion.java @@ -40,6 +40,9 @@ public class Discussion { @Column(name = "resolved") private Boolean resolved; + @Column(name = "notification") + private boolean notification; + @ManyToOne(optional = false, cascade = CascadeType.REMOVE) @JoinTable( name = "discussion_merge_request", diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequestForDiscussion.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequestForDiscussion.java index f1000ae..f9f8372 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequestForDiscussion.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequestForDiscussion.java @@ -45,4 +45,7 @@ public class MergeRequestForDiscussion { @Column(name = "web_url") private String webUrl; + @Column(name = "notification") + private boolean notification; + } diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/AppSettingService.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/AppSettingService.java index ed05533..587a736 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/AppSettingService.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/AppSettingService.java @@ -1,5 +1,7 @@ package dev.struchkov.bot.gitlab.context.service; +import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel; + /** * Сервис отвечает за пользовательские настройки приложения. * @@ -33,4 +35,6 @@ public interface AppSettingService { boolean isPrivateProjectScan(); + DiscussionLevel getLevelDiscussionNotify(); + } diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/AppSettingServiceImpl.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/AppSettingServiceImpl.java index 483e84c..92f4ef7 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/AppSettingServiceImpl.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/AppSettingServiceImpl.java @@ -1,6 +1,7 @@ package dev.struchkov.bot.gitlab.core.service.impl; import dev.struchkov.bot.gitlab.context.domain.entity.AppSetting; +import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel; import dev.struchkov.bot.gitlab.context.repository.AppSettingRepository; import dev.struchkov.bot.gitlab.context.service.AppSettingService; import dev.struchkov.haiti.context.exception.NotFoundException; @@ -79,6 +80,11 @@ public class AppSettingServiceImpl implements AppSettingService { return getAppSetting().isProjectPrivateScan(); } + @Override + public DiscussionLevel getLevelDiscussionNotify() { + return getAppSetting().getDiscussionNotifyLevel(); + } + private AppSetting getAppSetting() { return appSettingRepository.findById(KEY) .orElseThrow(NOT_FOUND_SETTINGS); diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/DiscussionServiceImpl.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/DiscussionServiceImpl.java index e3eb3f8..7344301 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/DiscussionServiceImpl.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/DiscussionServiceImpl.java @@ -7,9 +7,11 @@ import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion; import dev.struchkov.bot.gitlab.context.domain.entity.Note; import dev.struchkov.bot.gitlab.context.domain.entity.Person; import dev.struchkov.bot.gitlab.context.domain.notify.comment.NewCommentNotify; +import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel; import dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewNotify; import dev.struchkov.bot.gitlab.context.domain.notify.task.TaskCloseNotify; import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository; +import dev.struchkov.bot.gitlab.context.service.AppSettingService; import dev.struchkov.bot.gitlab.context.service.DiscussionService; import dev.struchkov.bot.gitlab.context.service.NotifyService; import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty; @@ -38,6 +40,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.NOTIFY_WITH_CONTEXT; +import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.WITHOUT_NOTIFY; import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException; import static dev.struchkov.haiti.utils.Checker.checkNotNull; import static java.lang.Boolean.FALSE; @@ -53,24 +57,33 @@ import static java.lang.Boolean.FALSE; public class DiscussionServiceImpl implements DiscussionService { protected static final Pattern PATTERN = Pattern.compile("@[\\w]+"); + private final OkHttpClient client = new OkHttpClient(); private final DiscussionRepository repository; - private final PersonInformation personInformation; - private final OkHttpClient client = new OkHttpClient(); + private final NotifyService notifyService; + private final AppSettingService settingService; + + private final PersonInformation personInformation; private final GitlabProperty gitlabProperty; private final PersonProperty personProperty; - private final NotifyService notifyService; @Override @Transactional public Discussion create(@NonNull Discussion discussion) { final List notes = discussion.getNotes(); - if (isNeedNotifyNewNote(discussion)) { - notifyNewDiscussion(discussion); + final DiscussionLevel levelDiscussionNotify = settingService.getLevelDiscussionNotify(); + if (!WITHOUT_NOTIFY.equals(levelDiscussionNotify)) { + discussion.setNotification(false); + + if (isNeedNotifyNewNote(discussion)) { + notifyNewDiscussion(discussion); + } else { + notes.forEach(note -> notificationPersonal(discussion, note)); + } } else { - notes.forEach(note -> notificationPersonal(discussion, note)); + discussion.setNotification(true); } final boolean resolved = discussion.getNotes().stream() @@ -89,6 +102,7 @@ public class DiscussionServiceImpl implements DiscussionService { discussion.setResponsible(oldDiscussion.getResponsible()); discussion.setMergeRequest(oldDiscussion.getMergeRequest()); + discussion.setNotification(oldDiscussion.isNotification()); final Person responsiblePerson = discussion.getResponsible(); if (checkNotNull(responsiblePerson)) { @@ -104,7 +118,10 @@ public class DiscussionServiceImpl implements DiscussionService { } } } - notifyUpdateNote(oldDiscussion, discussion); + + if (oldDiscussion.isNotification()) { + notifyUpdateNote(oldDiscussion, discussion); + } final boolean resolved = discussion.getNotes().stream() .allMatch(note -> note.isResolvable() && note.getResolved()); @@ -292,28 +309,32 @@ public class DiscussionServiceImpl implements DiscussionService { } private void notifyNewAnswer(Discussion discussion, Note note) { - if (!personInformation.getId().equals(note.getAuthor().getId())) { + final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify(); + + if (!WITHOUT_NOTIFY.equals(discussionLevel) + && !personInformation.getId().equals(note.getAuthor().getId())) { final Note firstNote = discussion.getFirstNote(); - final Optional prevLastNote = discussion.getPrevLastNote(); final NewCommentNotify.NewCommentNotifyBuilder notifyBuilder = NewCommentNotify.builder() + .url(note.getWebUrl()) .mergeRequestName(discussion.getMergeRequest().getTitle()); - if (prevLastNote.isPresent()) { - final Note prevNote = prevLastNote.get(); - notifyBuilder.previousMessage(prevNote.getBody()); - notifyBuilder.previousAuthor(prevNote.getAuthor().getName()); + if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) { + final Optional prevLastNote = discussion.getPrevLastNote(); + if (prevLastNote.isPresent()) { + final Note prevNote = prevLastNote.get(); + notifyBuilder.previousMessage(prevNote.getBody()); + notifyBuilder.previousAuthor(prevNote.getAuthor().getName()); + } + + notifyBuilder + .discussionMessage(firstNote.getBody()) + .discussionAuthor(firstNote.getAuthor().getName()) + .message(note.getBody()) + .authorName(note.getAuthor().getName()); } - notifyService.send( - notifyBuilder - .url(note.getWebUrl()) - .discussionMessage(firstNote.getBody()) - .discussionAuthor(firstNote.getAuthor().getName()) - .message(note.getBody()) - .authorName(note.getAuthor().getName()) - .build() - ); + notifyService.send(notifyBuilder.build()); } } @@ -321,32 +342,42 @@ public class DiscussionServiceImpl implements DiscussionService { * Уведомляет пользователя, если его никнейм упоминается в комментарии. */ protected void notificationPersonal(Discussion discussion, Note note) { - final Matcher matcher = PATTERN.matcher(note.getBody()); - final Set recipientsLogins = new HashSet<>(); - while (matcher.find()) { - final String login = matcher.group(0).replace("@", ""); - recipientsLogins.add(login); - } - if (recipientsLogins.contains(personInformation.getUsername())) { - final Optional prevLastNote = discussion.getPrevLastNote(); - final Note firstNote = discussion.getFirstNote(); + final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify(); + if (!WITHOUT_NOTIFY.equals(discussionLevel)) { + final Matcher matcher = PATTERN.matcher(note.getBody()); + final Set recipientsLogins = new HashSet<>(); - final NewCommentNotify.NewCommentNotifyBuilder notifyBuilder = NewCommentNotify.builder() - .mergeRequestName(discussion.getMergeRequest().getTitle()) - .url(note.getWebUrl()) - .discussionMessage(firstNote.getBody()) - .discussionAuthor(firstNote.getAuthor().getName()); - if (!firstNote.equals(note)) { - notifyBuilder.message(note.getBody()) - .authorName(note.getAuthor().getName()); - } - if (prevLastNote.isPresent()) { - final Note prevNote = prevLastNote.get(); - notifyBuilder.previousMessage(prevNote.getBody()); - notifyBuilder.previousAuthor(prevNote.getAuthor().getName()); + while (matcher.find()) { + final String login = matcher.group(0).replace("@", ""); + recipientsLogins.add(login); } - notifyService.send(notifyBuilder.build()); + if (recipientsLogins.contains(personInformation.getUsername())) { + final NewCommentNotify.NewCommentNotifyBuilder notifyBuilder = NewCommentNotify.builder() + .mergeRequestName(discussion.getMergeRequest().getTitle()) + .url(note.getWebUrl()); + + if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) { + final Optional prevLastNote = discussion.getPrevLastNote(); + final Note firstNote = discussion.getFirstNote(); + + if (!firstNote.equals(note)) { + notifyBuilder.message(note.getBody()) + .authorName(note.getAuthor().getName()); + } + if (prevLastNote.isPresent()) { + final Note prevNote = prevLastNote.get(); + notifyBuilder.previousMessage(prevNote.getBody()); + notifyBuilder.previousAuthor(prevNote.getAuthor().getName()); + } + + notifyBuilder + .discussionMessage(firstNote.getBody()) + .discussionAuthor(firstNote.getAuthor().getName()); + } + + notifyService.send(notifyBuilder.build()); + } } } diff --git a/gitlab-app/src/main/resources/liquibase/v.2.0.0/2022-12-03-create-tables.xml b/gitlab-app/src/main/resources/liquibase/v.2.0.0/2022-12-03-create-tables.xml index abef4c4..93723f7 100644 --- a/gitlab-app/src/main/resources/liquibase/v.2.0.0/2022-12-03-create-tables.xml +++ b/gitlab-app/src/main/resources/liquibase/v.2.0.0/2022-12-03-create-tables.xml @@ -163,6 +163,9 @@ references="person(id)"/> + + + diff --git a/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/NewCommentNotifyGenerator.java b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/NewCommentNotifyGenerator.java index 0b9f41d..ae732af 100644 --- a/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/NewCommentNotifyGenerator.java +++ b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/NewCommentNotifyGenerator.java @@ -3,38 +3,54 @@ package dev.struchkov.bot.gitlab.telegram.service.notify; import dev.struchkov.bot.gitlab.context.domain.notify.comment.NewCommentNotify; import dev.struchkov.bot.gitlab.context.utils.Icons; import dev.struchkov.godfather.main.domain.BoxAnswer; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.godfather.main.domain.BoxAnswer.boxAnswer; +import static dev.struchkov.godfather.main.domain.keyboard.button.SimpleButton.simpleButton; +import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; +import static dev.struchkov.godfather.telegram.domain.keyboard.button.UrlButton.urlButton; import static dev.struchkov.haiti.utils.Checker.checkNotNull; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; @Component +@RequiredArgsConstructor public class NewCommentNotifyGenerator implements NotifyBoxAnswerGenerator { @Override public BoxAnswer generate(NewCommentNotify notify) { final StringBuilder builder = new StringBuilder(Icons.COMMENT).append(" *New answer in Thread*") .append(Icons.HR) - .append(escapeMarkdown(notify.getMergeRequestName())); + .append(Icons.link(escapeMarkdown(notify.getMergeRequestName()), notify.getUrl())) + .append("\n"); if (checkNotNull(notify.getDiscussionMessage())) { - builder.append("\n-- -- thread first message -- --\n") - .append("*").append(notify.getDiscussionAuthor()).append("*: ").append(escapeMarkdown(notify.getDiscussionMessage())); + builder.append("\n-- -- thread first message -- --\n") + .append("*").append(notify.getDiscussionAuthor()).append("*: ").append(escapeMarkdown(notify.getDiscussionMessage())) + .append("\n"); } if (checkNotNull(notify.getPreviousMessage())) { builder.append("\n-- -- -- previous message -- -- --\n") - .append("*").append(notify.getPreviousAuthor()).append("*: ").append(escapeMarkdown(notify.getPreviousMessage())); + .append("*").append(notify.getPreviousAuthor()).append("*: ").append(escapeMarkdown(notify.getPreviousMessage())) + .append("\n"); } if (checkNotNull(notify.getMessage())) { builder.append("\n-- -- -- --- new answer --- -- -- --\n") - .append("*").append(notify.getAuthorName()).append("*: ").append(escapeMarkdown(notify.getMessage())); + .append("*").append(notify.getAuthorName()).append("*: ").append(escapeMarkdown(notify.getMessage())) + .append("\n"); } final String messageNotify = builder.toString(); - return boxAnswer(messageNotify); + return boxAnswer( + messageNotify, + inlineKeyBoard( + simpleButton(Icons.VIEW, DELETE_MESSAGE), + urlButton(Icons.LINK, notify.getUrl()) + ) + ); } @Override