Стабильная рабочая версия

This commit is contained in:
upagge 2020-04-08 00:43:27 +03:00
parent b74f7ae7da
commit f4ab127766
No known key found for this signature in database
GPG Key ID: 15CD012E46F6BA34
17 changed files with 213 additions and 81 deletions

View File

@ -13,7 +13,7 @@ public class AppConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(7);
taskScheduler.setPoolSize(10);
return taskScheduler;
}

View File

@ -0,0 +1,16 @@
package com.tsc.bitbucketbot.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "bitbucketbot.init")
public class InitConfig {
private Long startCommentId;
}

View File

@ -0,0 +1,19 @@
package com.tsc.bitbucketbot.domain;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class Answer {
private final String authorName;
private final String message;
public static Answer of(@NonNull String name, @NonNull String message) {
return new Answer(name, message);
}
}

View File

@ -0,0 +1,33 @@
package com.tsc.bitbucketbot.domain.change;
import com.tsc.bitbucketbot.domain.Answer;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Singular;
import java.util.List;
import java.util.Set;
@Getter
@EqualsAndHashCode(callSuper = true)
public class AnswerCommentChange extends Change {
private final String youMessage;
private final String url;
private final List<Answer> answers;
@Builder
protected AnswerCommentChange(
@Singular("telegramId") Set<Long> telegramId,
String youMessage,
String url,
List<Answer> answers
) {
super(ChangeType.NEW_ANSWERS_COMMENT, telegramId);
this.youMessage = youMessage;
this.url = url;
this.answers = answers;
}
}

View File

@ -2,6 +2,12 @@ package com.tsc.bitbucketbot.domain.change;
public enum ChangeType {
STATUS_PR, UPDATE_PR, REVIEWERS, NEW_PR, CONFLICT_PR
STATUS_PR,
UPDATE_PR,
REVIEWERS,
NEW_PR,
CONFLICT_PR,
NEW_COMMENT,
NEW_ANSWERS_COMMENT
}

View File

@ -0,0 +1,30 @@
package com.tsc.bitbucketbot.domain.change;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Singular;
import java.util.Set;
@Getter
@EqualsAndHashCode(callSuper = true)
public class CommentChange extends PrChange {
private final String authorName;
private final String message;
@Builder
private CommentChange(
@Singular("telegramId") Set<Long> telegramId,
String name,
String url,
String authorName,
String message
) {
super(ChangeType.NEW_COMMENT, telegramId, name, url);
this.authorName = authorName;
this.message = message;
}
}

View File

@ -15,7 +15,7 @@ import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Set;
@Getter
@ -30,17 +30,19 @@ public class Comment {
@Id
@Column(name = "id")
// @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "url")
private String url;
@Column(name = "pr_url")
private String prUrl;
@Column(name = "telegram")
private Long telegram;
@Column(name = "date")
private LocalDate date;
private LocalDateTime date;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "comment_tree", joinColumns = @JoinColumn(name = "parent_id"))

View File

@ -3,7 +3,7 @@ package com.tsc.bitbucketbot.repository.jpa;
import com.tsc.bitbucketbot.domain.entity.Comment;
import org.springframework.data.jpa.repository.JpaRepository;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@ -11,6 +11,6 @@ public interface CommentRepository extends JpaRepository<Comment, Long> {
Optional<Comment> findFirstByOrderByIdDesc();
List<Comment> findByDateBetween(LocalDate dateFrom, LocalDate dateTo);
List<Comment> findByDateBetween(LocalDateTime dateFrom, LocalDateTime dateTo);
}

View File

@ -1,6 +1,9 @@
package com.tsc.bitbucketbot.scheduler;
import com.tsc.bitbucketbot.domain.MessageSend;
import com.tsc.bitbucketbot.domain.change.AnswerCommentChange;
import com.tsc.bitbucketbot.domain.change.Change;
import com.tsc.bitbucketbot.domain.change.CommentChange;
import com.tsc.bitbucketbot.domain.change.ConflictPrChange;
import com.tsc.bitbucketbot.domain.change.NewPrChange;
import com.tsc.bitbucketbot.domain.change.ReviewersPrChange;
@ -25,23 +28,21 @@ public class SchedulerChangeParsing {
private final MessageSendService messageSendService;
private final ChangeService changeService;
// @Scheduled(cron = "0 * * * * *")
@Scheduled(fixedRate = 5000)
@Scheduled(cron = "30 */1 * * * MON-FRI")
public void parsing() {
final List<Change> newChange = changeService.getNew().stream()
.filter(change -> change.getTelegramId() != null && !change.getTelegramId().isEmpty())
.collect(Collectors.toList());
for (Change change : newChange) {
final String message = generateMessage(change);
System.out.println(message);
// change.getTelegramId().forEach(
// telegramId -> messageSendService.add(
// MessageSend.builder()
// .telegramId(telegramId)
// .message(message)
// .build()
// )
// );
change.getTelegramId().forEach(
telegramId -> messageSendService.add(
MessageSend.builder()
.telegramId(telegramId)
.message(message)
.build()
)
);
}
}
@ -63,6 +64,12 @@ public class SchedulerChangeParsing {
case CONFLICT_PR:
message = Message.generate(((ConflictPrChange) change));
break;
case NEW_COMMENT:
message = Message.generate(((CommentChange) change));
break;
case NEW_ANSWERS_COMMENT:
message = Message.generate(((AnswerCommentChange) change));
break;
default:
throw new NotFoundException("Нет обработчика для типа " + change.getType().name());
}

View File

@ -1,17 +1,18 @@
package com.tsc.bitbucketbot.scheduler;
import com.tsc.bitbucketbot.config.BitbucketConfig;
import com.tsc.bitbucketbot.domain.MessageSend;
import com.tsc.bitbucketbot.domain.Answer;
import com.tsc.bitbucketbot.domain.Pagination;
import com.tsc.bitbucketbot.domain.change.AnswerCommentChange;
import com.tsc.bitbucketbot.domain.change.CommentChange;
import com.tsc.bitbucketbot.domain.entity.Comment;
import com.tsc.bitbucketbot.domain.entity.PullRequest;
import com.tsc.bitbucketbot.dto.bitbucket.CommentJson;
import com.tsc.bitbucketbot.service.ChangeService;
import com.tsc.bitbucketbot.service.CommentService;
import com.tsc.bitbucketbot.service.MessageSendService;
import com.tsc.bitbucketbot.service.PullRequestsService;
import com.tsc.bitbucketbot.service.UserService;
import com.tsc.bitbucketbot.service.Utils;
import com.tsc.bitbucketbot.utils.Message;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -19,7 +20,8 @@ import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@ -33,17 +35,17 @@ import java.util.stream.Collectors;
public class SchedulerComments {
private static final Integer COUNT = 100;
private static final Integer NO_COMMENT = 100;
private static final Integer NO_COMMENT = 30;
private static final Pattern PATTERN = Pattern.compile("@[\\w]+");
private final CommentService commentService;
private final PullRequestsService pullRequestsService;
private final MessageSendService messageSendService;
private final UserService userService;
private final ChangeService changeService;
private final BitbucketConfig bitbucketConfig;
@Scheduled(cron = "0 */5 8-18 * * MON-FRI")
@Scheduled(cron = "0 */4 8-18 * * MON-FRI")
public void newComments() {
log.info("Начало сканирования комментариев");
long commentId = commentService.getLastCommentId() + 1;
@ -58,7 +60,7 @@ public class SchedulerComments {
if (optCommentJson.isPresent()) {
final CommentJson commentJson = optCommentJson.get();
notification(commentJson, pullRequest);
saveComments(commentJson, commentUrl);
saveComments(commentJson, commentUrl, pullRequest.getUrl());
count = 0;
break;
}
@ -73,7 +75,7 @@ public class SchedulerComments {
@Scheduled(cron = "0 */1 8-18 * * MON-FRI")
public void oldComments() {
@NonNull final List<Comment> comments = commentService.getAllBetweenDate(LocalDate.now().minusDays(10), LocalDate.now());
@NonNull final List<Comment> comments = commentService.getAllBetweenDate(LocalDateTime.now().minusDays(10), LocalDateTime.now());
for (Comment comment : comments) {
final Optional<CommentJson> optCommentJson = Utils.urlToJson(
comment.getUrl(),
@ -83,19 +85,23 @@ public class SchedulerComments {
if (optCommentJson.isPresent()) {
final CommentJson commentJson = optCommentJson.get();
final Set<Long> oldAnswerIds = comment.getAnswers();
final List<CommentJson> answerJsons = commentJson.getComments().stream()
final List<CommentJson> newAnswers = commentJson.getComments().stream()
.filter(answerJson -> !oldAnswerIds.contains(answerJson.getId()))
.collect(Collectors.toList());
if (!answerJsons.isEmpty()) {
userService.getTelegramIdByLogin(commentJson.getAuthor().getName()).ifPresent(
telegramAuthorComment -> messageSendService.add(
MessageSend.builder()
.telegramId(telegramAuthorComment)
.message(Message.answerComment(commentJson.getText(), answerJsons))
.build()
)
if (!newAnswers.isEmpty()) {
changeService.add(
AnswerCommentChange.builder()
.telegramId(userService.getTelegramIdByLogin(commentJson.getAuthor().getName()).orElse(null))
.url(comment.getPrUrl())
.youMessage(commentJson.getText())
.answers(
newAnswers.stream()
.map(json -> Answer.of(json.getAuthor().getName(), json.getText()))
.collect(Collectors.toList())
)
.build()
);
comment.getAnswers().addAll(answerJsons.stream().map(CommentJson::getId).collect(Collectors.toList()));
comment.getAnswers().addAll(newAnswers.stream().map(CommentJson::getId).collect(Collectors.toList()));
commentService.save(comment);
}
}
@ -103,11 +109,12 @@ public class SchedulerComments {
}
@NonNull
private void saveComments(CommentJson comment, String commentUrl) {
private void saveComments(CommentJson comment, String commentUrl, String prUrl) {
final Comment newComment = new Comment();
newComment.setId(comment.getId());
newComment.setDate(LocalDate.now());
newComment.setDate(LocalDateTime.now());
newComment.setUrl(commentUrl);
newComment.setPrUrl(prUrl);
userService.getTelegramIdByLogin(comment.getAuthor().getName()).ifPresent(newComment::setTelegram);
commentService.save(newComment);
}
@ -126,17 +133,21 @@ public class SchedulerComments {
private void notificationPersonal(@NonNull CommentJson comment, @NonNull PullRequest pullRequest) {
Matcher matcher = PATTERN.matcher(comment.getText());
Set<String> recipientsLogins = new HashSet<>();
while (matcher.find()) {
final String login = matcher.group(0).replace("@", "");
userService.getTelegramIdByLogin(login).ifPresent(
telegramId -> messageSendService.add(
MessageSend.builder()
.telegramId(telegramId)
.message(Message.personalNotify(comment, pullRequest.getName(), pullRequest.getUrl()))
.build()
)
);
recipientsLogins.add(login);
}
final List<Long> recipientsIds = userService.getAllTelegramIdByLogin(recipientsLogins);
changeService.add(
CommentChange.builder()
.authorName(comment.getAuthor().getName())
.name(pullRequest.getName())
.url(pullRequest.getUrl())
.telegramId(recipientsIds)
.message(comment.getText())
.build()
);
}
}

View File

@ -43,26 +43,18 @@ public class SchedulerNotification {
}
}
// @Scheduled(cron = "0 0 18 * * FRI")
// @Scheduled(fixedRate = 30000)
@Scheduled(cron = "0 0 18 * * FRI")
public void goodWeekEnd() {
// List<User> allRegister = userService.getAllRegister();
// for (User user : allRegister) {
// messageSendService.add(
// MessageSend.builder()
// .telegramId(user.getTelegramId())
// .message(Message.goodWeekEnd())
// .build()
// );
// reportService.generateReport(user.getLogin());
// }
final User user = userService.getByLogin("mstruchkov").get();
messageSendService.add(
MessageSend.builder()
.telegramId(user.getTelegramId())
.message(reportService.generateReport(user.getLogin()))
.build()
);
List<User> allRegister = userService.getAllRegister();
for (User user : allRegister) {
messageSendService.add(
MessageSend.builder()
.telegramId(user.getTelegramId())
.message(Message.goodWeekEnd())
.build()
);
reportService.generateReport(user.getLogin());
}
}
}

View File

@ -5,7 +5,7 @@ import com.tsc.bitbucketbot.domain.entity.Comment;
import lombok.NonNull;
import org.springframework.data.domain.Page;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
public interface CommentService {
@ -15,7 +15,7 @@ public interface CommentService {
Page<Comment> getAll(@NonNull Pagination pagination);
@NonNull
List<Comment> getAllBetweenDate(LocalDate dateFrom, LocalDate dateTo);
List<Comment> getAllBetweenDate(LocalDateTime dateFrom, LocalDateTime dateTo);
void save(@NonNull Comment comment);

View File

@ -1,5 +1,6 @@
package com.tsc.bitbucketbot.service.impl;
import com.tsc.bitbucketbot.config.InitConfig;
import com.tsc.bitbucketbot.domain.Pagination;
import com.tsc.bitbucketbot.domain.entity.Comment;
import com.tsc.bitbucketbot.repository.jpa.CommentRepository;
@ -10,7 +11,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
@Service
@ -18,10 +19,15 @@ import java.util.List;
public class CommentServiceImpl implements CommentService {
private final CommentRepository commentRepository;
private final InitConfig initConfig;
@Override
public Long getLastCommentId() {
return commentRepository.findFirstByOrderByIdDesc().map(Comment::getId).orElse(0L);
return commentRepository.findFirstByOrderByIdDesc().map(Comment::getId).orElse(getInitCommentId());
}
private Long getInitCommentId() {
return initConfig.getStartCommentId() != null ? initConfig.getStartCommentId() : 0L;
}
@Override
@ -30,7 +36,7 @@ public class CommentServiceImpl implements CommentService {
}
@Override
public @NonNull List<Comment> getAllBetweenDate(LocalDate dateFrom, LocalDate dateTo) {
public @NonNull List<Comment> getAllBetweenDate(LocalDateTime dateFrom, LocalDateTime dateTo) {
return commentRepository.findByDateBetween(dateFrom, dateTo);
}

View File

@ -1,5 +1,7 @@
package com.tsc.bitbucketbot.utils;
import com.tsc.bitbucketbot.domain.change.AnswerCommentChange;
import com.tsc.bitbucketbot.domain.change.CommentChange;
import com.tsc.bitbucketbot.domain.change.ConflictPrChange;
import com.tsc.bitbucketbot.domain.change.NewPrChange;
import com.tsc.bitbucketbot.domain.change.ReviewersPrChange;
@ -148,19 +150,19 @@ public class Message {
comment.getAuthor().getName() + ": " + comment.getText().replaceAll("@[\\w]+", "");
}
public static String personalNotify(@NonNull CommentJson comment, @NonNull String namePr, @NonNull String urlPr) {
return Smile.BELL + " *Новое упоминание* | " + comment.getAuthor().getName() + Smile.BR +
link(namePr, urlPr) +
public static String generate(@NonNull CommentChange commentChange) {
return Smile.BELL + " *Новое упоминание* | " + commentChange.getAuthorName() + Smile.BR +
link(commentChange.getName(), commentChange.getUrl()) +
Smile.HR +
comment.getText().replaceAll("@[\\w]+", "");
commentChange.getMessage().replaceAll("@[\\w]+", "");
}
public static String answerComment(@NonNull String commentMessage, @NonNull List<CommentJson> answerJsons) {
public static String generate(@NonNull AnswerCommentChange answerCommentChange) {
final StringBuilder message = new StringBuilder();
message.append(Smile.BELL).append("Новые ответы на ваш комментарий").append(Smile.HR)
.append(commentMessage, 0, Math.min(commentMessage.length(), 180)).append(Smile.HR);
answerJsons.forEach(answerJson -> message.append(answerJson.getAuthor().getName()).append(": ")
.append(answerJson.getText(), 0, Math.min(answerJson.getText().length(), 500)).append(Smile.TWO_BR));
message.append(Smile.BELL).append("Новые ответы на ваш комментарий").append(" | ").append(link("ПР", answerCommentChange.getUrl())).append(Smile.HR)
.append(answerCommentChange.getYouMessage(), 0, Math.min(answerCommentChange.getYouMessage().length(), 180)).append(Smile.HR);
answerCommentChange.getAnswers().forEach(answer -> message.append(answer.getAuthorName()).append(": ")
.append(answer.getMessage(), 0, Math.min(answer.getMessage().length(), 500)).append(Smile.TWO_BR));
return message.toString();
}

View File

@ -17,6 +17,8 @@ spring:
lob:
non_contextual_creation: true
bitbucketbot:
init:
start-comment-id:
server-send:
url: http://188.225.35.149:8080/api/send
bitbucket:

View File

@ -15,4 +15,10 @@
</update>
</changeSet>
<changeSet id="add-column-comment-pr_url" author="upagge">
<addColumn tableName="comment" schemaName="public" catalogName="pg_catalog">
<column name="pr_url" type="varchar(300)"/>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

@ -18,7 +18,7 @@
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>