diff --git a/src/main/java/com/tsc/bitbucketbot/domain/PullRequestStatus.java b/src/main/java/com/tsc/bitbucketbot/domain/PullRequestStatus.java index cd5fa14..a4a3d5b 100644 --- a/src/main/java/com/tsc/bitbucketbot/domain/PullRequestStatus.java +++ b/src/main/java/com/tsc/bitbucketbot/domain/PullRequestStatus.java @@ -7,6 +7,6 @@ package com.tsc.bitbucketbot.domain; */ public enum PullRequestStatus { - OPEN, MERGED, DECLINED + OPEN, MERGED, DECLINED, DELETE } diff --git a/src/main/java/com/tsc/bitbucketbot/dto/IdAndStatusPr.java b/src/main/java/com/tsc/bitbucketbot/dto/IdAndStatusPr.java new file mode 100644 index 0000000..ee28df5 --- /dev/null +++ b/src/main/java/com/tsc/bitbucketbot/dto/IdAndStatusPr.java @@ -0,0 +1,16 @@ +package com.tsc.bitbucketbot.dto; + +import com.tsc.bitbucketbot.domain.PullRequestStatus; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@AllArgsConstructor +public class IdAndStatusPr { + + private Long id; + private PullRequestStatus status; + +} diff --git a/src/main/java/com/tsc/bitbucketbot/repository/jpa/PullRequestsRepository.java b/src/main/java/com/tsc/bitbucketbot/repository/jpa/PullRequestsRepository.java index dfe7e62..973406c 100644 --- a/src/main/java/com/tsc/bitbucketbot/repository/jpa/PullRequestsRepository.java +++ b/src/main/java/com/tsc/bitbucketbot/repository/jpa/PullRequestsRepository.java @@ -1,19 +1,20 @@ package com.tsc.bitbucketbot.repository.jpa; +import com.tsc.bitbucketbot.domain.PullRequestStatus; import com.tsc.bitbucketbot.domain.ReviewerStatus; import com.tsc.bitbucketbot.domain.entity.PullRequest; +import com.tsc.bitbucketbot.dto.IdAndStatusPr; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.Set; /** - * TODO: Добавить описание интерфейса. - * * @author upagge [31.01.2020] */ public interface PullRequestsRepository extends JpaRepository { @@ -33,7 +34,13 @@ public interface PullRequestsRepository extends JpaRepository @Query("SELECT p FROM PullRequest p LEFT JOIN p.reviewers r WHERE p.author.login=:author AND r.status=:reviewerStatus") List findAllByAuthorAndReviewerStatus(@Param("author") String author, @Param("reviewerStatus") ReviewerStatus reviewerStatus); + @Query("SELECT new com.tsc.bitbucketbot.dto.IdAndStatusPr(p.id, p.status) FROM PullRequest p WHERE p.status IN :statuses") + Set findAllIdByStatusIn(@Param("statuses") Collection statuses); + @Query("SELECT p.id from PullRequest p") - Set getAllIds(); + Set findAllIds(); + + @Query("SELECT p FROM PullRequest p WHERE p.author.login = :login AND p.createDate BETWEEN :dateFrom AND :dateTo") + List findAllByAuthorAndDateBetween(@Param("login") String login, @Param("dateFrom") LocalDateTime dateFrom, @Param("dateTo") LocalDateTime dateTo); } diff --git a/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerNotification.java b/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerNotification.java index 17be936..f433142 100644 --- a/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerNotification.java +++ b/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerNotification.java @@ -6,6 +6,7 @@ import com.tsc.bitbucketbot.domain.entity.PullRequest; import com.tsc.bitbucketbot.domain.entity.User; import com.tsc.bitbucketbot.service.MessageSendService; import com.tsc.bitbucketbot.service.PullRequestsService; +import com.tsc.bitbucketbot.service.ReportService; import com.tsc.bitbucketbot.service.UserService; import com.tsc.bitbucketbot.utils.Message; import lombok.RequiredArgsConstructor; @@ -21,6 +22,7 @@ public class SchedulerNotification { private final UserService userService; private final PullRequestsService pullRequestsService; private final MessageSendService messageSendService; + private final ReportService reportService; // Утреннее сообщение @Scheduled(cron = "0 15 8 * * MON-FRI") @@ -41,17 +43,26 @@ public class SchedulerNotification { } } - @Scheduled(cron = "0 0 18 * * FRI") + // @Scheduled(cron = "0 0 18 * * FRI") +// @Scheduled(fixedRate = 30000) public void goodWeekEnd() { - List allRegister = userService.getAllRegister(); - for (User user : allRegister) { - messageSendService.add( - MessageSend.builder() - .telegramId(user.getTelegramId()) - .message(Message.goodWeekEnd()) - .build() - ); - } +// List 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() + ); } } diff --git a/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerPullRequest.java b/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerPullRequest.java index 3affbe1..2b3b4b8 100644 --- a/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerPullRequest.java +++ b/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerPullRequest.java @@ -8,13 +8,11 @@ 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.dto.bitbucket.PullRequestJson; import com.tsc.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson; 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.service.converter.PullRequestJsonConverter; import com.tsc.bitbucketbot.utils.Message; import com.tsc.bitbucketbot.utils.Pair; import com.tsc.bitbucketbot.utils.Smile; @@ -35,8 +33,6 @@ import java.util.Set; import java.util.stream.Collectors; /** - * TODO: Добавить описание класса. - * * @author upagge [30.01.2020] */ @Service @@ -51,53 +47,60 @@ public class SchedulerPullRequest { @Scheduled(fixedRate = 30000) public void checkOldPullRequest() { - Set existsId = pullRequestsService.getAllId(); - Set openId = checkOpenPullRequest(); - checkClosePullRequest(); - existsId.removeAll(openId); - if (!existsId.isEmpty()) { - pullRequestsService.deleteAll(existsId); + final Set existsId = pullRequestsService.getAllId(); + final Set openId = checkOpenPullRequest(); + final Set closeId = checkClosePullRequest(); + final Set newNotExistsId = existsId.stream() + .filter(id -> !openId.contains(id) && !closeId.contains(id)) + .collect(Collectors.toSet()); + if (!newNotExistsId.isEmpty()) { + updateDeletePr(newNotExistsId); } } - private void checkClosePullRequest() { + private void updateDeletePr(@NonNull Set ids) { + final Set deletePr = pullRequestsService.getAllById(ids); + deletePr.stream() + .filter(pullRequest -> pullRequest.getAuthor().getTelegramId() != null) + .forEach(pullRequest -> messageSendService.add( + MessageSend.builder() + .telegramId(pullRequest.getAuthor().getTelegramId()) + .message(Message.statusPullRequest(pullRequest.getName(), pullRequest.getUrl(), pullRequest.getStatus(), PullRequestStatus.DELETE)) + .build() + )); + pullRequestsService.updateAll( + deletePr.stream() + .peek(pullRequest -> pullRequest.setStatus(PullRequestStatus.DELETE)) + .collect(Collectors.toList()) + ); + } + + private Set checkClosePullRequest() { final List users = userService.getAllRegister(); + final Set ids = new HashSet<>(); for (User user : users) { Optional sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose(), user.getToken(), PullRequestSheetJson.class); while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) { final PullRequestSheetJson bitbucketSheet = sheetJson.get(); - final List jsonsPr = bitbucketSheet.getValues().stream() - .filter( - jsonPr -> pullRequestsService.existsByBitbucketIdAndReposId( - jsonPr.getId(), - jsonPr.getFromRef().getRepository().getId() - ) - ) + final List newPrs = bitbucketSheet.getValues().stream() + .map(jsonPr -> conversionService.convert(jsonPr, PullRequest.class)) + .peek(pullRequest -> pullRequestsService.getIdByBitbucketIdAndReposId(pullRequest.getBitbucketId(), pullRequest.getRepositoryId()).ifPresent(pullRequest::setId)) + .filter(pullRequest -> pullRequest.getId() != null) .collect(Collectors.toList()); - final Set idPr = jsonsPr.stream() - .map( - jsonPr -> pullRequestsService.getIdByBitbucketIdAndReposId( - jsonPr.getId(), - jsonPr.getFromRef().getRepository().getId() - ) - ) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toSet()); - for (PullRequestJson jsonPr : jsonsPr) { - final Optional optUser = userService.getByLogin(jsonPr.getAuthor().getUser().getName()); - if (optUser.isPresent()) { - final User author = optUser.get(); - final Long telegramId = author.getTelegramId(); - if (telegramId != null) { - final PullRequestStatus statusPr = PullRequestJsonConverter.convertPullRequestStatus(jsonPr.getState()); - final String message = Message.statusPullRequest(jsonPr.getTitle(), jsonPr.getLinks().getSelf().get(0).getHref(), PullRequestStatus.OPEN, statusPr); - messageSendService.add(MessageSend.builder().telegramId(telegramId).message(message).build()); - } + for (PullRequest pullRequest : newPrs) { + final User author = pullRequest.getAuthor(); + final Long telegramId = author.getTelegramId(); + if (telegramId != null) { + final String message = Message.statusPullRequest(pullRequest.getName(), pullRequest.getUrl(), PullRequestStatus.OPEN, pullRequest.getStatus()); + messageSendService.add(MessageSend.builder().telegramId(telegramId).message(message).build()); } } - pullRequestsService.deleteAll(idPr); + ids.addAll( + pullRequestsService.updateAll(newPrs).stream() + .map(PullRequest::getId) + .collect(Collectors.toSet()) + ); if (bitbucketSheet.getNextPageStart() != null) { sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose() + bitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class); @@ -106,6 +109,7 @@ public class SchedulerPullRequest { } } } + return ids; } private Set checkOpenPullRequest() { diff --git a/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerReport.java b/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerReport.java deleted file mode 100644 index 1a255d1..0000000 --- a/src/main/java/com/tsc/bitbucketbot/scheduler/SchedulerReport.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.tsc.bitbucketbot.scheduler; - -import com.tsc.bitbucketbot.service.ReportService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -@Service -@Slf4j -@RequiredArgsConstructor -public class SchedulerReport { - - public final ReportService reportService; - -} diff --git a/src/main/java/com/tsc/bitbucketbot/service/PullRequestsService.java b/src/main/java/com/tsc/bitbucketbot/service/PullRequestsService.java index a1e762f..e3adaae 100644 --- a/src/main/java/com/tsc/bitbucketbot/service/PullRequestsService.java +++ b/src/main/java/com/tsc/bitbucketbot/service/PullRequestsService.java @@ -6,6 +6,7 @@ import com.tsc.bitbucketbot.domain.entity.PullRequest; import lombok.NonNull; import org.springframework.data.domain.Page; +import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -36,4 +37,6 @@ public interface PullRequestsService { Page getAll(@NonNull Pagination pagination); + List getAllByAuthor(@NonNull String login, @NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo); + } diff --git a/src/main/java/com/tsc/bitbucketbot/service/ReportService.java b/src/main/java/com/tsc/bitbucketbot/service/ReportService.java index 7e07790..b23b90a 100644 --- a/src/main/java/com/tsc/bitbucketbot/service/ReportService.java +++ b/src/main/java/com/tsc/bitbucketbot/service/ReportService.java @@ -1,4 +1,9 @@ package com.tsc.bitbucketbot.service; +import lombok.NonNull; + public interface ReportService { + + String generateReport(@NonNull String login); + } diff --git a/src/main/java/com/tsc/bitbucketbot/service/impl/PullRequestsServiceImpl.java b/src/main/java/com/tsc/bitbucketbot/service/impl/PullRequestsServiceImpl.java index f802d17..3a30eca 100644 --- a/src/main/java/com/tsc/bitbucketbot/service/impl/PullRequestsServiceImpl.java +++ b/src/main/java/com/tsc/bitbucketbot/service/impl/PullRequestsServiceImpl.java @@ -12,6 +12,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import javax.transaction.Transactional; +import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -72,7 +73,7 @@ public class PullRequestsServiceImpl implements PullRequestsService { @Override public Set getAllId() { - return pullRequestsRepository.getAllIds(); + return pullRequestsRepository.findAllIds(); } @Override @@ -80,4 +81,10 @@ public class PullRequestsServiceImpl implements PullRequestsService { return pullRequestsRepository.findAll(PageRequest.of(pagination.getPage(), pagination.getSize())); } + @Override + public List getAllByAuthor(@NonNull String login, @NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo) { + return pullRequestsRepository.findAllByAuthorAndDateBetween(login, dateFrom, dateTo); + } + + } diff --git a/src/main/java/com/tsc/bitbucketbot/service/impl/ReportServiceImpl.java b/src/main/java/com/tsc/bitbucketbot/service/impl/ReportServiceImpl.java deleted file mode 100644 index f78018e..0000000 --- a/src/main/java/com/tsc/bitbucketbot/service/impl/ReportServiceImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.tsc.bitbucketbot.service.impl; - -import com.tsc.bitbucketbot.service.ReportService; -import org.springframework.stereotype.Service; - -@Service -public class ReportServiceImpl implements ReportService { - -} diff --git a/src/main/java/com/tsc/bitbucketbot/service/impl/ReportServiceSimple.java b/src/main/java/com/tsc/bitbucketbot/service/impl/ReportServiceSimple.java new file mode 100644 index 0000000..8be2ab1 --- /dev/null +++ b/src/main/java/com/tsc/bitbucketbot/service/impl/ReportServiceSimple.java @@ -0,0 +1,66 @@ +package com.tsc.bitbucketbot.service.impl; + +import com.tsc.bitbucketbot.domain.entity.PullRequest; +import com.tsc.bitbucketbot.service.PullRequestsService; +import com.tsc.bitbucketbot.service.ReportService; +import com.tsc.bitbucketbot.utils.Smile; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ReportServiceSimple implements ReportService { + + private final PullRequestsService pullRequestsService; + + @Override + public String generateReport(@NonNull String login) { + final LocalDateTime now = LocalDateTime.now(); + final Map> prByDay = pullRequestsService.getAllByAuthor(login, now.minusDays(7L), now).stream() + .collect(Collectors.groupingBy(pullRequest -> pullRequest.getUpdateDate().toLocalDate())); + return generateMessage(prByDay).orElse("Кажется эту неделю ты не работал"); + } + + private Optional generateMessage(@NonNull Map> prByDay) { + if (!prByDay.isEmpty()) { + final StringBuilder message = new StringBuilder("Твой отчет на эту неделю:").append(Smile.TWO_BR); + for (Map.Entry> entry : prByDay.entrySet()) { + message.append(dayOfWeek(entry.getKey())).append(": "); + for (PullRequest pullRequest : entry.getValue()) { + message.append(" - ").append(pullRequest.getName()).append(Smile.BR) + .append(" --").append(pullRequest.getDescription()); + } + } + } + return Optional.empty(); + } + + private String dayOfWeek(LocalDate date) { + switch (date.getDayOfWeek()) { + case MONDAY: + return "Понедельник"; + case SUNDAY: + return "Воскресенье"; + case TUESDAY: + return "Вторник"; + case SATURDAY: + return "Суббота"; + case THURSDAY: + return "Четверг"; + case WEDNESDAY: + return "Среда"; + case FRIDAY: + return "Пятница"; + } + return ""; + } + +} diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..08103b0 --- /dev/null +++ b/src/main/resources/application-dev.yaml @@ -0,0 +1,29 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5432/bitbucket_bot + username: postgres + driver-class-name: org.postgresql.Driver + password: 121314Ma + liquibase: + change-log: classpath:liquibase/change-log.xml + jpa: + show-sql: false + hibernate: + ddl-auto: none + database-platform: org.hibernate.dialect.PostgreSQLDialect + properties: + hibernate: + jdbc: + lob: + non_contextual_creation: true +bitbucketbot: + init: + start-comment-id: + server-send: + url: http://188.225.35.149:8080/api/send + bitbucket: + token: Nzg5NjUyNDQwMzk2OlA+6naQz02+GxOG0Q9li/jnsn7E + url-pull-request-open: http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN + url-pull-request-close: http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&closedSince=86400 + url-pull-request-comment: http://192.168.236.164:7990/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId} + url-pull-request: http://192.168.236.164:7990/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/overview diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml new file mode 100644 index 0000000..999e5a5 --- /dev/null +++ b/src/main/resources/application-prod.yaml @@ -0,0 +1,27 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5432/bitbucket_bot + username: postgres + driver-class-name: org.postgresql.Driver + password: + liquibase: + change-log: classpath:liquibase/change-log.xml + jpa: + show-sql: false + hibernate: + ddl-auto: none + database-platform: org.hibernate.dialect.PostgreSQLDialect + properties: + hibernate: + jdbc: + lob: + non_contextual_creation: true +bitbucketbot: + server-send: + url: http://188.225.35.149:8080/api/send + bitbucket: + token: Nzg5NjUyNDQwMzk2OlA+6naQz02+GxOG0Q9li/jnsn7E + url-pull-request-open: http://localhost:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN + url-pull-request-close: http://localhost:7990/rest/api/1.0/dashboard/pull-requests?limit=150&closedSince=86400 + url-pull-request-comment: http://localhost:7990/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId} + url-pull-request: http://localhost:7990/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/overview diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index ee2a01d..fa917ab 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,29 +1,2 @@ -spring: - datasource: - url: jdbc:postgresql://localhost:5432/bitbucket_bot - username: postgres - driver-class-name: org.postgresql.Driver - password: - liquibase: - change-log: classpath:liquibase/change-log.xml - jpa: - show-sql: false - hibernate: - ddl-auto: none - database-platform: org.hibernate.dialect.PostgreSQLDialect - properties: - hibernate: - jdbc: - lob: - non_contextual_creation: true -bitbucketbot: - server-send: - url: http://188.225.35.149:8080/api/send - bitbucket: - token: Nzg5NjUyNDQwMzk2OlA+6naQz02+GxOG0Q9li/jnsn7E - url-pull-request-open: http://localhost:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN - url-pull-request-close: http://localhost:7990/rest/api/1.0/dashboard/pull-requests?limit=150&closedSince=86400 - url-pull-request-comment: http://localhost:7990/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId} - url-pull-request: http://localhost:7990/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/overview server: port: 8018 diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 0335154..e106cf3 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -18,7 +18,7 @@ - + \ No newline at end of file