Сообщение о количестве решенных задач

This commit is contained in:
uPagge 2021-03-23 13:34:40 +03:00
parent 3df376d0f1
commit 760a17e30c
No known key found for this signature in database
GPG Key ID: 964B40928E4C9088
16 changed files with 156 additions and 24 deletions

View File

@ -22,7 +22,7 @@ telegram-config:
bot-username: ${TELEGRAM_BOT_USERNAME}
bot-token: ${TELEGRAM_BOT_TOKEN}
gitlab-bot:
version: 0.0.4 Beta
version: 0.0.5 Beta
person:
telegram-id: ${TELEGRAM_PERSON_ID}
token: ${GITLAB_PERSONAL_TOKEN}

View File

@ -126,6 +126,7 @@
<constraints nullable="false" foreignKeyName="discussion_responsible_id_person_id"
references="person(id)"/>
</column>
<column name="resolved" type="boolean"/>
</createTable>
</changeSet>

View File

@ -22,7 +22,7 @@ notify.pr.forgotten={0} *Напоминание о просмотре PullReques
notify.pr.conflict={0} *Внимание! Конфликт в MergeRequest | {4}*{1}[{2}]({3})
notify.pr.smart={0} *Напоминание о MergeRequest | {6}*{3}[{1}]({2}){3}{4} изменил свое решение на {5}
notify.pr.state={0} *Изменился статус MergeRequest | {7}*{1}[{2}]({3}){1}{4} {5} {6}
notify.pr.update={0} *Обновление MergeRequest | {6}*{3}[{1}]({2}){3}{4}: {5}
notify.pr.update={0} *Обновление MergeRequest | {6}*{3}[{1}]({2}){3}Все задачи: {8}/{7}\nВаши задачи: {10}/{9}{3}{4}: {5}
notify.task.close={0} *Закрыта* [задача]({1}){2}*{3}*: {4}
notify.task.new={0} *Назначена новая* [задача]({1}){2}*{3}*: {4}
notify.project.new={0} *Новый Проект*{1}[{2}]({3}){1}{4}{5}: {6}

View File

@ -37,6 +37,9 @@ public class Discussion implements BasicEntity<String> {
@JoinColumn(name = "responsible_id")
private Person responsible;
@Column(name = "resolved")
private Boolean resolved;
@ManyToOne()
@JoinTable(
name = "discussion_merge_request",
@ -60,4 +63,8 @@ public class Discussion implements BasicEntity<String> {
this.notes = notes;
}
public Note getFirstNote() {
return this.notes.get(0);
}
}

View File

@ -9,23 +9,35 @@ import org.sadtech.bot.gitlab.context.utils.Smile;
public class UpdatePrNotify extends PrNotify {
private final String author;
private final Long allTasks;
private final Long allResolvedTasks;
private final Long personTasks;
private final Long personResolvedTasks;
@Builder
private UpdatePrNotify(
String name,
String url,
String author,
String projectKey
String projectKey,
Long allTasks,
Long allResolvedTasks,
Long personTasks,
Long personResolvedTasks
) {
super(projectKey, name, url);
this.author = author;
this.allTasks = allTasks;
this.allResolvedTasks = allResolvedTasks;
this.personTasks = personTasks;
this.personResolvedTasks = personResolvedTasks;
}
@Override
public String generateMessage(AppSettingService settingService) {
return settingService.getMessage(
"notify.pr.update",
Smile.UPDATE.getValue(), title, url, Smile.HR.getValue(), Smile.AUTHOR.getValue(), author, projectName
Smile.UPDATE.getValue(), title, url, Smile.HR.getValue(), Smile.AUTHOR.getValue(), author, projectName, allTasks, allResolvedTasks, personTasks, personResolvedTasks
);
}

View File

@ -1,8 +1,11 @@
package org.sadtech.bot.gitlab.context.repository;
import lombok.NonNull;
import org.sadtech.bot.gitlab.context.domain.entity.Discussion;
import org.sadtech.haiti.context.repository.SimpleManagerRepository;
import java.util.List;
/**
* // TODO: 11.02.2021 Добавить описание.
*
@ -10,4 +13,6 @@ import org.sadtech.haiti.context.repository.SimpleManagerRepository;
*/
public interface DiscussionRepository extends SimpleManagerRepository<Discussion, String> {
List<Discussion> findAllByMergeRequestId(@NonNull Long mergeRequestId);
}

View File

@ -16,7 +16,7 @@ public interface AppSettingService {
String getMessage(@NonNull String label);
String getMessage(@NonNull String label, String... params);
String getMessage(@NonNull String label, Object... params);
void setLocale(@NonNull AppLocale appLocale);

View File

@ -4,6 +4,8 @@ import lombok.NonNull;
import org.sadtech.bot.gitlab.context.domain.entity.Discussion;
import org.sadtech.haiti.context.service.SimpleManagerService;
import java.util.List;
/**
* // TODO: 11.02.2021 Добавить описание.
*
@ -13,4 +15,6 @@ public interface DiscussionService extends SimpleManagerService<Discussion, Stri
void answer(@NonNull String discussionId, @NonNull String text);
List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId);
}

View File

@ -54,7 +54,7 @@ public class AppSettingServiceImpl implements AppSettingService {
}
@Override
public String getMessage(@NonNull String label, String... params) {
public String getMessage(@NonNull String label, Object... params) {
final Object[] paramsArray = Arrays.stream(params).toArray();
return messageSource.getMessage(
label,

View File

@ -13,9 +13,11 @@ import org.sadtech.bot.gitlab.context.domain.entity.MergeRequest;
import org.sadtech.bot.gitlab.context.domain.entity.Note;
import org.sadtech.bot.gitlab.context.domain.notify.comment.CommentNotify;
import org.sadtech.bot.gitlab.context.domain.notify.task.TaskCloseNotify;
import org.sadtech.bot.gitlab.context.domain.notify.task.TaskNewNotify;
import org.sadtech.bot.gitlab.context.repository.DiscussionRepository;
import org.sadtech.bot.gitlab.context.service.DiscussionService;
import org.sadtech.bot.gitlab.context.service.NotifyService;
import org.sadtech.bot.gitlab.context.service.PersonService;
import org.sadtech.bot.gitlab.core.config.properties.GitlabProperty;
import org.sadtech.bot.gitlab.core.config.properties.PersonProperty;
import org.sadtech.haiti.context.exception.NotFoundException;
@ -25,6 +27,7 @@ import org.springframework.stereotype.Service;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
@ -45,6 +48,7 @@ public class DiscussionServiceImpl extends AbstractSimpleManagerService<Discussi
protected static final Pattern PATTERN = Pattern.compile("@[\\w]+");
private final PersonService personService;
private final DiscussionRepository discussionRepository;
private final PersonInformation personInformation;
@ -53,8 +57,9 @@ public class DiscussionServiceImpl extends AbstractSimpleManagerService<Discussi
private final PersonProperty personProperty;
private final NotifyService notifyService;
public DiscussionServiceImpl(DiscussionRepository discussionRepository, PersonInformation personInformation, GitlabProperty gitlabProperty, PersonProperty personProperty, NotifyService notifyService) {
public DiscussionServiceImpl(PersonService personService, DiscussionRepository discussionRepository, PersonInformation personInformation, GitlabProperty gitlabProperty, PersonProperty personProperty, NotifyService notifyService) {
super(discussionRepository);
this.personService = personService;
this.discussionRepository = discussionRepository;
this.personInformation = personInformation;
this.gitlabProperty = gitlabProperty;
@ -64,35 +69,78 @@ public class DiscussionServiceImpl extends AbstractSimpleManagerService<Discussi
@Override
public Discussion create(@NonNull Discussion discussion) {
discussion.getNotes().forEach(note -> personService.create(note.getAuthor()));
discussion.getNotes().forEach(this::notificationPersonal);
discussion.getNotes().forEach(note -> notifyNewTask(note, discussion));
final boolean resolved = discussion.getNotes().stream()
.allMatch(note -> note.isResolvable() && note.getResolved());
discussion.setResolved(resolved);
return discussionRepository.save(discussion);
}
private void notifyNewTask(Note note, Discussion discussion) {
if (note.isResolvable()
&& personInformation.getId().equals(discussion.getResponsible().getId())
&& !personInformation.getId().equals(note.getAuthor().getId())
&& note.getResolved() != null
&& !note.getResolved()
) {
notifyService.send(
TaskNewNotify.builder()
.authorName(note.getAuthor().getName())
.messageTask(note.getBody())
.url(note.getWebUrl())
.build()
);
}
}
@Override
public Discussion update(@NonNull Discussion discussion) {
final Discussion oldDiscussion = discussionRepository.findById(discussion.getId()).orElseThrow(() -> new NotFoundException("Дискуссия не найдена"));
final Discussion oldDiscussion = discussionRepository.findById(discussion.getId())
.orElseThrow(() -> new NotFoundException("Дискуссия не найдена"));
final Map<Long, Note> noteMap = oldDiscussion
.getNotes().stream()
.collect(Collectors.toMap(Note::getId, note -> note));
final boolean inDiscussion = discussion.getNotes().stream()
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
discussion.setResponsible(oldDiscussion.getResponsible());
discussion.getNotes().forEach(note -> updateNote(note, noteMap));
discussion.getNotes().forEach(note -> updateNote(note, noteMap, inDiscussion));
final boolean resolved = discussion.getNotes().stream()
.allMatch(note -> note.isResolvable() && note.getResolved());
discussion.setResolved(resolved);
return discussionRepository.save(discussion);
}
private void updateNote(Note note, Map<Long, Note> noteMap) {
private void updateNote(Note note, Map<Long, Note> noteMap, boolean inDiscussion) {
if (noteMap.containsKey(note.getId())) {
final Note oldNote = noteMap.get(note.getId());
note.setWebUrl(oldNote.getWebUrl());
if (note.isResolvable()) {
updateTask(note, oldNote);
}
} else {
notificationPersonal(note);
if (inDiscussion) {
notifyNewAnswer(note);
} else {
notificationPersonal(note);
}
}
}
private void notifyNewAnswer(Note note) {
if (!personInformation.getId().equals(note.getAuthor().getId())) {
notifyService.send(
CommentNotify.builder()
.url(note.getWebUrl())
.message(note.getBody())
.authorName(note.getAuthor().getName())
.build()
);
}
}
@ -143,6 +191,11 @@ public class DiscussionServiceImpl extends AbstractSimpleManagerService<Discussi
}
@Override
public List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId) {
return discussionRepository.findAllByMergeRequestId(mergeRequestId);
}
protected void notificationPersonal(@NonNull Note note) {
Matcher matcher = PATTERN.matcher(note.getBody());
Set<String> recipientsLogins = new HashSet<>();

View File

@ -4,6 +4,7 @@ import lombok.NonNull;
import org.sadtech.bot.gitlab.context.domain.IdAndStatusPr;
import org.sadtech.bot.gitlab.context.domain.MergeRequestState;
import org.sadtech.bot.gitlab.context.domain.PersonInformation;
import org.sadtech.bot.gitlab.context.domain.entity.Discussion;
import org.sadtech.bot.gitlab.context.domain.entity.MergeRequest;
import org.sadtech.bot.gitlab.context.domain.entity.Project;
import org.sadtech.bot.gitlab.context.domain.filter.MergeRequestFilter;
@ -12,6 +13,7 @@ import org.sadtech.bot.gitlab.context.domain.notify.pullrequest.NewPrNotify;
import org.sadtech.bot.gitlab.context.domain.notify.pullrequest.StatusPrNotify;
import org.sadtech.bot.gitlab.context.domain.notify.pullrequest.UpdatePrNotify;
import org.sadtech.bot.gitlab.context.repository.MergeRequestRepository;
import org.sadtech.bot.gitlab.context.service.DiscussionService;
import org.sadtech.bot.gitlab.context.service.MergeRequestsService;
import org.sadtech.bot.gitlab.context.service.NotifyService;
import org.sadtech.bot.gitlab.context.service.PersonService;
@ -24,8 +26,11 @@ import org.sadtech.haiti.filter.FilterService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class MergeRequestsServiceImpl extends AbstractSimpleManagerService<MergeRequest, Long> implements MergeRequestsService {
@ -35,6 +40,7 @@ public class MergeRequestsServiceImpl extends AbstractSimpleManagerService<Merge
private final PersonService personService;
private final FilterService<MergeRequest, MergeRequestFilter> filterService;
private final ProjectService projectService;
private final DiscussionService discussionService;
private final PersonInformation personInformation;
@ -44,7 +50,7 @@ public class MergeRequestsServiceImpl extends AbstractSimpleManagerService<Merge
PersonService personService,
@Qualifier("mergeRequestFilterService") FilterService<MergeRequest, MergeRequestFilter> filterService,
ProjectService projectService,
PersonInformation personInformation
DiscussionService discussionService, PersonInformation personInformation
) {
super(mergeRequestRepository);
this.notifyService = notifyService;
@ -52,6 +58,7 @@ public class MergeRequestsServiceImpl extends AbstractSimpleManagerService<Merge
this.personService = personService;
this.filterService = filterService;
this.projectService = projectService;
this.discussionService = discussionService;
this.personInformation = personInformation;
}
@ -125,12 +132,30 @@ public class MergeRequestsServiceImpl extends AbstractSimpleManagerService<Merge
!personInformation.getId().equals(mergeRequest.getAuthor().getId())
&& !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit())
) {
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId())
.stream()
.filter(discussion -> Objects.nonNull(discussion.getResponsible()))
.collect(Collectors.toList());
final long allTask = discussions.size();
final long resolvedTask = discussions.stream()
.filter(Discussion::getResolved)
.count();
final long allYouTasks = discussions.stream()
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()))
.count();
final long resolvedYouTask = discussions.stream()
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved())
.count();
notifyService.send(
UpdatePrNotify.builder()
.author(oldMergeRequest.getAuthor().getName())
.name(oldMergeRequest.getTitle())
.projectKey(project.getName())
.url(oldMergeRequest.getWebUrl())
.allTasks(allTask)
.allResolvedTasks(resolvedTask)
.personTasks(allYouTasks)
.personResolvedTasks(resolvedYouTask)
.build()
);
}
@ -159,6 +184,7 @@ public class MergeRequestsServiceImpl extends AbstractSimpleManagerService<Merge
!oldStatus.equals(newStatus)
&& oldMergeRequest.getAuthor().getId().equals(personInformation.getId())
) {
notifyService.send(
StatusPrNotify.builder()
.name(newMergeRequest.getTitle())

View File

@ -16,7 +16,6 @@ import java.util.List;
@Service
public class NoteServiceImpl extends AbstractSimpleManagerService<Note, Long> implements NoteService {
private final NoteRepository noteRepository;
public NoteServiceImpl(NoteRepository noteRepository) {

View File

@ -9,7 +9,6 @@ import org.sadtech.bot.gitlab.core.config.properties.GitlabProperty;
import org.sadtech.bot.gitlab.core.config.properties.PersonProperty;
import org.sadtech.bot.gitlab.sdk.domain.DiscussionJson;
import org.sadtech.haiti.context.domain.ExistsContainer;
import org.sadtech.haiti.context.exception.ConvertException;
import org.sadtech.haiti.context.page.Sheet;
import org.sadtech.haiti.core.page.PaginationImpl;
import org.sadtech.haiti.utils.network.HttpParse;
@ -18,6 +17,7 @@ import org.springframework.stereotype.Component;
import java.text.MessageFormat;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -93,6 +93,7 @@ public class DiscussionParser {
);
return discussion;
})
.filter(discussion -> discussion.getNotes() != null && !discussion.getNotes().isEmpty())
.collect(Collectors.toList());
discussionService.createAll(newDiscussions);
}
@ -114,13 +115,21 @@ public class DiscussionParser {
for (Discussion discussion : discussions) {
if (discussion.getMergeRequest() != null) {
final Discussion newDiscussion = HttpParse.request(MessageFormat.format(gitlabProperty.getUrlOneDiscussion(), discussion.getMergeRequest().getProjectId(), discussion.getMergeRequest().getTwoId(), discussion.getId()))
final Optional<Discussion> optNewDiscussion = HttpParse.request(MessageFormat.format(gitlabProperty.getUrlOneDiscussion(), discussion.getMergeRequest().getProjectId(), discussion.getMergeRequest().getTwoId(), discussion.getId()))
.header(ACCEPT)
.header(AUTHORIZATION, BEARER + personProperty.getToken())
.execute(DiscussionJson.class)
.map(json -> conversionService.convert(json, Discussion.class))
.orElseThrow(() -> new ConvertException("Ошибка парсинга дискуссии"));
discussionService.update(newDiscussion);
.map(json -> {
final Discussion newDiscussion = conversionService.convert(json, Discussion.class);
newDiscussion.getNotes().forEach(
note -> {
final String url = MessageFormat.format(gitlabProperty.getUrlNote(), discussion.getMergeRequest().getWebUrl(), note.getId());
note.setWebUrl(url);
}
);
return newDiscussion;
});
optNewDiscussion.ifPresent(discussionService::update);
} else {
discussionService.deleteById(discussion.getId());
}

View File

@ -36,7 +36,6 @@ import static org.sadtech.haiti.utils.network.HttpParse.BEARER;
@RequiredArgsConstructor
public class MergeRequestParser {
public static final Integer COUNT = 100;
private static final Set<MergeRequestState> OLD_STATUSES = Stream.of(
MergeRequestState.MERGED, MergeRequestState.OPENED, MergeRequestState.CLOSED
@ -119,7 +118,9 @@ public class MergeRequestParser {
.header(ACCEPT)
.header(AUTHORIZATION, BEARER + personProperty.getToken())
.executeList(CommitJson.class);
mergeRequest.setDateLastCommit(commitJson.get(0).getCreatedDate());
if (commitJson != null && !commitJson.isEmpty()) {
mergeRequest.setDateLastCommit(commitJson.get(0).getCreatedDate());
}
}
private List<MergeRequestJson> getMergeRequestJsons(Project project, int page) {

View File

@ -1,11 +1,14 @@
package org.sadtech.bot.gitlab.data.impl;
import lombok.NonNull;
import org.sadtech.bot.gitlab.context.domain.entity.Discussion;
import org.sadtech.bot.gitlab.context.repository.DiscussionRepository;
import org.sadtech.bot.gitlab.data.jpa.DiscussionJpaRepository;
import org.sadtech.haiti.database.repository.manager.AbstractSimpleManagerRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* // TODO: 11.02.2021 Добавить описание.
*
@ -14,8 +17,16 @@ import org.springframework.stereotype.Repository;
@Repository
public class DiscussionRepositoryImpl extends AbstractSimpleManagerRepository<Discussion, String> implements DiscussionRepository {
public DiscussionRepositoryImpl(JpaRepository<Discussion, String> jpaRepository) {
private final DiscussionJpaRepository jpaRepository;
public DiscussionRepositoryImpl(DiscussionJpaRepository jpaRepository) {
super(jpaRepository);
this.jpaRepository = jpaRepository;
}
@Override
public List<Discussion> findAllByMergeRequestId(@NonNull Long mergeRequestId) {
return jpaRepository.findAllByMergeRequestId(mergeRequestId);
}
}

View File

@ -3,6 +3,8 @@ package org.sadtech.bot.gitlab.data.jpa;
import org.sadtech.bot.gitlab.context.domain.entity.Discussion;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
* // TODO: 11.02.2021 Добавить описание.
*
@ -10,4 +12,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
*/
public interface DiscussionJpaRepository extends JpaRepository<Discussion, String> {
List<Discussion> findAllByMergeRequestId(Long mergeRequestId);
}