Первая рабочая версия
This commit is contained in:
parent
71de4746fd
commit
2739efff32
@ -0,0 +1,15 @@
|
||||
package com.tsc.bitbucketbot.bitbucket;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
*
|
||||
* @author upagge [04.02.2020]
|
||||
*/
|
||||
@Data
|
||||
public class FromRefJson {
|
||||
|
||||
private RepositoryJson repository;
|
||||
|
||||
}
|
@ -20,5 +20,6 @@ public class PullRequestJson {
|
||||
private LinkJson links;
|
||||
private UserDecisionJson author;
|
||||
private List<UserDecisionJson> reviewers;
|
||||
private FromRefJson fromRef;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package com.tsc.bitbucketbot.bitbucket;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
*
|
||||
* @author upagge [04.02.2020]
|
||||
*/
|
||||
@Data
|
||||
public class RepositoryJson {
|
||||
|
||||
private Long id;
|
||||
|
||||
}
|
@ -1,12 +1,23 @@
|
||||
package com.tsc.bitbucketbot.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* TODO: Добавить комментарий енума.
|
||||
*
|
||||
* @author upagge [01.02.2020]
|
||||
*/
|
||||
@Getter
|
||||
public enum ReviewerStatus {
|
||||
|
||||
NEEDS_WORK, APPROVED, UNAPPROVED
|
||||
NEEDS_WORK("'NEEDS WORK'"),
|
||||
APPROVED("'APPROVED'"),
|
||||
UNAPPROVED("'UNAPPROVED'");
|
||||
|
||||
private String value;
|
||||
|
||||
ReviewerStatus(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,21 +32,29 @@ import java.util.List;
|
||||
@Setter
|
||||
@Entity
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(of = "id")
|
||||
@ToString
|
||||
public class PullRequest {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "bitbucket_pr_id")
|
||||
private Long bitbucketId;
|
||||
|
||||
@Column(name = "repository_id")
|
||||
private Long repositoryId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "autor_login")
|
||||
@JoinColumn(name = "author_login")
|
||||
private User author;
|
||||
|
||||
@OneToMany(mappedBy = "pullRequestId", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
|
||||
@JoinColumn(name = "pull_request_id")
|
||||
private List<Reviewer> reviewers;
|
||||
|
||||
@Column(name = "url")
|
||||
@ -59,4 +67,20 @@ public class PullRequest {
|
||||
@Column(name = "status")
|
||||
private PullRequestStatus status;
|
||||
|
||||
// public void setReviewers(List<Reviewer> reviewers) {
|
||||
// this.reviewers = reviewers;
|
||||
// this.reviewers.forEach(reviewer -> reviewer.setPullRequest(this));
|
||||
// }
|
||||
//
|
||||
// public PullRequest(Long bitbucketId, Long repositoryId, User author, List<Reviewer> reviewers, String url, String name, PullRequestStatus status) {
|
||||
// this.bitbucketId = bitbucketId;
|
||||
// this.repositoryId = repositoryId;
|
||||
// this.author = author;
|
||||
// this.reviewers = reviewers;
|
||||
// this.url = url;
|
||||
// this.name = name;
|
||||
// this.status = status;
|
||||
// this.reviewers.forEach(reviewer -> reviewer.setPullRequest(this));
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -35,13 +35,6 @@ public class Reviewer {
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
// @OneToMany(fetch = FetchType.LAZY)
|
||||
// @JoinColumn(name = "pull_request_id")
|
||||
@Column(name = "pull_request_id")
|
||||
private Long pullRequestId;
|
||||
|
||||
// @OneToMany(fetch = FetchType.LAZY)
|
||||
// @JoinColumn(name = "user_login")
|
||||
@Column(name = "user_login")
|
||||
private String user;
|
||||
|
||||
@ -49,5 +42,4 @@ public class Reviewer {
|
||||
@Column(name = "status")
|
||||
private ReviewerStatus status;
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
package com.tsc.bitbucketbot.domain.util;
|
||||
|
||||
import com.tsc.bitbucketbot.domain.ReviewerStatus;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
*
|
||||
* @author upagge [07.02.2020]
|
||||
*/
|
||||
@Getter
|
||||
public class ReviewerChange {
|
||||
|
||||
private String name;
|
||||
private Type type;
|
||||
private ReviewerStatus status;
|
||||
private ReviewerStatus oldStatus;
|
||||
|
||||
private ReviewerChange(String name, Type type, ReviewerStatus status) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
private ReviewerChange(String name, Type type, ReviewerStatus status, ReviewerStatus oldStatus) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.status = status;
|
||||
this.oldStatus = oldStatus;
|
||||
}
|
||||
|
||||
private ReviewerChange(String name, Type type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ReviewerChange ofNew(String name, ReviewerStatus reviewerStatus) {
|
||||
return new ReviewerChange(name, Type.NEW, reviewerStatus);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ReviewerChange ofOld(String name, ReviewerStatus oldStatus, ReviewerStatus newStatus) {
|
||||
return new ReviewerChange(name, Type.OLD, newStatus, oldStatus);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ReviewerChange ofDeleted(String name) {
|
||||
return new ReviewerChange(name, Type.DELETED);
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
NEW, DELETED, OLD
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,11 @@ package com.tsc.bitbucketbot.repository;
|
||||
|
||||
import com.tsc.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -14,4 +18,11 @@ public interface PullRequestsRepository extends JpaRepository<PullRequest, Long>
|
||||
|
||||
Set<PullRequest> findAllByIdIn(Set<Long> ids);
|
||||
|
||||
Boolean existsByBitbucketIdAndRepositoryId(Long bitbucketId, Long repositoryId);
|
||||
|
||||
@Query("SELECT p.id FROM PullRequest p WHERE p.bitbucketId=:bitbucketId AND p.repositoryId=:repositoryId")
|
||||
Optional<Long> findIdByBitbucketIdAndRepositoryId(@Param("bitbucketId") Long bitbucketId, @Param("repositoryId") Long repositoryId);
|
||||
|
||||
void deleteAllByIdIn(Collection<Long> id);
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.tsc.bitbucketbot.scheduler;
|
||||
|
||||
import com.tsc.bitbucketbot.bitbucket.PullRequestJson;
|
||||
import com.tsc.bitbucketbot.bitbucket.UserDecisionJson;
|
||||
import com.tsc.bitbucketbot.bitbucket.sheet.PullRequestSheetJson;
|
||||
import com.tsc.bitbucketbot.config.BitbucketConfig;
|
||||
import com.tsc.bitbucketbot.domain.PullRequestStatus;
|
||||
@ -9,10 +8,13 @@ import com.tsc.bitbucketbot.domain.ReviewerStatus;
|
||||
import com.tsc.bitbucketbot.domain.entity.PullRequest;
|
||||
import com.tsc.bitbucketbot.domain.entity.Reviewer;
|
||||
import com.tsc.bitbucketbot.domain.entity.User;
|
||||
import com.tsc.bitbucketbot.domain.util.ReviewerChange;
|
||||
import com.tsc.bitbucketbot.service.PullRequestsService;
|
||||
import com.tsc.bitbucketbot.service.UserService;
|
||||
import com.tsc.bitbucketbot.service.Utils;
|
||||
import com.tsc.bitbucketbot.service.converter.PullRequestJsonConverter;
|
||||
import com.tsc.bitbucketbot.utils.Message;
|
||||
import javafx.util.Pair;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.social.core.domain.BoxAnswer;
|
||||
@ -21,9 +23,11 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@ -37,8 +41,8 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class SchedulerPullRequest {
|
||||
|
||||
private static final String URL_NEW_PR = "http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN";
|
||||
private static final String URL_OLD_PR = "http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&closedSince=86400";
|
||||
private static final String URL_OPEN_PR = "http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN";
|
||||
private static final String URL_CLOSE_PR = "http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&closedSince=86400";
|
||||
private final BitbucketConfig bitbucketConfig;
|
||||
private final PullRequestsService pullRequestsService;
|
||||
private final UserService userService;
|
||||
@ -46,34 +50,48 @@ public class SchedulerPullRequest {
|
||||
private final Sending sending;
|
||||
|
||||
@Scheduled(fixedRate = 15000)
|
||||
public void checkOldPullRequest() {
|
||||
public void checkClosePullRequest() {
|
||||
final List<User> users = userService.getAllRegistered();
|
||||
for (User user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(URL_OLD_PR, user.getToken(), PullRequestSheetJson.class);
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(URL_CLOSE_PR, user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) {
|
||||
final PullRequestSheetJson pullRequestBitbucketSheet = sheetJson.get();
|
||||
Set<Long> existsId = pullRequestsService.existsById(
|
||||
pullRequestBitbucketSheet.getValues().stream()
|
||||
.map(PullRequestJson::getId)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
final Map<Long, PullRequestJson> existsPullRequestBitbucket = pullRequestBitbucketSheet.getValues().stream()
|
||||
.filter(pullRequestJson -> existsId.contains(pullRequestJson.getId()))
|
||||
.collect(Collectors.toMap(PullRequestJson::getId, pullRequestJson -> pullRequestJson));
|
||||
final Set<PullRequest> pullRequests = pullRequestsService.getAllById(existsId);
|
||||
if (!existsPullRequestBitbucket.isEmpty() && !pullRequests.isEmpty()) {
|
||||
processingUpdate(existsPullRequestBitbucket, pullRequests);
|
||||
final List<PullRequestJson> bitbucketPullRequests = pullRequestBitbucketSheet.getValues().stream()
|
||||
.filter(
|
||||
pullRequestJson -> pullRequestsService.existsByBitbucketIdAndReposId(
|
||||
pullRequestJson.getId(),
|
||||
pullRequestJson.getFromRef().getRepository().getId()
|
||||
)
|
||||
)
|
||||
.collect(Collectors.toList());
|
||||
final Set<Long> pullRequestId = bitbucketPullRequests.stream()
|
||||
.map(
|
||||
pullRequestJson -> pullRequestsService.getIdByBitbucketIdAndReposId(
|
||||
pullRequestJson.getId(),
|
||||
pullRequestJson.getFromRef().getRepository().getId()
|
||||
)
|
||||
)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
for (PullRequestJson bitbucketPullRequest : bitbucketPullRequests) {
|
||||
final Optional<User> optUser = userService.getByLogin(bitbucketPullRequest.getAuthor().getUser().getName());
|
||||
if (optUser.isPresent()) {
|
||||
final User author = optUser.get();
|
||||
final Long telegramId = author.getTelegramId();
|
||||
if (telegramId != null) {
|
||||
final PullRequestStatus pullRequestStatus = PullRequestJsonConverter.convertPullRequestStatus(bitbucketPullRequest.getState());
|
||||
@NonNull final String message = Message.statusPullRequest(bitbucketPullRequest.getTitle(), bitbucketPullRequest.getLinks().getSelf().get(0).getHref(), PullRequestStatus.OPEN, pullRequestStatus);
|
||||
sending.send(telegramId, BoxAnswer.of(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!existsPullRequestBitbucket.isEmpty()) {
|
||||
pullRequestsService.updateAll(
|
||||
existsPullRequestBitbucket.values().stream()
|
||||
.map(pullRequestBitbucket -> conversionService.convert(pullRequestBitbucket, PullRequest.class))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
pullRequestsService.deleteAll(pullRequestId);
|
||||
|
||||
if (pullRequestBitbucketSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(URL_OLD_PR + pullRequestBitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
sheetJson = Utils.urlToJson(URL_CLOSE_PR + pullRequestBitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -81,76 +99,113 @@ public class SchedulerPullRequest {
|
||||
}
|
||||
}
|
||||
|
||||
private void processingUpdate(Map<Long, PullRequestJson> existsPullRequestBitbucket, Set<PullRequest> pullRequests) {
|
||||
@Scheduled(fixedRate = 15000)
|
||||
public void checkOldPullRequest() {
|
||||
final List<User> users = userService.getAllRegistered();
|
||||
for (User user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(URL_OPEN_PR, user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) {
|
||||
final PullRequestSheetJson pullRequestBitbucketSheet = sheetJson.get();
|
||||
final Map<Long, PullRequest> existsPullRequestBitbucket = pullRequestBitbucketSheet.getValues().stream()
|
||||
.filter(
|
||||
pullRequestJson -> pullRequestsService.existsByBitbucketIdAndReposId(
|
||||
pullRequestJson.getId(),
|
||||
pullRequestJson.getFromRef().getRepository().getId()
|
||||
)
|
||||
)
|
||||
.map(pullRequestJson -> conversionService.convert(pullRequestJson, PullRequest.class))
|
||||
.filter(Objects::nonNull)
|
||||
.peek(pullRequest -> pullRequestsService.getIdByBitbucketIdAndReposId(pullRequest.getBitbucketId(), pullRequest.getRepositoryId()).ifPresent(pullRequest::setId))
|
||||
.collect(Collectors.toMap(PullRequest::getId, pullRequest -> pullRequest));
|
||||
final Set<PullRequest> pullRequests = pullRequestsService.getAllById(existsPullRequestBitbucket.keySet());
|
||||
if (!existsPullRequestBitbucket.isEmpty() && !pullRequests.isEmpty()) {
|
||||
pullRequestsService.updateAll(processingUpdate(existsPullRequestBitbucket, pullRequests));
|
||||
}
|
||||
|
||||
if (pullRequestBitbucketSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(URL_CLOSE_PR + pullRequestBitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private List<PullRequest> processingUpdate(Map<Long, PullRequest> newPullRequests, Set<PullRequest> pullRequests) {
|
||||
List<PullRequest> updatePullRequest = new ArrayList<>();
|
||||
for (PullRequest pullRequest : pullRequests) {
|
||||
final PullRequestJson pullRequestBitbucket = existsPullRequestBitbucket.get(pullRequest.getId());
|
||||
final PullRequest newPullRequest = newPullRequests.get(pullRequest.getId());
|
||||
final User author = pullRequest.getAuthor();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (author.getTelegramId() != null) {
|
||||
sendStatusPR(pullRequest, pullRequestBitbucket);
|
||||
sendReviewersPR(pullRequest, pullRequestBitbucket);
|
||||
changeStatusPR(pullRequest, newPullRequest).ifPresent(stringBuilder::append);
|
||||
changeReviewersPR(pullRequest, newPullRequest).ifPresent(stringBuilder::append);
|
||||
final String message = stringBuilder.toString();
|
||||
if (!Message.EMPTY.equalsIgnoreCase(message)) {
|
||||
updatePullRequest.add(newPullRequest);
|
||||
sending.send(author.getTelegramId(), BoxAnswer.of(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
return updatePullRequest;
|
||||
}
|
||||
|
||||
private void sendReviewersPR(PullRequest pullRequest, PullRequestJson pullRequestBitbucket) {
|
||||
final Map<String, Reviewer> oldReviewers = pullRequest.getReviewers().stream().collect(Collectors.toMap(Reviewer::getUser, reviewer -> reviewer));
|
||||
final List<UserDecisionJson> newReviewers = pullRequestBitbucket.getReviewers();
|
||||
for (UserDecisionJson newReviewer : newReviewers) {
|
||||
if (oldReviewers.containsKey(newReviewer.getUser().getName())) {
|
||||
final Reviewer oldReviewer = oldReviewers.get(newReviewer.getUser().getName());
|
||||
@NonNull
|
||||
private Optional<String> changeReviewersPR(PullRequest pullRequest, PullRequest newPullRequest) {
|
||||
final Map<String, Reviewer> oldReviewers = pullRequest.getReviewers().stream()
|
||||
.collect(Collectors.toMap(Reviewer::getUser, reviewer -> reviewer));
|
||||
final Map<String, Reviewer> newReviewers = newPullRequest.getReviewers().stream()
|
||||
.collect(Collectors.toMap(Reviewer::getUser, reviewer -> reviewer));
|
||||
List<ReviewerChange> reviewerChanges = new ArrayList<>();
|
||||
for (Reviewer newReviewer : newReviewers.values()) {
|
||||
if (oldReviewers.containsKey(newReviewer.getUser())) {
|
||||
final Reviewer oldReviewer = oldReviewers.get(newReviewer.getUser());
|
||||
final ReviewerStatus oldStatus = oldReviewer.getStatus();
|
||||
final ReviewerStatus newStatus = PullRequestJsonConverter.convertStatusReviewer(newReviewer.getStatus());
|
||||
boolean flag = false;
|
||||
StringBuilder stringBuilder = new StringBuilder("✏️ *Изменилось решение по вашему ПР*\n")
|
||||
.append("[").append(pullRequest.getName()).append("](").append(pullRequest.getUrl()).append(")\n");
|
||||
final ReviewerStatus newStatus = newReviewer.getStatus();
|
||||
if (!oldStatus.equals(newStatus)) {
|
||||
flag = true;
|
||||
stringBuilder.append("\uD83D\uDC68\u200D\uD83D\uDCBB️ ").append(oldReviewer.getUser()).append(" ")
|
||||
.append(oldStatus).append(" -> ").append(newStatus).append("\n");
|
||||
}
|
||||
if (flag) {
|
||||
sending.send(pullRequest.getAuthor().getTelegramId(), BoxAnswer.of(stringBuilder.toString()));
|
||||
reviewerChanges.add(ReviewerChange.ofOld(oldReviewer.getUser(), oldStatus, newStatus));
|
||||
}
|
||||
} else {
|
||||
reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getUser(), newReviewer.getStatus()));
|
||||
}
|
||||
}
|
||||
final Set<String> oldLogins = oldReviewers.keySet();
|
||||
oldLogins.removeAll(newReviewers.keySet());
|
||||
oldLogins.forEach(login -> reviewerChanges.add(ReviewerChange.ofDeleted(login)));
|
||||
return Message.statusReviewers(pullRequest, reviewerChanges);
|
||||
}
|
||||
|
||||
private void sendStatusPR(PullRequest pullRequest, PullRequestJson pullRequestBitbucket) {
|
||||
|
||||
@NonNull
|
||||
private Optional<String> changeStatusPR(PullRequest pullRequest, PullRequest newPullRequest) {
|
||||
final PullRequestStatus oldStatus = pullRequest.getStatus();
|
||||
final PullRequestStatus newStatus = PullRequestJsonConverter.convertPullRequestStatus(pullRequestBitbucket.getState());
|
||||
final PullRequestStatus newStatus = newPullRequest.getStatus();
|
||||
if (!oldStatus.equals(newStatus)) {
|
||||
StringBuilder stringBuilder = new StringBuilder("✏️ *Изменился статус вашего ПР*\n")
|
||||
.append("[").append(pullRequest.getName()).append("](").append(pullRequest.getUrl()).append(")\n")
|
||||
.append(oldStatus.name()).append(" -> ").append(newStatus.name())
|
||||
.append("\n-- -- -- --\n")
|
||||
.append("\uD83D\uDCCC: #pullRequest #change")
|
||||
.append("\n\n");
|
||||
sending.send(pullRequest.getAuthor().getTelegramId(), BoxAnswer.of(stringBuilder.toString()));
|
||||
return Optional.of(Message.statusPullRequest(pullRequest.getName(), pullRequest.getUrl(), oldStatus, newStatus));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
@Scheduled(fixedRate = 15000)
|
||||
public void checkNewPullRequest() {
|
||||
final List<User> users = userService.getAllRegistered();
|
||||
for (User user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(URL_NEW_PR, user.getToken(), PullRequestSheetJson.class);
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(URL_OPEN_PR, user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) {
|
||||
final PullRequestSheetJson pullRequestBitbucketSheet = sheetJson.get();
|
||||
final Set<Long> pullRequestBitbucketId = pullRequestBitbucketSheet.getValues().stream()
|
||||
.map(PullRequestJson::getId)
|
||||
.collect(Collectors.toSet());
|
||||
Set<Long> existsId = pullRequestsService.existsAllIdById(pullRequestBitbucketId);
|
||||
final Set<PullRequestJson> newPullRequestBitbucket = pullRequestBitbucketSheet.getValues().stream()
|
||||
.filter(pullRequestJson -> !existsId.contains(pullRequestJson.getId()))
|
||||
.collect(Collectors.toSet());
|
||||
final List<PullRequest> newPullRequests = pullRequestsService.addAll(
|
||||
newPullRequestBitbucket.stream()
|
||||
.map(pullRequestJson -> conversionService.convert(pullRequestJson, PullRequest.class))
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
final List<PullRequest> newPullRequest = pullRequestBitbucketSheet.getValues().stream()
|
||||
.collect(Collectors.toMap(pullRequestJson -> new Pair<>(pullRequestJson.getId(), pullRequestJson.getFromRef().getRepository().getId()), pullRequestJson -> pullRequestJson))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(test -> !pullRequestsService.existsByBitbucketIdAndReposId(test.getKey().getKey(), test.getKey().getValue()))
|
||||
.map(test -> conversionService.convert(test.getValue(), PullRequest.class))
|
||||
.collect(Collectors.toList());
|
||||
final List<PullRequest> newPullRequests = pullRequestsService.addAll(newPullRequest);
|
||||
sendNotification(newPullRequests);
|
||||
if (pullRequestBitbucketSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(URL_NEW_PR + pullRequestBitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
sheetJson = Utils.urlToJson(URL_OPEN_PR + pullRequestBitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.tsc.bitbucketbot.service;
|
||||
|
||||
import com.tsc.bitbucketbot.domain.entity.PullRequest;
|
||||
import com.tsc.bitbucketbot.domain.entity.Reviewer;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@ -15,14 +15,20 @@ import java.util.Set;
|
||||
*/
|
||||
public interface PullRequestsService {
|
||||
|
||||
Set<Long> existsById(@NonNull final Set<Long> pullRequestId);
|
||||
|
||||
Set<Long> existsAllIdById(@NonNull Set<Long> pullRequestId);
|
||||
@NonNull
|
||||
boolean existsByBitbucketIdAndReposId(Long bitbucketId, Long repositoryId);
|
||||
|
||||
Set<PullRequest> getAllById(@NonNull Set<Long> pullRequestJsonId);
|
||||
|
||||
List<PullRequest> addAll(@NonNull Set<PullRequest> pullRequests);
|
||||
List<PullRequest> addAll(@NonNull Collection<PullRequest> pullRequests);
|
||||
|
||||
List<PullRequest> updateAll(@NonNull List<PullRequest> pullRequests);
|
||||
List<PullRequest> updateAll(@NonNull Collection<PullRequest> pullRequests);
|
||||
|
||||
@NonNull
|
||||
Optional<Long> getIdByBitbucketIdAndReposId(Long bitbucketId, Long repositoryId);
|
||||
|
||||
void deleteAll(@NonNull Set<Long> id);
|
||||
|
||||
Optional<PullRequest> update(PullRequest pullRequest);
|
||||
|
||||
}
|
||||
|
@ -33,12 +33,13 @@ public class PullRequestJsonConverter implements Converter<PullRequestJson, Pull
|
||||
@Override
|
||||
public PullRequest convert(PullRequestJson json) {
|
||||
return PullRequest.builder()
|
||||
.id(json.getId())
|
||||
.bitbucketId(json.getId())
|
||||
.repositoryId(json.getFromRef().getRepository().getId())
|
||||
.author(this.convertUser(json.getAuthor().getUser()))
|
||||
.name(json.getTitle())
|
||||
.url(json.getLinks().getSelf().get(0).getHref())
|
||||
.status(convertPullRequestStatus(json.getState()))
|
||||
.reviewers(convertReviewers(json.getId(), json.getReviewers()))
|
||||
.reviewers(convertReviewers(json.getReviewers()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -58,12 +59,11 @@ public class PullRequestJsonConverter implements Converter<PullRequestJson, Pull
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Reviewer> convertReviewers(Long id, List<UserDecisionJson> jsonReviewers) {
|
||||
private List<Reviewer> convertReviewers(List<UserDecisionJson> jsonReviewers) {
|
||||
return jsonReviewers.stream()
|
||||
.map(
|
||||
jsonReviewer -> {
|
||||
final Reviewer reviewer = new Reviewer();
|
||||
reviewer.setPullRequestId(id);
|
||||
reviewer.setUser(jsonReviewer.getUser().getName());
|
||||
reviewer.setStatus(convertStatusReviewer(jsonReviewer.getStatus()));
|
||||
return reviewer;
|
||||
@ -85,5 +85,4 @@ public class PullRequestJsonConverter implements Converter<PullRequestJson, Pull
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.tsc.bitbucketbot.service.impl;
|
||||
|
||||
import com.tsc.bitbucketbot.domain.entity.PullRequest;
|
||||
import com.tsc.bitbucketbot.domain.entity.Reviewer;
|
||||
import com.tsc.bitbucketbot.repository.PullRequestsRepository;
|
||||
import com.tsc.bitbucketbot.service.PullRequestsService;
|
||||
import lombok.NonNull;
|
||||
@ -9,6 +8,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@ -26,15 +26,8 @@ public class PullRequestsServiceImpl implements PullRequestsService {
|
||||
private final PullRequestsRepository pullRequestsRepository;
|
||||
|
||||
@Override
|
||||
public Set<Long> existsById(@NonNull Set<Long> idList) {
|
||||
return idList.stream()
|
||||
.filter(pullRequestsRepository::existsById)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> existsAllIdById(@NonNull Set<Long> pullRequestJsonId) {
|
||||
return pullRequestJsonId.stream().filter(pullRequestsRepository::existsById).collect(Collectors.toSet());
|
||||
public boolean existsByBitbucketIdAndReposId(@NonNull Long bitbucketId, @NonNull Long repositoryId) {
|
||||
return pullRequestsRepository.existsByBitbucketIdAndRepositoryId(bitbucketId, repositoryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,13 +36,36 @@ public class PullRequestsServiceImpl implements PullRequestsService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PullRequest> addAll(@NonNull Set<PullRequest> pullRequests) {
|
||||
@Transactional
|
||||
public List<PullRequest> addAll(@NonNull Collection<PullRequest> pullRequests) {
|
||||
return pullRequestsRepository.saveAll(pullRequests);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PullRequest> updateAll(@NonNull List<PullRequest> pullRequests) {
|
||||
return pullRequestsRepository.saveAll(pullRequests);
|
||||
public List<PullRequest> updateAll(@NonNull Collection<PullRequest> pullRequests) {
|
||||
final List<PullRequest> updatePullRequests = pullRequests.stream()
|
||||
.filter(pullRequest -> pullRequestsRepository.existsById(pullRequest.getId()))
|
||||
.collect(Collectors.toList());
|
||||
return pullRequestsRepository.saveAll(updatePullRequests);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PullRequest> update(PullRequest pullRequest) {
|
||||
if (pullRequestsRepository.existsById(pullRequest.getId())) {
|
||||
pullRequestsRepository.save(pullRequest);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Long> getIdByBitbucketIdAndReposId(@NonNull Long bitbucketId, @NonNull Long repositoryId) {
|
||||
return pullRequestsRepository.findIdByBitbucketIdAndRepositoryId(bitbucketId, repositoryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteAll(@NonNull Set<Long> id) {
|
||||
pullRequestsRepository.deleteAllByIdIn(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
88
src/main/java/com/tsc/bitbucketbot/utils/Message.java
Normal file
88
src/main/java/com/tsc/bitbucketbot/utils/Message.java
Normal file
@ -0,0 +1,88 @@
|
||||
package com.tsc.bitbucketbot.utils;
|
||||
|
||||
import com.tsc.bitbucketbot.domain.PullRequestStatus;
|
||||
import com.tsc.bitbucketbot.domain.entity.PullRequest;
|
||||
import com.tsc.bitbucketbot.domain.util.ReviewerChange;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.tsc.bitbucketbot.domain.util.ReviewerChange.Type.DELETED;
|
||||
import static com.tsc.bitbucketbot.domain.util.ReviewerChange.Type.NEW;
|
||||
import static com.tsc.bitbucketbot.domain.util.ReviewerChange.Type.OLD;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
*
|
||||
* @author upagge [07.02.2020]
|
||||
*/
|
||||
public class Message {
|
||||
|
||||
public static final String EMPTY = "";
|
||||
private static final String BREAK = "\n";
|
||||
private static final String TWO_BREAK = "\n\n";
|
||||
private static final String SMILE_AUTHOR = "\uD83D\uDC68\u200D\uD83D\uDCBB️";
|
||||
private static final String SMILE_PEN = "✏️";
|
||||
|
||||
private Message() {
|
||||
throw new IllegalStateException("Утилитарный класс");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String statusPullRequest(String name, String url, PullRequestStatus oldStatus, PullRequestStatus newStatus) {
|
||||
return "✏️ *Изменился статус вашего ПР*" + BREAK +
|
||||
"[" + name + "](" + url + ")" + BREAK +
|
||||
oldStatus.name() + " -> " + newStatus.name() +
|
||||
BREAK + "-- -- -- --" + BREAK +
|
||||
"\uD83D\uDCCC: #pullRequest #change" +
|
||||
TWO_BREAK;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Optional<String> statusReviewers(PullRequest pullRequest, List<ReviewerChange> reviewerChanges) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
final Map<ReviewerChange.Type, List<ReviewerChange>> changes = reviewerChanges.stream()
|
||||
.collect(Collectors.groupingBy(ReviewerChange::getType));
|
||||
if (changes.containsKey(OLD)) {
|
||||
stringBuilder.append(BREAK).append("Изменили свое решение:").append(BREAK);
|
||||
changes.get(OLD).forEach(
|
||||
change -> stringBuilder
|
||||
.append(SMILE_AUTHOR).append(change.getName()).append(": ")
|
||||
.append(change.getOldStatus().getValue()).append(" -> ")
|
||||
.append(change.getStatus().getValue())
|
||||
.append(BREAK)
|
||||
);
|
||||
}
|
||||
if (changes.containsKey(NEW)) {
|
||||
stringBuilder.append(BREAK).append("Новые ревьюверы:").append(BREAK);
|
||||
changes.get(NEW).forEach(
|
||||
change -> stringBuilder
|
||||
.append(change.getName()).append(" (").append(change.getStatus().getValue()).append(")")
|
||||
.append(BREAK)
|
||||
);
|
||||
}
|
||||
if (changes.containsKey(DELETED)) {
|
||||
stringBuilder.append(BREAK).append("Не выдержали ревью:").append(BREAK)
|
||||
.append(
|
||||
changes.get(DELETED).stream()
|
||||
.map(ReviewerChange::getName).collect(Collectors.joining(","))
|
||||
);
|
||||
}
|
||||
|
||||
final String createMessage = stringBuilder.toString();
|
||||
if (!EMPTY.equalsIgnoreCase(createMessage)) {
|
||||
return Optional.of(
|
||||
SMILE_PEN + " *Изменения ревьюверов вашего ПР*" + BREAK +
|
||||
"[" + pullRequest.getName() + "](" + pullRequest.getUrl() + ")" + BREAK +
|
||||
createMessage
|
||||
+ "\n-- -- -- -- --"
|
||||
);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -22,9 +22,11 @@ bitbucketbot:
|
||||
bot-token: 1096235968:AAHvIy_mlZJXiNc9aDQWtCuiksz9YGknoXE
|
||||
admin-chatid: 3000811
|
||||
proxy-config:
|
||||
host: 167.172.171.134
|
||||
host: 212.237.23.75
|
||||
port: 1080
|
||||
type: SOCKS5
|
||||
user: upagge
|
||||
password: seAbotd9Bidu%ZqZB3g4
|
||||
bitbucket:
|
||||
token: Nzg5NjUyNDQwMzk2OlA+6naQz02+GxOG0Q9li/jnsn7E
|
||||
url: http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=50
|
||||
|
@ -18,10 +18,12 @@
|
||||
</createTable>
|
||||
|
||||
<createTable tableName="pull_request">
|
||||
<column name="id" type="integer">
|
||||
<column name="id" type="integer" autoIncrement="true">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="autor_login" type="varchar(100)">
|
||||
<column name="bitbucket_pr_id" type="integer"/>
|
||||
<column name="repository_id" type="integer"/>
|
||||
<column name="author_login" type="varchar(100)">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="login"
|
||||
references="user(login)"/>
|
||||
@ -34,13 +36,14 @@
|
||||
</column>
|
||||
<column name="name" type="varchar(100)"/>
|
||||
</createTable>
|
||||
<addUniqueConstraint tableName="pull_request" columnNames="bitbucket_pr_id, repository_id"/>
|
||||
|
||||
<createTable tableName="reviewer">
|
||||
<column name="id" type="integer" autoIncrement="true">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="pull_request_id" type="integer">
|
||||
<constraints nullable="false" foreignKeyName="fk_pull_request_id" references="pull_request(id)"/>
|
||||
<constraints foreignKeyName="fk_pull_request_id" references="pull_request(id)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="user_login" type="varchar(100)">
|
||||
<constraints nullable="false"
|
||||
@ -50,7 +53,6 @@
|
||||
<column name="status" type="varchar(50)"/>
|
||||
</createTable>
|
||||
<addUniqueConstraint tableName="reviewer" columnNames="pull_request_id, user_login"/>
|
||||
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
Loading…
Reference in New Issue
Block a user