Добавил возможность подписываться на новые репозитории
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Struchkov Mark 2023-01-25 15:07:00 +03:00
parent 91bd1bbc4b
commit f2ab675dd0
Signed by: upagge
GPG Key ID: D3018BE7BA428CA6
30 changed files with 433 additions and 184 deletions

View File

@ -28,4 +28,10 @@ public class AppSetting {
@Column(name = "enable_notify")
private boolean enableNotify;
@Column(name = "project_private_scan")
private boolean projectPrivateScan;
@Column(name = "project_public_scan")
private boolean projectPublicScan;
}

View File

@ -39,4 +39,10 @@ public class Project {
@Column(name = "web_url")
private String webUrl;
@Column(name = "notification")
private boolean notification;
@Column(name = "processing")
private boolean processing;
}

View File

@ -1,5 +1,6 @@
package dev.struchkov.bot.gitlab.context.domain.notify;
package dev.struchkov.bot.gitlab.context.domain.notify.project;
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
import lombok.Builder;
import lombok.Getter;
@ -11,6 +12,7 @@ public final class NewProjectNotify implements Notify {
public static final String TYPE = "NewProjectNotify";
private final Long projectId;
private final String projectName;
private final String projectUrl;
private final String projectDescription;
@ -18,11 +20,13 @@ public final class NewProjectNotify implements Notify {
@Builder
public NewProjectNotify(
Long projectId,
String projectName,
String projectUrl,
String projectDescription,
String authorName
) {
this.projectId = projectId;
this.projectName = projectName;
this.projectUrl = projectUrl;
this.projectDescription = projectDescription;

View File

@ -23,8 +23,14 @@ public interface ProjectRepository {
Page<Project> findAllById(Pageable pagination);
Set<Long> findAllIds();
Set<Long> findAllIdByProcessingEnable();
Optional<String> findProjectNameById(Long projectId);
Set<Long> findAllIds();
void notification(boolean enable, Set<Long> projectIds);
void processing(boolean enable, Set<Long> projectIds);
}

View File

@ -25,4 +25,12 @@ public interface AppSettingService {
void turnOnAllNotify();
void privateProjectScan(boolean enable);
void publicProjectScan(boolean enable);
boolean isPrivateProjectScan();
boolean isPublicProjectScan();
}

View File

@ -25,8 +25,14 @@ public interface ProjectService {
ExistContainer<Project, Long> existsById(Set<Long> projectIds);
Set<Long> getAllIds();
Set<Long> getAllIdByProcessingEnable();
Optional<String> getProjectNameById(Long projectId);
Set<Long> getAllIds();
void notification(boolean enable, Set<Long> projectIds);
void processing(boolean enable, Set<Long> projectIds);
}

View File

@ -25,6 +25,9 @@ public class Icons {
public static final String DISABLE_NOTIFY = "\uD83D\uDD15";
public static final String YES = "";
public static final String NO = "";
public static final String NOTIFY = "\uD83D\uDD14";
public static final String NO_PROCESSING = "\uD83D\uDDD1";
public static final String GOOD = "\uD83D\uDC4D";
private Icons() {
utilityClass();

View File

@ -1,51 +0,0 @@
package dev.struchkov.bot.gitlab.context.utils;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
public enum Smile {
BR("\n"),
TWO_BR("\n\n"),
AUTHOR("\uD83D\uDC68\u200D\uD83D\uDCBB"),
PEN("✏️"),
FUN("\uD83C\uDF89"),
UPDATE("\uD83D\uDD04"),
SUN("\uD83D\uDD06"),
MIG("\uD83D\uDE09"),
BUY("\uD83D\uDC4B"),
FLOWER("\uD83C\uDF40"),
DAY_0("\uD83C\uDF15"),
DAY_1("\uD83C\uDF16"),
DAY_2("\uD83C\uDF17"),
DAY_3("\uD83C\uDF18"),
DAY_4("\uD83C\uDF11"),
DAY_5("\uD83C\uDF1A"),
TASK("\uD83D\uDCBC"),
TOP_ONE("\uD83C\uDF1F\uD83C\uDF1F\uD83C\uDF1F"),
TOP_TWO("\uD83D\uDE0E"),
TOP_THREE("\uD83E\uDD49"),
DANGEROUS("⚠️"),
COMMENT("\uD83D\uDCAC"),
ARROW(""),
SHORT_HR("\n-- -- --\n"),
HR("\n-- -- -- -- --\n"),
HR2("\n-- -- -- -- -- -- -- -- -- --\n"),
FAILURE(""),
SUCCESS(""),
BUILD("♻️"),
SMART("\uD83E\uDDE0"),
SADLY("\uD83D\uDE14"),
TREE("\uD83C\uDF33"),
TOP("\uD83D\uDD1D");
@Getter
private final String value;
@Override
public String toString() {
return value;
}
}

View File

@ -55,6 +55,30 @@ public class AppSettingServiceImpl implements AppSettingService {
log.info("Получение всех уведомлений активировано");
}
@Override
@Transactional
public void privateProjectScan(boolean enable) {
final AppSetting appSetting = getAppSetting();
appSetting.setProjectPrivateScan(enable);
}
@Override
@Transactional
public void publicProjectScan(boolean enable) {
final AppSetting appSetting = getAppSetting();
appSetting.setProjectPublicScan(enable);
}
@Override
public boolean isPrivateProjectScan() {
return getAppSetting().isProjectPrivateScan();
}
@Override
public boolean isPublicProjectScan() {
return getAppSetting().isProjectPublicScan();
}
private AppSetting getAppSetting() {
return appSettingRepository.findById(KEY)
.orElseThrow(NOT_FOUND_SETTINGS);

View File

@ -1,9 +1,8 @@
package dev.struchkov.bot.gitlab.core.service.impl;
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
import dev.struchkov.bot.gitlab.context.domain.notify.NewProjectNotify;
import dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectNotify;
import dev.struchkov.bot.gitlab.context.repository.ProjectRepository;
import dev.struchkov.bot.gitlab.context.service.NotifyService;
import dev.struchkov.bot.gitlab.context.service.PersonService;
@ -31,19 +30,14 @@ public class ProjectServiceImpl implements ProjectService {
private final NotifyService notifyService;
private final PersonService personService;
private final PersonInformation personInformation;
@Override
@Transactional
public Project create(@NonNull Project project) {
final Project newProject = repository.save(project);
final Long gitlabUserId = personInformation.getId();
if (!gitlabUserId.equals(newProject.getCreatorId())) {
final String authorName = personService.getByIdOrThrown(newProject.getCreatorId()).getName();
notifyAboutNewProject(newProject, authorName);
}
return newProject;
}
@ -89,8 +83,8 @@ public class ProjectServiceImpl implements ProjectService {
@Override
@Transactional(readOnly = true)
public Set<Long> getAllIds() {
return repository.findAllIds();
public Set<Long> getAllIdByProcessingEnable() {
return repository.findAllIdByProcessingEnable();
}
@Override
@ -98,9 +92,27 @@ public class ProjectServiceImpl implements ProjectService {
return repository.findProjectNameById(projectId);
}
@Override
public Set<Long> getAllIds() {
return repository.findAllIds();
}
@Override
@Transactional
public void notification(boolean enable, @NonNull Set<Long> projectIds) {
repository.notification(enable, projectIds);
}
@Override
@Transactional
public void processing(boolean enable, @NonNull Set<Long> projectIds) {
repository.processing(enable, projectIds);
}
private void notifyAboutNewProject(Project newProject, String authorName) {
notifyService.send(
NewProjectNotify.builder()
.projectId(newProject.getId())
.projectDescription(newProject.getDescription())
.projectName(newProject.getName())
.projectUrl(newProject.getWebUrl())

View File

@ -107,7 +107,7 @@ public class MergeRequestParser {
public void parsingNewMergeRequest() {
log.debug("Старт обработки новых MR");
final Set<Long> projectIds = projectService.getAllIds();
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
final List<MergeRequestJson> mergeRequestJsons = getMergeRequests(projectIds);

View File

@ -76,7 +76,7 @@ public class PipelineParser {
public void scanNewPipeline() {
log.debug("Старт обработки новых пайплайнов");
final Set<Long> projectIds = projectService.getAllIds();
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
final Map<Long, Long> pipelineProjectMap = getPipelineShortJsons(projectIds).stream()
.collect(Collectors.toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId));

View File

@ -24,6 +24,7 @@ import java.util.stream.Collectors;
import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
import static dev.struchkov.haiti.context.exception.ConvertException.convertException;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
/**
* Парсер проектов.
@ -36,7 +37,7 @@ import static dev.struchkov.haiti.context.exception.ConvertException.convertExce
public class ProjectParser {
public static final String PRIVATE = "&visibility=private";
public static final String OWNER = "&owned=true";
public static final String OWNER = "&visibility=public&owned=true";
private final ProjectService projectService;
private final PersonService personService;
@ -47,18 +48,22 @@ public class ProjectParser {
private final PersonProperty personProperty;
public void parseAllPrivateProject() {
log.debug("Старт обработки приватных проектов");
parseProjects(PRIVATE);
log.debug("Конец обработки приватных проектов");
}
public void parseAllProjectOwner() {
log.debug("Старт обработки публичных проектов, в которых пользователь хозяин");
parseProjects(OWNER);
log.debug("Конец обработки публичных проектов, в которых пользователь хозяин");
}
private void parseProjects(String param) {
int page = 1;
List<ProjectJson> projectJsons = getProjectJsons(page, param);
while (!projectJsons.isEmpty()) {
while (checkNotEmpty(projectJsons)) {
final Set<Long> projectIds = projectJsons.stream()
.map(ProjectJson::getId)
@ -72,7 +77,7 @@ public class ProjectParser {
.map(json -> conversionService.convert(json, Project.class))
.toList();
if (!newProjects.isEmpty()) {
if (checkNotEmpty(newProjects)) {
projectService.createAll(newProjects);
}

View File

@ -47,8 +47,8 @@ public class ProjectRepositoryImpl implements ProjectRepository {
}
@Override
public Set<Long> findAllIds() {
return jpaRepository.findAllIds();
public Set<Long> findAllIdByProcessingEnable() {
return jpaRepository.findAllIdByProcessingEnableTrue();
}
@Override
@ -56,4 +56,19 @@ public class ProjectRepositoryImpl implements ProjectRepository {
return jpaRepository.findProjectNameById(projectId);
}
@Override
public Set<Long> findAllIds() {
return jpaRepository.findAllIds();
}
@Override
public void notification(boolean enable, Set<Long> projectIds) {
jpaRepository.notification(enable, projectIds);
}
@Override
public void processing(boolean enable, Set<Long> projectIds) {
jpaRepository.processing(enable, projectIds);
}
}

View File

@ -2,6 +2,7 @@ package dev.struchkov.bot.gitlab.data.jpa;
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
@ -13,10 +14,21 @@ import java.util.Set;
*/
public interface ProjectJpaRepository extends JpaRepository<Project, Long> {
@Query("SELECT p.id FROM Project p")
Set<Long> findAllIds();
@Query("SELECT p.id FROM Project p WHERE p.processing = true")
Set<Long> findAllIdByProcessingEnableTrue();
@Query("SELECT p.name FROM Project p WHERE p.id = :projectId")
Optional<String> findProjectNameById(@Param("projectId") Long projectId);
@Query("SELECT p.id FROM Project p")
Set<Long> findAllIds();
@Modifying
@Query("UPDATE Project p SET p.notification = :enable WHERE p.id in :projectIds")
void notification(@Param("enable") boolean enable, @Param("projectIds") Set<Long> projectIds);
@Modifying
@Query("UPDATE Project p SET p.processing = :enable WHERE p.id in :projectIds")
void processing(@Param("enable") boolean enable, @Param("projectIds") Set<Long> projectIds);
}

View File

@ -7,6 +7,7 @@ import dev.struchkov.bot.gitlab.context.service.PipelineService;
import dev.struchkov.bot.gitlab.core.service.parser.DiscussionParser;
import dev.struchkov.bot.gitlab.core.service.parser.MergeRequestParser;
import dev.struchkov.bot.gitlab.core.service.parser.PipelineParser;
import dev.struchkov.bot.gitlab.core.service.parser.ProjectParser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
@ -22,18 +23,25 @@ public class SchedulerService {
private final AppSettingService settingService;
private final PipelineParser pipelineParser;
private final MergeRequestParser mergeRequestParser;
private final ProjectParser projectParser;
private final PipelineParser pipelineParser;
private final DiscussionParser discussionParser;
private final PipelineService pipelineService;
private final MergeRequestsService mergeRequestsService;
private final DiscussionService discussionService;
@Scheduled(cron = "0 */1 * * * *")
@Scheduled(cron = "0 */2 * * * *")
public void newMergeRequest() {
log.info("Запуск процесса обновления данных c GitLab");
if (!settingService.isFirstStart()) {
if (settingService.isPrivateProjectScan()) {
projectParser.parseAllPrivateProject();
}
if (settingService.isPublicProjectScan()) {
projectParser.parseAllProjectOwner();
}
mergeRequestParser.parsingOldMergeRequest();
mergeRequestParser.parsingNewMergeRequest();
pipelineParser.scanOldPipeline();

View File

@ -14,6 +14,12 @@
<column name="enable_notify" type="boolean" defaultValue="false">
<constraints nullable="false"/>
</column>
<column name="project_private_scan" type="boolean" defaultValue="false">
<constraints nullable="false"/>
</column>
<column name="project_public_scan" type="boolean" defaultValue="false">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
@ -35,6 +41,12 @@
<column name="web_url" type="varchar(300)">
<constraints nullable="false" unique="true"/>
</column>
<column name="notification" type="boolean">
<constraints nullable="false"/>
</column>
<column name="processing" type="boolean">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>

View File

@ -44,7 +44,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<godfather.telegram.core.version>0.0.48-SNAPSHOT</godfather.telegram.core.version>
<godfather.telegram.core.version>0.0.49-SNAPSHOT</godfather.telegram.core.version>
<jakarta.persistance.version>3.1.0</jakarta.persistance.version>

View File

@ -5,6 +5,7 @@ import dev.struchkov.bot.gitlab.telegram.unit.MenuConfig;
import dev.struchkov.bot.gitlab.telegram.unit.command.AnswerNoteUnit;
import dev.struchkov.bot.gitlab.telegram.unit.command.DeleteMessageUnit;
import dev.struchkov.bot.gitlab.telegram.unit.command.DisableNotifyMrUnit;
import dev.struchkov.bot.gitlab.telegram.unit.command.EnableProjectNotify;
import dev.struchkov.bot.gitlab.telegram.unit.flow.InitSettingFlow;
import dev.struchkov.godfather.main.core.unit.TypeUnit;
import dev.struchkov.godfather.main.domain.content.Mail;
@ -78,9 +79,10 @@ public class TelegramBotConfig {
InitSettingFlow unitConfig,
AnswerNoteUnit commandUnit,
DeleteMessageUnit deleteMessageUnit,
DisableNotifyMrUnit disableNotifyMrUnit
DisableNotifyMrUnit disableNotifyMrUnit,
EnableProjectNotify enableProjectNotify
) {
final List<Object> config = List.of(menuConfig, unitConfig, commandUnit, deleteMessageUnit, disableNotifyMrUnit);
final List<Object> config = List.of(menuConfig, unitConfig, commandUnit, deleteMessageUnit, disableNotifyMrUnit, enableProjectNotify);
return new StorylineMailService(
unitPointerService,

View File

@ -1,7 +1,7 @@
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.Smile;
import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.godfather.main.domain.BoxAnswer;
import org.springframework.stereotype.Component;
@ -14,7 +14,7 @@ public class NewCommentNotifyGenerator implements NotifyBoxAnswerGenerator<NewCo
@Override
public BoxAnswer generate(NewCommentNotify notify) {
final StringBuilder builder = new StringBuilder(Smile.COMMENT.getValue()).append(" [New answer in discussion](").append(notify.getUrl()).append(")");
final StringBuilder builder = new StringBuilder(Icons.COMMENT).append(" [New answer in discussion](").append(notify.getUrl()).append(")");
if (checkNotNull(notify.getDiscussionMessage())) {
builder.append("\n-- -- discussion first message -- --\n")

View File

@ -45,7 +45,7 @@ public class NewMrForAssigneeNotifyGenerator implements NotifyBoxAnswerGenerator
}
builder
.append(Icons.TREE).append(": ").append(notify.getSourceBranch()).append(Icons.ARROW).append(notify.getTargetBranch()).append("\n")
.append(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch())).append(Icons.ARROW).append(escapeMarkdown(notify.getTargetBranch())).append("\n")
.append(Icons.AUTHOR).append(": ").append(notify.getAuthor()).append("\n");
final List<String> reviewers = notify.getReviewers();

View File

@ -44,7 +44,7 @@ public class NewMrForReviewNotifyGenerator implements NotifyBoxAnswerGenerator<N
}
builder
.append(Icons.TREE).append(": ").append(notify.getSourceBranch()).append(Icons.ARROW).append(notify.getTargetBranch()).append("\n")
.append(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch())).append(Icons.ARROW).append(escapeMarkdown(notify.getTargetBranch())).append("\n")
.append(Icons.AUTHOR).append(": ").append(notify.getAuthor()).append("\n");
if (checkNotNull(notify.getAssignee())) {

View File

@ -1,15 +1,21 @@
package dev.struchkov.bot.gitlab.telegram.service.notify;
import dev.struchkov.bot.gitlab.context.domain.notify.NewProjectNotify;
import dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectNotify;
import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.bot.gitlab.telegram.utils.Const;
import dev.struchkov.godfather.main.domain.BoxAnswer;
import dev.struchkov.haiti.utils.Strings;
import org.springframework.stereotype.Component;
import java.util.Optional;
import static dev.struchkov.bot.gitlab.context.utils.Icons.link;
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.main.domain.keyboard.simple.SimpleKeyBoardLine.simpleLine;
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.Strings.escapeMarkdown;
@Component
public class NewProjectNotifyGenerator implements NotifyBoxAnswerGenerator<NewProjectNotify> {
@ -17,24 +23,34 @@ public class NewProjectNotifyGenerator implements NotifyBoxAnswerGenerator<NewPr
@Override
public BoxAnswer generate(NewProjectNotify notify) {
final Optional<String> optDescription = Optional.ofNullable(notify.getProjectDescription())
.filter(Strings.EMPTY::equals)
.map(Strings::escapeMarkdown);
final StringBuilder builder = new StringBuilder(Icons.FUN).append("*New project*")
final StringBuilder builder = new StringBuilder(Icons.FUN).append("* New project*")
.append(Icons.HR)
.append(link(notify.getProjectName(), notify.getProjectUrl()))
.append(escapeMarkdown(notify.getProjectName()))
.append(Icons.HR);
if (optDescription.isPresent() || !Strings.EMPTY.equals(optDescription.get())) {
if (optDescription.isPresent()) {
final String description = optDescription.get();
builder.append(description)
builder.append(escapeMarkdown(description))
.append(Icons.HR);
}
builder.append(Icons.AUTHOR).append(": ").append(notify.getAuthorName());
builder.append(Icons.AUTHOR).append(": ").append(escapeMarkdown(notify.getAuthorName()));
final String notifyMessage = builder.toString();
return boxAnswer(notifyMessage);
return boxAnswer(
notifyMessage,
inlineKeyBoard(
simpleLine(urlButton(Icons.LINK, notify.getProjectUrl())),
simpleLine(
simpleButton(Icons.NOTIFY, "[" + Const.BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID + ":" + notify.getProjectId() + "]"),
simpleButton(Icons.DISABLE_NOTIFY, DELETE_MESSAGE)
)
)
);
}
@Override

View File

@ -2,7 +2,6 @@ package dev.struchkov.bot.gitlab.telegram.service.notify;
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.UpdateMrNotify;
import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.bot.gitlab.context.utils.Smile;
import dev.struchkov.godfather.main.domain.BoxAnswer;
import org.springframework.stereotype.Component;
@ -25,11 +24,11 @@ public class UpdatePrNotifyGenerator implements NotifyBoxAnswerGenerator<UpdateM
public BoxAnswer generate(UpdateMrNotify notify) {
final StringBuilder builder = new StringBuilder(Icons.UPDATE).append(" *MergeRequest update*")
.append(Smile.HR.getValue())
.append(Icons.HR)
.append(notify.getTitle());
if (notify.getAllTasks() > 0) {
builder.append(Smile.HR.getValue())
builder.append(Icons.HR)
.append("All tasks: ").append(notify.getAllResolvedTasks()).append("/").append(notify.getAllTasks());
if (notify.getPersonTasks() > 0) {

View File

@ -5,10 +5,9 @@ import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
import dev.struchkov.bot.gitlab.context.service.NoteService;
import dev.struchkov.bot.gitlab.context.utils.Smile;
import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
import dev.struchkov.bot.gitlab.core.service.parser.ProjectParser;
import dev.struchkov.bot.gitlab.telegram.utils.Keys;
import dev.struchkov.bot.gitlab.telegram.utils.UnitName;
import dev.struchkov.godfather.main.domain.BoxAnswer;
import dev.struchkov.godfather.main.domain.annotation.Unit;
@ -34,7 +33,6 @@ import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.GET_TASKS;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.SETTINGS;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.TEXT_ADD_NEW_PROJECT;
import static dev.struchkov.godfather.main.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.main.domain.BoxAnswer.replaceBoxAnswer;
import static dev.struchkov.godfather.main.domain.keyboard.button.SimpleButton.simpleButton;
import static dev.struchkov.godfather.main.domain.keyboard.simple.SimpleKeyBoardLine.simpleLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
@ -65,7 +63,7 @@ public class MenuConfig {
.triggerCheck(mail -> !personInformation.getTelegramId().equals(mail.getPersonId()))
.answer(message -> {
final String messageText = new StringBuilder("\uD83D\uDEA8 *Попытка несанкционированного доступа к боту*")
.append(Smile.HR.getValue())
.append(Icons.HR)
.append("\uD83E\uDDB9\u200D♂: ").append(message.getPersonId()).append("\n")
.append("\uD83D\uDCAC: ").append(message.getText())
.toString();
@ -101,13 +99,6 @@ public class MenuConfig {
),
simpleLine(simpleButton("Settings", SETTINGS))
);
final String personId = mail.getPersonId();
final var initSettingFinish = context.removeKey(personId, Keys.INIT_SETTING_FINISH);
if (initSettingFinish.isPresent()) {
context.removeKey(personId, Keys.INIT_SETTING_PRIVATE_PROJECT_MESSAGE_ID).ifPresent(messageId -> sending.deleteMessage(personId, messageId));
context.removeKey(personId, Keys.INIT_SETTING_PUBLIC_PROJECT_MESSAGE_ID).ifPresent(messageId -> sending.deleteMessage(personId, messageId));
return replaceBoxAnswer(messageText, generalMenuKeyBoard);
}
return boxAnswer(messageText, generalMenuKeyBoard);
}
)

View File

@ -0,0 +1,71 @@
package dev.struchkov.bot.gitlab.telegram.unit.command;
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
import dev.struchkov.bot.gitlab.context.service.ProjectService;
import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.bot.gitlab.telegram.utils.UnitName;
import dev.struchkov.godfather.main.domain.annotation.Unit;
import dev.struchkov.godfather.main.domain.content.Mail;
import dev.struchkov.godfather.simple.core.unit.AnswerText;
import dev.struchkov.godfather.telegram.domain.attachment.ButtonClickAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.ButtonClickAttachment.Arg;
import dev.struchkov.godfather.telegram.main.core.util.Attachments;
import dev.struchkov.godfather.telegram.simple.context.service.TelegramSending;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID;
import static dev.struchkov.godfather.main.domain.BoxAnswer.replaceBoxAnswer;
@Component
@RequiredArgsConstructor
public class EnableProjectNotify {
private final ProjectService projectService;
private final AppSettingService settingService;
private final PersonInformation personInformation;
private final TelegramSending sending;
private final ScheduledExecutorService scheduledExecutorService;
@Unit(value = UnitName.ENABLE_NOTIFY_PROJECT, global = true)
public AnswerText<Mail> enableNotifyProject() {
return AnswerText.<Mail>builder()
.triggerCheck(mail -> {
final boolean isAccess = personInformation.getTelegramId().equals(mail.getPersonId());
if (isAccess) {
final boolean isFirstStart = settingService.isFirstStart();
if (!isFirstStart) {
final Optional<ButtonClickAttachment> optButtonClick = Attachments.findFirstButtonClick(mail.getAttachments());
if (optButtonClick.isPresent()) {
final ButtonClickAttachment buttonClick = optButtonClick.get();
return buttonClick.getArgByType(BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID).isPresent();
}
}
}
return false;
}).answer(
mail -> {
final ButtonClickAttachment buttonClick = Attachments.findFirstButtonClick(mail.getAttachments()).orElseThrow();
final Arg arg = buttonClick.getArgByType(BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID).orElseThrow();
final long projectId = Long.parseLong(arg.getValue());
final Set<Long> setProjectId = Set.of(projectId);
projectService.processing(true, setProjectId);
projectService.notification(true, setProjectId);
return replaceBoxAnswer(mail.getId(), Icons.GOOD + " you will now receive notifications!");
}
)
.<Integer>callBack(
sentBox -> scheduledExecutorService.schedule(() -> sending.deleteMessage(sentBox.getPersonId(), sentBox.getMessageId()), 5, TimeUnit.SECONDS)
)
.build();
}
}

View File

@ -10,7 +10,6 @@ import dev.struchkov.bot.gitlab.core.service.parser.DiscussionParser;
import dev.struchkov.bot.gitlab.core.service.parser.MergeRequestParser;
import dev.struchkov.bot.gitlab.core.service.parser.PipelineParser;
import dev.struchkov.bot.gitlab.core.service.parser.ProjectParser;
import dev.struchkov.bot.gitlab.telegram.utils.Keys;
import dev.struchkov.godfather.main.domain.annotation.Unit;
import dev.struchkov.godfather.main.domain.content.Mail;
import dev.struchkov.godfather.simple.core.unit.AnswerText;
@ -22,12 +21,20 @@ import dev.struchkov.godfather.telegram.simple.context.service.TelegramSending;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.AUTO_PARSE_PRIVATE_PROJECT;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.AUTO_PARSE_PUBLIC_PROJECT;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.CHECK_PARSER_PRIVATE_PROJECT_NO;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.CHECK_PARSER_PRIVATE_PROJECT_YES;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.CHECK_PARSE_OWNER_PROJECT_NO;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.CHECK_PARSE_OWNER_PROJECT_YES;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.END_SETTING;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.FIRST_START;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.TEXT_AUTO_PARSE_PRIVATE_PROJECT;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.TEXT_AUTO_PARSE_PUBLIC_PROJECT;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.TEXT_PARSER_PRIVATE_PROJECT;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.TEXT_PARSE_OWNER_PROJECT;
import static dev.struchkov.godfather.main.core.unit.UnitActiveType.AFTER;
@ -37,6 +44,7 @@ import static dev.struchkov.godfather.main.domain.keyboard.button.SimpleButton.s
import static dev.struchkov.godfather.main.domain.keyboard.simple.SimpleKeyBoardLine.simpleLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
import static dev.struchkov.godfather.telegram.simple.core.util.TriggerChecks.clickButtonRaw;
import static dev.struchkov.godfather.telegram.simple.core.util.TriggerChecks.isClickButton;
import static java.text.MessageFormat.format;
/**
@ -65,6 +73,8 @@ public class InitSettingFlow {
private final PipelineService pipelineService;
private final DiscussionService discussionService;
private final ScheduledExecutorService scheduledExecutorService;
@Unit(value = FIRST_START, main = true)
public AnswerText<Mail> firstStart(
@Unit(value = TEXT_PARSER_PRIVATE_PROJECT) MainUnit<Mail> textParserPrivateProject
@ -82,6 +92,7 @@ public class InitSettingFlow {
"""
Hello!
This bot will help you keep your finger on the pulse of all your GitLab projects.
Press start to start initial setup 👇
""",
inlineKeyBoard(simpleButton("start", TEXT_PARSER_PRIVATE_PROJECT))
@ -93,11 +104,16 @@ public class InitSettingFlow {
@Unit(value = TEXT_PARSER_PRIVATE_PROJECT)
public AnswerText<Mail> textParserPrivateProject(
@Unit(CHECK_PARSER_PRIVATE_PROJECT_YES) MainUnit<Mail> checkParserPrivateProject
@Unit(CHECK_PARSER_PRIVATE_PROJECT_YES) MainUnit<Mail> checkParserPrivateProjectYes,
@Unit(CHECK_PARSER_PRIVATE_PROJECT_NO) MainUnit<Mail> checkParserPrivateProjectNo
) {
return AnswerText.<Mail>builder()
.answer(() -> replaceBoxAnswer(
"Start tracking private projects?",
"""
I can scan all your private projects and put them on tracking. This will notify you of new merge requests and other events. Or you can add only the projects you want later manually one by one.
Add all available private projects?
""",
inlineKeyBoard(
simpleLine(
simpleButton("Yes", "YES"),
@ -106,67 +122,63 @@ public class InitSettingFlow {
)
)
)
.next(checkParserPrivateProject)
.next(checkParserPrivateProjectYes)
.next(checkParserPrivateProjectNo)
.build();
}
@Unit(CHECK_PARSER_PRIVATE_PROJECT_YES)
public AnswerText<Mail> checkParserPrivateProjectYes(
@Unit(TEXT_PARSE_OWNER_PROJECT) MainUnit<Mail> textParseOwnerProject
@Unit(TEXT_AUTO_PARSE_PRIVATE_PROJECT) MainUnit<Mail> textAutoParsePrivateProject
) {
final String step1 = """
-- -- -- -- --
🔘 Scanning of private projects has begun.
Wait...
-- -- -- -- --
""";
final String step2 = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 {0} private projects found.
🔘 Scanning merge requests in found projects.
Wait...
-- -- -- -- --
""";
final String step3 = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 Merge requests have been successfully added. Found: {1}
🟢 {0} private projects found.
🟢 {1} merge requests found.
🔘 Scanning pipelines in found merge requests.
Wait...
-- -- -- -- --
""";
final String step4 = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 Merge requests have been successfully added. Found: {1}
🟢 Pipelines have been successfully added. Found: {2}
🟢 {0} private projects found.
🟢 {1} merge requests found.
🟢 {2} pipelines found.
🔘 Scanning threads in merge requests.
Wait...
-- -- -- -- --
""";
final String finalAnswer = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 Merge requests have been successfully added. Found: {1}
🟢 Pipelines have been successfully added. Found: {2}
🟢 Threads have been successfully added. Found: {3}
-- -- -- -- --
🟢 {0} private projects found.
🟢 {1} merge requests found.
🟢 {2} pipelines found.
🟢 {3} threads found.
""";
return AnswerText.<Mail>builder()
.triggerCheck(clickButtonRaw("YES"))
.answer(mail -> {
final String personId = mail.getPersonId();
final Integer messageId = Attachments.findFirstButtonClick(mail.getAttachments())
final String messageId = Attachments.findFirstButtonClick(mail.getAttachments())
.map(ButtonClickAttachment::getMessageId)
.orElseThrow();
sending.replaceMessage(personId, messageId, boxAnswer(step1));
projectParser.parseAllPrivateProject();
final int projectCount = projectService.getAllIds().size();
final Set<Long> projectIds = projectService.getAllIds();
projectService.notification(true, projectIds);
projectService.processing(true, projectIds);
final int projectCount = projectIds.size();
sending.replaceMessage(personId, messageId, boxAnswer(format(step2, projectCount)));
mergeRequestParser.parsingNewMergeRequest();
@ -180,26 +192,63 @@ public class InitSettingFlow {
discussionParser.scanNewDiscussion();
final int discussionCount = discussionService.getAllIds().size();
context.save(mail.getPersonId(), Keys.INIT_SETTING_PRIVATE_PROJECT_MESSAGE_ID, messageId);
return replaceBoxAnswer(format(finalAnswer, pipelineCount, mrCount, pipelineCount, discussionCount));
})
.next(textParseOwnerProject)
.<Integer>callBack(
sentBox -> scheduledExecutorService.schedule(() -> sending.deleteMessage(sentBox.getPersonId(), sentBox.getMessageId()), 10, TimeUnit.SECONDS)
)
.next(textAutoParsePrivateProject)
.build();
}
@Unit(CHECK_PARSER_PRIVATE_PROJECT_NO)
public AnswerText<Mail> checkParserPrivateProjectNo(
@Unit(TEXT_PARSE_OWNER_PROJECT) MainUnit<Mail> textParseOwnerProject
@Unit(TEXT_AUTO_PARSE_PRIVATE_PROJECT) MainUnit<Mail> textAutoParsePrivateProject
) {
return AnswerText.<Mail>builder()
.triggerPhrase("NO")
.answer(mail -> {
final Integer messageId = Attachments.findFirstButtonClick(mail.getAttachments())
.map(ButtonClickAttachment::getMessageId)
.orElseThrow();
.answer(replaceBoxAnswer("Okay, I won't scan private projects."))
.<Integer>callBack(
sentBox -> scheduledExecutorService.schedule(() -> sending.deleteMessage(sentBox.getPersonId(), sentBox.getMessageId()), 10, TimeUnit.SECONDS)
)
.next(textAutoParsePrivateProject)
.build();
}
context.save(mail.getPersonId(), Keys.INIT_SETTING_PRIVATE_PROJECT_MESSAGE_ID, messageId);
replaceBoxAnswer("Okay, I won't scan private projects.");
@Unit(TEXT_AUTO_PARSE_PRIVATE_PROJECT)
public AnswerText<Mail> textAutoParsePrivateProject(
@Unit(AUTO_PARSE_PRIVATE_PROJECT) MainUnit<Mail> autoParsePrivateProject
) {
return AnswerText.<Mail>builder()
.activeType(AFTER)
.answer(
boxAnswer(
"Do you want to enable automatic notification of new private projects available to you?",
inlineKeyBoard(
simpleLine(
simpleButton("Yes", "YES"),
simpleButton("No", "NO")
)
)
)
)
.next(autoParsePrivateProject)
.build();
}
@Unit(AUTO_PARSE_PRIVATE_PROJECT)
public AnswerText<Mail> autoParsePrivateProject(
@Unit(TEXT_PARSE_OWNER_PROJECT) MainUnit<Mail> textParseOwnerProject
) {
return AnswerText.<Mail>builder()
.triggerCheck(isClickButton())
.answer(mail -> {
final ButtonClickAttachment buttonClick = Attachments.findFirstButtonClick(mail.getAttachments()).orElseThrow();
if ("YES".equals(buttonClick.getRawCallBackData())) {
settingService.privateProjectScan(true);
} else {
settingService.privateProjectScan(false);
}
})
.next(textParseOwnerProject)
.build();
@ -211,9 +260,14 @@ public class InitSettingFlow {
@Unit(CHECK_PARSE_OWNER_PROJECT_NO) MainUnit<Mail> checkParseOwnerProjectNo
) {
return AnswerText.<Mail>builder()
.activeType(AFTER)
.answer(
boxAnswer(
"Start tracking public projects that you own?",
replaceBoxAnswer(
"""
Now do you want to track all available public projects *where you are the creator*?
(The process is similar to private projects)
""",
inlineKeyBoard(
simpleLine(
simpleButton("Yes", "YES"),
@ -222,7 +276,6 @@ public class InitSettingFlow {
)
)
)
.activeType(AFTER)
.next(checkParseOwnerProjectYes)
.next(checkParseOwnerProjectNo)
.build();
@ -230,93 +283,132 @@ public class InitSettingFlow {
@Unit(CHECK_PARSE_OWNER_PROJECT_YES)
public AnswerText<Mail> checkParseOwnerProjectYes(
@Unit(END_SETTING) MainUnit<Mail> endSetting
@Unit(TEXT_AUTO_PARSE_PUBLIC_PROJECT) MainUnit<Mail> textAutoParsePublicProject
) {
final String step1 = """
-- -- -- -- --
🔘 Scanning of public projects has begun.
Wait...
-- -- -- -- --
""";
final String step2 = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 {0} public projects found.
🔘 Scanning merge requests in found projects.
Wait...
-- -- -- -- --
""";
final String step3 = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 Merge requests have been successfully added. Found: {1}
🟢 {0} public projects found.
🟢 {1} merge requests found.
🔘 Scanning pipelines in found merge requests.
Wait...
-- -- -- -- --
""";
final String step4 = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 Merge requests have been successfully added. Found: {1}
🟢 Pipelines have been successfully added. Found: {2}
🟢 {0} public projects found.
🟢 {1} merge requests found.
🟢 {2} pipelines found.
🔘 Scanning threads in merge requests.
Wait...
-- -- -- -- --
""";
final String finalAnswer = """
-- -- -- -- --
🟢 Projects have been successfully added to tracking. Found: {0}
🟢 Merge requests have been successfully added. Found: {1}
🟢 Pipelines have been successfully added. Found: {2}
🟢 Threads have been successfully added. Found: {3}
-- -- -- -- --
🟢 {0} public projects found.
🟢 {1} merge requests found.
🟢 {2} pipelines found.
🟢 {3} threads found.
""";
return AnswerText.<Mail>builder()
.triggerCheck(clickButtonRaw("YES"))
.answer(mail -> {
final String personId = mail.getPersonId();
final Integer messageId = Attachments.findFirstButtonClick(mail.getAttachments())
final String messageId = Attachments.findFirstButtonClick(mail.getAttachments())
.map(ButtonClickAttachment::getMessageId)
.orElseThrow();
sending.replaceMessage(personId, messageId, boxAnswer(step1));
final int oldCountProjects = projectService.getAllIds().size();
projectParser.parseAllProjectOwner();
final int projectCount = projectService.getAllIds().size();
final Set<Long> projectIds = projectService.getAllIds();
projectService.notification(true, projectIds);
projectService.processing(true, projectIds);
final int projectCount = projectIds.size() - oldCountProjects;
sending.replaceMessage(personId, messageId, boxAnswer(format(step2, projectCount)));
final int oldCountMr = mergeRequestsService.getAllIds().size();
mergeRequestParser.parsingNewMergeRequest();
final int mrCount = mergeRequestsService.getAllIds().size();
final int mrCount = mergeRequestsService.getAllIds().size() - oldCountMr;
sending.replaceMessage(personId, messageId, boxAnswer(format(step3, projectCount, mrCount)));
final int oldCountPipelines = pipelineService.getAllIds().size();
pipelineParser.scanNewPipeline();
final int pipelineCount = pipelineService.getAllIds().size();
final int pipelineCount = pipelineService.getAllIds().size() - oldCountPipelines;
sending.replaceMessage(personId, messageId, boxAnswer(format(step4, projectCount, mrCount, pipelineCount)));
final int oldCountThreads = discussionService.getAllIds().size();
discussionParser.scanNewDiscussion();
final int discussionCount = discussionService.getAllIds().size();
final int discussionCount = discussionService.getAllIds().size() - oldCountThreads;
context.save(mail.getPersonId(), Keys.INIT_SETTING_PUBLIC_PROJECT_MESSAGE_ID, messageId);
return replaceBoxAnswer(format(finalAnswer, pipelineCount, mrCount, pipelineCount, discussionCount));
})
.next(endSetting)
.<Integer>callBack(
sentBox -> scheduledExecutorService.schedule(() -> sending.deleteMessage(sentBox.getPersonId(), sentBox.getMessageId()), 10, TimeUnit.SECONDS)
)
.next(textAutoParsePublicProject)
.build();
}
@Unit(CHECK_PARSE_OWNER_PROJECT_NO)
public AnswerText<Mail> checkParseOwnerProjectNo(
@Unit(END_SETTING) MainUnit<Mail> endSetting
@Unit(TEXT_AUTO_PARSE_PUBLIC_PROJECT) MainUnit<Mail> textAutoParsePublicProject
) {
return AnswerText.<Mail>builder()
.triggerCheck(clickButtonRaw("NO"))
.answer(replaceBoxAnswer("Okay, I won't scan public projects."))
.<Integer>callBack(
sentBox -> scheduledExecutorService.schedule(() -> sending.deleteMessage(sentBox.getPersonId(), sentBox.getMessageId()), 10, TimeUnit.SECONDS)
)
.next(textAutoParsePublicProject)
.build();
}
@Unit(TEXT_AUTO_PARSE_PUBLIC_PROJECT)
public AnswerText<Mail> textAutoParsePublicProject(
@Unit(AUTO_PARSE_PUBLIC_PROJECT) MainUnit<Mail> autoParsePublicProject
) {
return AnswerText.<Mail>builder()
.activeType(AFTER)
.answer(
boxAnswer(
"Do you want to enable automatic notification of new public projects available to you?",
inlineKeyBoard(
simpleLine(
simpleButton("Yes", "YES"),
simpleButton("No", "NO")
)
)
)
)
.next(autoParsePublicProject)
.build();
}
@Unit(AUTO_PARSE_PUBLIC_PROJECT)
public AnswerText<Mail> autoParsePublicProject(
@Unit(END_SETTING) MainUnit<Mail> endSetting
) {
return AnswerText.<Mail>builder()
.triggerCheck(isClickButton())
.answer(mail -> {
final Integer messageId = Attachments.findFirstButtonClick(mail.getAttachments())
.map(ButtonClickAttachment::getMessageId)
.orElseThrow();
context.save(mail.getPersonId(), Keys.INIT_SETTING_PUBLIC_PROJECT_MESSAGE_ID, messageId);
return replaceBoxAnswer("Okay, I won't scan public projects.");
final ButtonClickAttachment buttonClick = Attachments.findFirstButtonClick(mail.getAttachments()).orElseThrow();
if ("YES".equals(buttonClick.getRawCallBackData())) {
settingService.publicProjectScan(true);
} else {
settingService.publicProjectScan(false);
}
})
.next(endSetting)
.build();
@ -328,10 +420,9 @@ public class InitSettingFlow {
.activeType(AFTER)
.answer(
mail -> {
context.save(mail.getPersonId(), Keys.INIT_SETTING_FINISH, Boolean.TRUE);
settingService.turnOnAllNotify();
settingService.disableFirstStart();
return boxAnswer("""
return replaceBoxAnswer("""
Configuration completed successfully
Developer: [uPagge](https://mark.struchkov.dev)
""",

View File

@ -9,6 +9,8 @@ public class Const {
public static final String BUTTON_VALUE_TRUE = "t";
public static final String BUTTON_ARG_DISABLE_NOTIFY_MR_ID = "dis_mr_id";
public static final String BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID = "ena_p_id";
public static final String BUTTON_ARG_CONFIRMATION = "conf";

View File

@ -1,13 +1,9 @@
package dev.struchkov.bot.gitlab.telegram.utils;
import dev.struchkov.godfather.main.domain.ContextKey;
import lombok.experimental.UtilityClass;
@UtilityClass
public class Keys {
public static final ContextKey<Boolean> INIT_SETTING_FINISH = ContextKey.of("INIT_SETTING_FINISH", Boolean.class);
public static final ContextKey<Integer> INIT_SETTING_PRIVATE_PROJECT_MESSAGE_ID = ContextKey.of("INIT_SETTING_PRIVATE_PROJECT_MESSAGE_ID", Integer.class);
public static final ContextKey<Integer> INIT_SETTING_PUBLIC_PROJECT_MESSAGE_ID = ContextKey.of("INIT_SETTING_PUBLIC_PROJECT_MESSAGE_ID", Integer.class);
}

View File

@ -20,10 +20,15 @@ public final class UnitName {
public static final String ACCESS_ERROR = "ACCESS_ERROR";
public static final String CHECK_PARSER_PRIVATE_PROJECT_NO = "CHECK_PARSER_PRIVATE_PROJECT_NO";
public static final String CHECK_PARSE_OWNER_PROJECT_NO = "CHECK_PARSE_OWNER_PROJECT_NO";
public static final String TEXT_AUTO_PARSE_PRIVATE_PROJECT = "TEXT_AUTO_PARSE_PRIVATE_PROJECT";
public static final String AUTO_PARSE_PRIVATE_PROJECT = "AUTO_PARSE_PRIVATE_PROJECT";
public static final String AUTO_PARSE_PUBLIC_PROJECT = "AUTO_PARSE_PUBLIC_PROJECT";
public static final String TEXT_AUTO_PARSE_PUBLIC_PROJECT = "TEXT_AUTO_PARSE_PUBLIC_PROJECT";
// команды
public static final String DELETE_MESSAGE = "DELETE_MESSAGE";
public static final String DISABLE_NOTIFY_MR = "DISABLE_NOTIFY_MR";
public static final String ENABLE_NOTIFY_PROJECT = "ENABLE_NOTIFY_PROJECT";
private UnitName() {
utilityClass();